package dedicated

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

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

// SlowLogListCase test case for slow query list API
type SlowLogListCase struct {
	Fields string // fields to query, comma separated
	Limit  int    // max number of records to return
}

// NewSlowLogListCase creates a new SlowLogListCase with default parameters
func NewSlowLogListCase() *SlowLogListCase {
	return &SlowLogListCase{
		Fields: "query,timestamp,query_time,memory_max,process_keys,user,db",
		Limit:  100,
	}
}

func (c *SlowLogListCase) Name() string {
	return "SlowLogList"
}

func (c *SlowLogListCase) Description() string {
	return "Verify slow query list API - /api/v1/orgs/{orgID}/projects/{projectID}/clusters/{clusterID}/ngm/slow_query/list"
}

// SlowLogItem represents a single slow log item in the list response
type SlowLogItem struct {
	Query       string  `json:"query"`
	Timestamp   float64 `json:"timestamp"`
	QueryTime   float64 `json:"query_time"`
	MemoryMax   int64   `json:"memory_max"`
	ProcessKeys int64   `json:"process_keys"`
	User        string  `json:"user"`
	DB          string  `json:"db"`
}

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

	// Check if ClinicURL is configured
	if ctx.ClinicURL == "" {
		result.AddError("ClinicURL is not configured - set clinicURL in config or use --clinic-url flag")
		return result
	}

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

	// Build time range (last 30 minutes)
	endTime := time.Now().Unix()
	beginTime := endTime - 1800 // 30 minutes ago

	// Build request URL with query parameters
	// /api/v1/orgs/{orgID}/projects/{projectID}/clusters/{clusterID}/ngm/slow_query/list
	baseURL := fmt.Sprintf("%s/api/v1/orgs/%s/projects/%s/clusters/%s/ngm/slow_query/list",
		ctx.ClinicURL,
		ctx.OrgID,
		ctx.ProjectID,
		ctx.ClusterID,
	)

	params := url.Values{}
	params.Set("begin_time", fmt.Sprintf("%d", beginTime))
	params.Set("end_time", fmt.Sprintf("%d", endTime))
	params.Set("fields", c.Fields)
	params.Set("limit", fmt.Sprintf("%d", c.Limit))
	params.Set("orderBy", "query_time")
	params.Set("desc", "true")
	params.Set("show_internal", "false")

	fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
	result.SetRequest("GET", fullURL, nil)

	// Send request
	resp, err := ctx.Client.Get(fullURL)
	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)
	// For clinic API: access-control-allow-origin is "*", access-control-allow-credentials can be absent
	checker := framework.NewCommonResponseChecker(result, ctx.Origin)
	if ctx.EnableNewPath {
		checker.CheckCORSHeaders(resp)
	} else {
		checker.CheckCORSHeadersWithOptions(resp, framework.CORSCheckOptions{
			ExpectedOrigin:      "*",
			CredentialsOptional: true,
		})
	}
	checker.CheckStatusCode(resp, 200)

	// 2. Parse response - should be an array of slow log items (can be empty)
	var slowLogList []SlowLogItem
	if err := json.Unmarshal(resp.Body, &slowLogList); err != nil {
		result.AddError(fmt.Sprintf("Failed to parse response as slow log list array: %v", err))
		return result
	}

	return result
}
