package service

import (
	"context"
	"strings"
	"time"

	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/common"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/log"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/model"
	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/prometheus"

	"go.uber.org/zap"
)

type SlowQueryService struct {
	commonDAO common.CommonDAO
}

func NewSlowQueryService() *SlowQueryService {
	return &SlowQueryService{
		commonDAO: common.NewCommonDAO(),
	}
}

// processDateRange handles the logic of iterating through a date range.
func (s *SlowQueryService) processDateRange(ctx context.Context, clusterId, startDay, endDay string, dailyProcessor func(context.Context, string, string)) {
	layout := "20060102"
	startDate, err := time.Parse(layout, startDay)
	if err != nil {
		log.PlainError("parse startDay failed", zap.String("startDay", startDay), zap.Error(err))
		return
	}
	endDate, err := time.Parse(layout, endDay)
	if err != nil {
		log.PlainError("parse endDay failed", zap.String("endDay", endDay), zap.Error(err))
		return
	}

	if startDate.After(endDate) {
		log.PlainError("startDay cannot be after endDay", zap.String("startDay", startDay), zap.String("endDay", endDay))
		return
	}

	for d := startDate; !d.After(endDate); d = d.AddDate(0, 0, 1) {
		dayStr := d.Format(layout)
		log.PlainInfo("start to process for day", zap.String("day", dayStr))
		dailyProcessor(ctx, clusterId, dayStr)
	}
}

func (s *SlowQueryService) SaveCpuPercent(ctx context.Context, clusterId string, startDay string, endDay string) {
	//  s.processDateRange(ctx, clusterId, startDay, endDay, s.UpdateSlowQuery)
	log.PlainInfo("SaveCpuPercent done")
}

func (s *SlowQueryService) UpdateSlowQuery(ctx context.Context) error {
	// startDay:="2025-08-11"
	// endDay:="2025-09-01"
	var dailyStatArr []model.DailyStat
	params := common.ListParams{
		AdvancedFilters: map[string]interface{}{
			// "report_date >= ?":        startDay,
			// "report_date <= ?":        endDay,
			"report_date in (?)": []string{"2025-08-11", "2025-08-12", "2025-08-13"},
			"org_id = ?":         "1372813089209061633",
			// "id > ?":                  4530003,
		},
		Orders: []string{"id asc"},
	}
	errs := s.commonDAO.ListEntities(ctx, params, &dailyStatArr)
	if errs != nil {
		log.PlainError("ListEntities failed", zap.Error(errs))
		return errs
	}

	for _, d := range dailyStatArr {
		clusterIds := strings.Split(d.ClusterID, ",")
		// ReportDate:="2025-08-01" -> 20250801
		t, err := time.Parse(time.RFC3339, d.ReportDate)
		if err != nil {
			log.PlainError("parse report date failed", zap.Error(err))
			return err
		}
		day := t.Format("20060102")
		resp, err := prometheus.CheckCPU(clusterIds, day, d.Digest)
		if err != nil {
			log.PlainError("CheckCPU failed ", zap.Any("DailyStat", d))
			log.PlainError("CheckCPU failed", zap.Any("id", d.ID), zap.Error(err))
			// return err
		}

		updateColumn := model.DailyStat{
			TotalCpuTime:        resp.MaxTotalCpuTime,
			TotalCpuTimePer:     resp.MaxTotalCpuTimePer,
			MaxCpuTimeIn5Min:    resp.MaxCpuTimeIn5MinOfDay,
			MaxCpuTimeIn5MinPer: resp.CpuTimeIn5MinOfDayPer,
		}
		u := &model.DailyStat{}
		s.commonDAO.UpdateEntityById(ctx, d.ID, updateColumn, u)
	}

	return nil

}
