package oldreport

import (
	"github.com/pingcap/errors"

	"github.com/pingcap-inc/clinic/pkg/compute_engine"
	"github.com/pingcap-inc/clinic/pkg/db"
)

type ReportResp struct {
	TaskID string
}

type RealtimeReportAdvice struct {
	ID        int      `json:"id"`
	Name      string   `json:"name"`
	Category  []string `json:"category"`
	Component string   `json:"component"`
	Qualified bool     `json:"qualified"`
	Level     string   `json:"level"`
	Type      string   `json:"type"`
	Content   struct {
		Key       string         `json:"key"`
		Variables map[string]any `json:"variables"`
	} `json:"content"`
}

type RealtimeReportContent struct {
	Type      string                 `json:"type"`
	Tiemstamp int                    `json:"timestamp"`
	Advice    []RealtimeReportAdvice `json:"advice"`
}

type RealtimeReportData struct {
	Content []RealtimeReportContent `json:"content"`
}

type FeedbackContent struct {
	Args FeedbackArgs `json:"args"`
}

type FeedbackArgs struct {
	User  string `json:"user"`
	Rule  int    `json:"rule"`
	Agree bool   `json:"agree"`
	Msg   string `json:"msg"`
}

type Report struct {
	ID        string             `json:"id"`
	TaskType  string             `json:"task"`
	Status    string             `json:"status"`
	Args      map[string]any     `json:"args"`
	Data      RealtimeReportData `json:"data"`
	CreatedAt uint               `json:"created_at"`
	UpdatedAt uint               `json:"updated_at"`
}

type HealthReportReq struct {
	ItemID    string `json:"itemID"`
	StartTime uint64 `json:"startTime"` // unix seconds, used when the health report is for cluster under cloud org.
	EndTime   uint64 `json:"endTime"`   // unix seconds, used when the health report is for cluster under cloud org.
}

func (req *HealthReportReq) Validate(orgType string) error {
	switch orgType {
	case "cloud":
		if len(req.ItemID) == 0 {
			if req.StartTime == 0 {
				return errors.New("startTime is zero")
			}
			if req.EndTime == 0 {
				return errors.New("endTime is zero")
			}
		}
	default:
		if len(req.ItemID) == 0 {
			return errors.New("itemID is empty")
		}
	}
	return nil
}

type HealthReportResp struct {
	Reports []HealthReport `json:"reports"`
}

type HealthReport struct {
	StartTime uint   `json:"startTime"`
	EndTime   uint   `json:"endTime"`
	ItemID    string `json:"itemID"`

	ReportExisted bool `json:"existed"`

	InRebuild bool `json:"inRebuild"`
	Progress  uint `json:"progress"`

	Status     string     `json:"status"`
	HealthData HealthData `json:"healthData"`
}

type HealthData struct {
	Data      *compute_engine.Report `json:"data"`
	CreatedAt uint                   `json:"createdAt"`
	UpdatedAt uint                   `json:"updatedAt"`
}

type TouchComparisonReportReq struct {
	PackageID1 []string `json:"packageID1"`
	StartTime1 uint     `json:"startTime1"`
	EndTime1   uint     `json:"endTime1"`

	PackageID2 []string `json:"packageID2"`
	StartTime2 uint     `json:"startTime2"`
	EndTime2   uint     `json:"endTime2"`
}

type ComparisonReportResp struct {
	Total   uint               `json:"total"`
	Reports []ComparisonReport `json:"reports"`
}

type ComparisonReport struct {
	Status    string `json:"status"`
	Creator   string `json:"creator"`
	CreatedAt uint   `json:"createdAt"`
	ID        uint   `json:"id"`

	Args db.ComparisonArg `json:"args"`
}

type TouchTrafficComparisonReportReq struct {
	Name string `json:"name"`

	ClusterID1 string `json:"clusterID1"`
	StartTime1 uint   `json:"startTime1"`
	EndTime1   uint   `json:"endTime1"`

	ClusterID2 string `json:"clusterID2"`
	StartTime2 uint   `json:"startTime2"`
	EndTime2   uint   `json:"endTime2"`
}

type ListTrafficComparisonReportResp struct {
	Total   uint                      `json:"total"`
	Reports []TrafficComparisonReport `json:"reports"`
}

type TrafficComparisonReport struct {
	ID   string `json:"id"`
	Name string `json:"name"`

	ClusterID1 string `json:"clusterID1"`
	StartTime1 uint   `json:"startTime1"`
	EndTime1   uint   `json:"endTime1"`

	ClusterID2 string `json:"clusterID2"`
	StartTime2 uint   `json:"startTime2"`
	EndTime2   uint   `json:"endTime2"`

	OverAllDiff  int    `json:"overAllDiff"`
	DatetimeDiff int    `json:"datetimeDiff"`
	Status       string `json:"status"`
	Error        string `json:"error"`
	Creator      string `json:"creator"`
	CreatedAt    uint   `json:"createdAt"`

	Data *TrafficComparisonReportData `json:"data"`
}

type TrafficComparisonReportData struct {
	MetricsDiff any `json:"metricsDiff"`
	SQLDiff     any `json:"sqlDiff"`
}
