package shared

import (
	"encoding/json"
	"fmt"
	"net/url"
	"strconv"
	"time"

	"github.com/tidbcloud/observability/test/webconsolee2e/framework"
)

// StmtListCase test case for shared cluster SQL statements list API
type StmtListCase struct {
	Fields string
}

func NewStmtListCase() *StmtListCase {
	return &StmtListCase{
		Fields: "digest_text,sum_latency,avg_latency,max_latency,min_latency,exec_count,plan_count",
	}
}

func (c *StmtListCase) Name() string {
	return "StmtList"
}

func (c *StmtListCase) Description() string {
	return "Verify SQL statements list API for shared cluster - /api/v1/orgs/{orgID}/projects/{projectID}/clusters/{clusterID}/ngm/statements/list"
}

// StmtListResponse statement list response (can be null or empty array)
type StmtListResponse []StmtListItem

type StmtListItem struct {
	DigestText string  `json:"digest_text,omitempty"`
	SumLatency float64 `json:"sum_latency,omitempty"`
	AvgLatency float64 `json:"avg_latency,omitempty"`
	MaxLatency float64 `json:"max_latency,omitempty"`
	MinLatency float64 `json:"min_latency,omitempty"`
	ExecCount  int64   `json:"exec_count,omitempty"`
	PlanCount  int64   `json:"plan_count,omitempty"`
}

func (c *StmtListCase) Run(ctx *framework.TestContext) *framework.CaseResult {
	result := framework.NewCaseResult()

	// Set clinic-specific headers (X-Deploy-Type, X-Provider, X-Region)
	setClinicHeaders(ctx)

	// Build time range: last 3 hours
	now := time.Now().Unix()
	endTime := now
	startTime := now - 3*60*60 // 3 hours ago

	// Build request URL for shared cluster
	// URL pattern: {clinicURL}/api/v1/orgs/{orgID}/projects/{projectID}/clusters/{clusterID}/ngm/statements/list
	params := url.Values{}
	params.Set("begin_time", strconv.FormatInt(startTime, 10))
	params.Set("end_time", strconv.FormatInt(endTime, 10))
	params.Set("text", "")
	params.Set("fields", c.Fields)

	requestURL := fmt.Sprintf("%s/api/v1/orgs/%s/projects/%s/clusters/%s/ngm/statements/list?%s",
		ctx.ClinicURL,
		ctx.OrgID,
		ctx.ProjectID,
		ctx.ClusterID,
		params.Encode(),
	)
	result.SetRequest("GET", requestURL, nil)

	// Send request
	resp, err := ctx.Client.Get(requestURL)
	if err != nil {
		result.AddError(fmt.Sprintf("Request failed: %v", err))
		return result
	}

	result.SetRequestWithHeaders(result.Request.Method, result.Request.URL, resp.RequestHeaders, result.Request.Body)
	result.SetResponseWithHeaders(resp.StatusCode, resp.GetResponseHeaders(), resp.String())

	// 1. Check common response headers (CORS)
	checker := framework.NewCommonResponseChecker(result, ctx.Origin)
	checker.CheckCORSHeaders(resp)
	checker.CheckStatusCode(resp, 200)

	// 2. Parse response body (can be null or empty array for shared clusters)
	// Response can be: null, [], or [{...}]
	var respBody StmtListResponse
	if string(resp.Body) == "null" || string(resp.Body) == "[]" {
		// Empty result is acceptable
		respBody = []StmtListItem{}
	} else {
		if err := json.Unmarshal(resp.Body, &respBody); err != nil {
			result.AddError(fmt.Sprintf("Failed to parse response JSON: %v", err))
			return result
		}
	}

	// 3. Verify it's a valid array (empty is acceptable for shared clusters)
	if respBody == nil {
		// Initialize to empty slice if nil
		respBody = []StmtListItem{}
	}

	return result
}
