package shared

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

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

// setClinicHeaders sets clinic-specific headers for shared cluster requests
// and sets X-Deploy-Type to "shared".
func setClinicHeaders(ctx *framework.TestContext) {
	// Parse regionID to extract provider and region
	// Format: "provider-region" e.g., "aws-us-east-1"
	provider := "aws"
	region := ""

	if ctx.RegionID != "" {
		parts := strings.SplitN(ctx.RegionID, "-", 2)
		if len(parts) >= 2 {
			provider = parts[0]
			region = parts[1]
		} else {
			region = ctx.RegionID
		}
	}

	// Set clinic-specific headers for shared cluster
	ctx.Client.SetHeader("X-Deploy-Type", "shared")
	ctx.Client.SetHeader("X-Provider", provider)
	if region != "" {
		ctx.Client.SetHeader("X-Region", region)
	}
}

// SlowLogListCase test case for shared cluster slow query list API
type SlowLogListCase struct {
	Limit int
}

func NewSlowLogListCase() *SlowLogListCase {
	return &SlowLogListCase{
		Limit: 100,
	}
}

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

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

// SlowLogListResponse slow query list response structure (can be empty array)
type SlowLogListResponse []SlowLogItem

type SlowLogItem struct {
	Query       string  `json:"query,omitempty"`
	Timestamp   int64   `json:"timestamp,omitempty"`
	QueryTime   float64 `json:"query_time,omitempty"`
	RU          float64 `json:"ru,omitempty"`
	ProcessKeys int64   `json:"process_keys,omitempty"`
	User        string  `json:"user,omitempty"`
	DB          string  `json:"db,omitempty"`
}

func (c *SlowLogListCase) 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 30 minutes
	now := time.Now().Unix()
	endTime := now
	startTime := now - 30*60 // 30 minutes ago

	// Build request URL for shared cluster
	// URL pattern: {clinicURL}/api/v1/orgs/{orgID}/projects/{projectID}/clusters/{clusterID}/ngm/slow_query/list
	params := url.Values{}
	params.Set("begin_time", strconv.FormatInt(startTime, 10))
	params.Set("end_time", strconv.FormatInt(endTime, 10))
	params.Set("fields", "query,timestamp,query_time,ru,process_keys,user,db")
	params.Set("limit", strconv.Itoa(c.Limit))
	params.Set("orderBy", "query_time")
	params.Set("desc", "true")
	params.Set("show_internal", "false")

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

	// Send request with special headers for shared cluster
	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 empty array)
	var respBody SlowLogListResponse
	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 = []SlowLogItem{}
	}

	return result
}
