package dto

import (
	"strconv"
	"time"
)

// Spec-compliant request schema (Traffic Mirroring API Design)
// type SpecTimeRange struct {
// 	From string `json:"from"`
// 	To   string `json:"to"`
// }

// type SpecClusterSide struct {
// 	ClusterID string        `json:"cluster_id"`
// 	Alias     string        `json:"alias"`
// 	Range     SpecTimeRange `json:"range"`
// }

// type SpecOptions struct {
// 	TopDigest         int  `json:"top_digest,omitempty"`
// 	IncludeTidbTopSql bool `json:"include_tidb_topsql,omitempty"`
// 	IncludeTikvTopSql bool `json:"include_tikv_topsql,omitempty"`
// }

// type QueryComparisonSpecRequest struct {
// 	Baseline SpecClusterSide `json:"baseline"`
// 	Canary   SpecClusterSide `json:"canary"`
// 	Options  SpecOptions     `json:"options,omitempty"`
// }

// type TimeRangeDTO struct {
// 	Start string `json:"start"`
// 	End   string `json:"end"`
// }

type ClusterSideDTO struct {
	ClusterId string `json:"clusterId"`
	Alias     string `json:"alias,omitempty"`
	// TimeRange TimeRangeDTO `json:"timeRange"`
	TimeRange TimeRange `json:"timeRange,omitempty"`

	ClusterUrls       ClusterUrls `json:"clusterUrls,omitempty"`
	Provider          string      `json:"provider,omitempty"`
	Region            string      `json:"region,omitempty"`
	PhysicalClusterID string      `json:"physicalClusterId,omitempty"`
	DeployType        string      `json:"deployType,omitempty"`
	TenantID          string      `json:"tenantId,omitempty"`
	ProjectID         string      `json:"projectId,omitempty"`

	// DataPlaneID string       `json:"dataPlaneId,omitempty"`
}

type QueryComparisonRequest struct {
	ClusterA ClusterSideDTO         `json:"clusterA"`
	ClusterB ClusterSideDTO         `json:"clusterB"`
	Options  QueryComparisonOptions `json:"options,omitempty"`
}
type CreateDiffReportRequest struct {
	CallBackUrl string `json:"callBackUrl"`
	QueryComparisonRequest
}

type QueryComparisonOptions struct {
	TopN           int      `json:"topN,omitempty"`
	DigestDiffKeys []string `json:"digestDiffKeys,omitempty"`
	DigestSources  []string `json:"digestSources,omitempty"`
	ReportId       string   `json:"reportId,omitempty"`
}

type DigestStat struct {
	Digest           string  `json:"digest"`
	Query            string  `json:"query,omitempty"`
	AvgMem           float64 `json:"avg_mem"`
	MaxMem           float64 `json:"max_mem"`
	AvgQueryTime     float64 `json:"avg_query_time"`
	MaxQueryTime     float64 `json:"max_query_time"`
	TotalCount       int64   `json:"total_count"`
	IsNewDigest      bool    `json:"is_new_digest,omitempty"`
	CountDiff        int64   `json:"count_diff,omitempty"`
	AvgQueryTimeDiff float64 `json:"avg_query_time_diff,omitempty"`
}

type Result struct {
	IsSuccess  bool   `json:"isSuccess"`
	ErrMessage string `json:"errMessage,omitempty"`
}
type SqlDiffResponse struct {
	DiffClusters         DiffClusters      `json:"diffClusters"`
	Result               Result            `json:"result"`
	Comments             string            `json:"comments"`
	Units                map[string]string `json:"units,omitempty"`
	Summary              *SummaryOuter     `json:"summary,omitempty"`
	ClusterDiff          []DiffInfo        `json:"clusterDiff,omitempty"`
	SlowQueryDigestDiff  *DiffGroup        `json:"slowQueryDigestDiff,omitempty"`
	TopSqlTidbDigestDiff *DiffGroup        `json:"topSqlTidbDigestDiff,omitempty"`
	TopSqlTikvDigestDiff *DiffGroup        `json:"topSqlTikvDigestDiff,omitempty"`
}

type SqlCheckResponse struct {
	DiffClusters DiffClusters      `json:"diffClusters"`
	Result       Result            `json:"result"`
	Comments     string            `json:"comments"`
	Units        map[string]string `json:"units,omitempty"`
	Summary      *SummaryOuter     `json:"summary,omitempty"`
	SqlCheckData *SqlCheckData     `json:"sqlCheckData,omitempty"`
}
type SqlCheckData struct {
	SlowQueryCountDiff   []DiffInfo `json:"slowQueryCountDiff,omitempty"`
	SlowQueryDigestDiff  *DiffGroup `json:"slowQueryDigestDiff,omitempty"`
	TopSqlTidbDigestDiff *DiffGroup `json:"topSqlTidbDigestDiff,omitempty"`
	TopSqlTikvDigestDiff *DiffGroup `json:"topSqlTikvDigestDiff,omitempty"`
}

