package params

import (
	"fmt"

	"github.com/tidbcloud/pov-service/internal/common/options"
	"github.com/tidbcloud/pov-service/internal/model"
)

type RunWorkload struct {
	WorkloadID int64 `json:"workloadID"`
	// @deprecated
	WorkloadName string                `json:"workloadName"`
	Name         string                `json:"name"`
	IsAuto       *bool                 `json:"isAuto"`
	Params       *model.WorkloadParams `json:"params"`
}

func (p *RunWorkload) Validate() error {
	if p.WorkloadID == 0 {
		return fmt.Errorf("workloadID is required")
	}

	return nil
}

func (p *RunWorkload) GetTestName() string {
	if p.Name != "" {
		return p.Name
	}

	return p.WorkloadName
}

func (p *RunWorkload) GetParams() model.WorkloadParams {
	if p.Params != nil {
		return *p.Params
	}

	return nil
}

func (p *RunWorkload) GetParam(name string) *model.WorkloadParam {
	for _, param := range p.GetParams() {
		if param.Name == name {
			return &param
		}
	}
	return nil
}

func (p *RunWorkload) GetParamValue(name string) string {
	param := p.GetParam(name)
	if param != nil {
		return param.Value
	}
	return ""
}

func (p *RunWorkload) SetParam(key, name string) {
	params := p.GetParams()
	params.Set(key, name)
	p.Params = &params
}

type Sort string

const (
	SortAsc  Sort = "asc"
	SortDesc Sort = "desc"
)

type ListWorkloads struct {
	Type     model.WorkloadType `json:"type"  query:"type"`
	Keyword  string             `json:"keyword"  query:"keyword"`
	Industry string             `json:"industry"  query:"industry"`

	Sort    Sort   `json:"sort" query:"sort"`
	OrderBy string `json:"orderBy" query:"orderBy"`
	// PageSize int    `json:"pageSize" query:"pageSize"`
}

type ListWorkloadTests struct {
	Status   model.ExecStatus `json:"status"  query:"status"`
	Sort     Sort             `json:"sort" query:"sort"`
	OrderBy  string           `json:"orderBy" query:"orderBy"`
	PageSize int              `json:"pageSize" query:"pageSize"`
	Page     int              `json:"page" query:"page"`
}

func (p ListWorkloadTests) ToListOption() options.ListOption[options.WorkloadTestRefOption] {
	opt := options.ListOption[options.WorkloadTestRefOption]{}
	if p.OrderBy != "" {
		opt.OrderBy = fmt.Sprintf("%s %s", p.OrderBy, p.Sort)
	}

	if p.Status != "" {
		opt.Filters = append(opt.Filters, options.ColumnOption{
			Column: "status",
			Values: []any{p.Status},
		})
	}

	if p.Page != 0 {
		opt.Limit = p.PageSize
		opt.Offset = (p.Page - 1) * p.PageSize
	}
	return opt
}

// NOTE: All fields are declative
// which means the original values should be sent in the request too.
type UpdateWorkloadTest struct {
	MaxConn int
	MinRU   int64
	MaxRU   int64
}

// All fields are instructive
type InstructWorkloadTest struct {
	SQLStatement string
}

type ListScripts struct {
	TestID string `json:"testID"  query:"testID"`
}
