package collector

import (
	"context"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/tidbcloud/dataflow-service/app/container"
	"github.com/tidbcloud/dataflow-service/app/metrics/base"
	crrf_metric "github.com/tidbcloud/dataflow-service/app/metrics/crrf/metric"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"gorm.io/gorm"
)

func NewMetricsCollector() prometheus.Collector {
	app := container.Global()
	unfinishedStatus := []entity.CRRFSettingStatus{entity.CRRFSettingStatusEnabling, entity.CRRFSettingStatusDisabling}
	latestUpdatedRange := time.Hour * 24 * 7

	return base.NewMetricsCollector(&base.Target[*entity.CRRFSetting]{
		Name:            "crrf",
		StatusCollector: crrf_metric.StatusDesc,
		// collect unfinished and updated within 7 days CRRF settings
		ListUnfinished: func(ctx context.Context) ([]*entity.CRRFSetting, error) {
			return app.CRRFSettingRepo.ListByFilter(ctx, func(rdb *gorm.DB) *gorm.DB {
				return rdb.Where("updated_at > ? AND status IN ?", time.Now().Add(-latestUpdatedRange), unfinishedStatus)
			})
		},
		ListByIDs: func(ctx context.Context, ids []entity.ID) ([]*entity.CRRFSetting, error) {
			if len(ids) == 0 {
				return nil, nil
			}

			crrfs, err := app.CRRFSettingRepo.ListByFilter(ctx, func(rdb *gorm.DB) *gorm.DB {
				// collect deleted CRRF settings to delete the metrics of them
				return rdb.Unscoped().Where("id IN ?", ids)
			})
			return crrfs, err
		},
		UpdateStatusMetrics: func(collector *prometheus.Desc, obj *entity.CRRFSetting) {
			crrf_metric.UpdateStatusMetric(obj)
		},
		DeleteStatusMetrics: crrf_metric.DeleteStatusMetric,
	})
}