// ParseTimeFlexible supports either Unix seconds (string) or RFC3339 timestamp string.
func ParseTimeFlexible(s string) (time.Time, error) {
	if ts, err := strconv.ParseInt(s, 10, 64); err == nil {
		return time.Unix(ts, 0).UTC(), nil
	}
	t, err := time.Parse(time.RFC3339, s)
	if err != nil {
		return time.Time{}, err
	}
	return t.UTC(), nil
}

// TopSqlDigestStat represents per-digest TiDB TopSQL metrics for comparison.
type TopSqlDigestStat struct {
	Digest           string  `json:"digest"`
	Count            float64 `json:"count"`
	AvgLatency       float64 `json:"avg_latency"`
	TotalCpuTimeTidb float64 `json:"total_cpu_time_tidb"`
	TotalCpuTimeTikv float64 `json:"total_cpu_time_tikv,omitempty"`
	Cluster          string  `json:"cluster_id"`
	Sql              string  `json:"sql,omitempty"`
}

// TopSqlTikvDigestStat represents per-digest TiKV TopSQL metrics for comparison.
type TopSqlTikvDigestStat struct {
	Digest     string  `json:"digest"`
	CpuTime    float64 `json:"cpu_time_min"`
	CpuPercent float64 `json:"cpu_percent"`
	Cluster    string  `json:"cluster_id"`
}

type DigestComparison struct {
	Digest           string  `json:"digest"`
	CountA           int64   `json:"countA"`
	CountB           int64   `json:"countB"`
	CountDiff        int64   `json:"countDiff"`
	AvgQueryTimeA    float64 `json:"avgQueryTimeA"`
	AvgQueryTimeB    float64 `json:"avgQueryTimeB"`
	AvgQueryTimeDiff float64 `json:"avgQueryTimeDiff"`
	MaxQueryTimeA    float64 `json:"maxQueryTimeA"`
	MaxQueryTimeB    float64 `json:"maxQueryTimeB"`
	MaxQueryTimeDiff float64 `json:"maxQueryTimeDiff"`
	AvgMemA          float64 `json:"avgMemA"`
	AvgMemB          float64 `json:"avgMemB"`
	AvgMemDiff       float64 `json:"avgMemDiff"`
	MaxMemA          float64 `json:"maxMemA"`
	MaxMemB          float64 `json:"maxMemB"`
	MaxMemDiff       float64 `json:"maxMemDiff"`
}

type DiffInfo struct {
	Key      string  `json:"key"`
	ClusterA float64 `json:"clusterA"`
	ClusterB float64 `json:"clusterB"`
	Diff     float64 `json:"diff"`
}

type DiffClusters struct {
	ClusterA ClusterSideDTO `json:"clusterA"`

	ClusterB ClusterSideDTO `json:"clusterB"`
}

type DiffDetail struct {
	Cloumn  string           `json:"cloumn"`
	Buckets []map[string]any `json:"buckets"`
}

type DiffGroupSummary struct {
	Added int `json:"added"`
	// AddedDigests        []string    `json:"addedDigests,omitempty"`
	Removed int `json:"removed"`
	// RemovedDigests      []string    `json:"removedDigests,omitempty"`
	ImprovedPerformance int         `json:"ImprovedPerformance"`
	ImprovedDigests     []string    `json:"improvedDigests,omitempty"`
	DegradedPerformance int         `json:"DegradedPerformance"`
	DegradedDigests     []string    `json:"degradedDigests,omitempty"`
	Stable              int         `json:"Stable"`
	DiffDetail          *DiffDetail `json:"diffDetail,omitempty"`
}
type TopSqlDiffGroupSummary struct {
	DiffGroupSummary
	ImprovedPerformance int `json:"ImprovedPerformance"`
	DegradedPerformance int `json:"DegradedPerformance"`
}

type DigestDiffEntry struct {
	Digest                 string                  `json:"digest"`
	Label                  string                  `json:"label"`
	SQL                    string                  `json:"sql,omitempty"`
	MaxCpuTimeIn5MinWindow *MaxCpuTimeIn5MinWindow `json:"MaxCpuTimeIn5MinWindow,omitempty"`
	DiffInfos              []DiffInfo              `json:"diffInfos"`
}

type MaxCpuTimeIn5MinWindow struct {
	ClusterA MaxCpuTimeInfo `json:"clusterA"`
	ClusterB MaxCpuTimeInfo `json:"clusterB"`
}
type MaxCpuTimeInfo struct {
	MaxCpuTime float64 `json:"maxCpuTime"`
	Instance   string  `json:"instance"`
	Timestamp  string  `json:"timestamp"`
}

type DiffGroup struct {
	DigestDiff []DigestDiffEntry `json:"digestDiff"`
}

type SummaryOuter struct {
	SlowQueryDigest *DiffGroupSummary `json:"slowQueryDigest,omitempty"`
	TopSqlDigest    *DiffGroupSummary `json:"topSqlDigest,omitempty"`
}
