package entity

import (
	"time"

	"github.com/tidbcloud/devops/entity/tenant"
)

type RemediationTicketPhase = string

const (
	RemediationTicketPhaseCreated               RemediationTicketPhase = "created"
	RemediationTicketPhaseRegionTSELeader       RemediationTicketPhase = "region_tse_leader"
	RemediationTicketPhaseRDGSLAOwner           RemediationTicketPhase = "rdg_sla_owner"
	RemediationTicketPhaseRDGFinalDecisionMaker RemediationTicketPhase = "rdg_final_decision_maker"
	RemediationTicketPhaseGlobalDealDesk        RemediationTicketPhase = "global_deal_desk"
	RemediationTicketPhaseRegionalGM            RemediationTicketPhase = "regional_gm"
	RemediationTicketPhaseCommercialOperation   RemediationTicketPhase = "commercial_operation"
	RemediationTicketPhaseSucceed               RemediationTicketPhase = "succeed"
	RemediationTicketPhaseClosed                RemediationTicketPhase = "closed"
)

var RemediationTicketValidPhases = []RemediationTicketPhase{
	RemediationTicketPhaseCreated,
	RemediationTicketPhaseRegionTSELeader,
	RemediationTicketPhaseRDGSLAOwner,
	RemediationTicketPhaseRDGFinalDecisionMaker,
	RemediationTicketPhaseGlobalDealDesk,
	RemediationTicketPhaseRegionalGM,
	RemediationTicketPhaseCommercialOperation,
	RemediationTicketPhaseSucceed,
}

var RemediationTicketEndPhases = []RemediationTicketPhase{
	RemediationTicketPhaseClosed,
	RemediationTicketPhaseSucceed,
}

type RemediationTicketReason string

const (
	RemediationTicketReasonMisuse             RemediationTicketReason = "misuse"
	RemediationTicketReasonUnauthorizedModify RemediationTicketReason = "unauthorized_modify"
	RemediationTicketReason3PartyHardware     RemediationTicketReason = "3party_hardware"
	RemediationTicketReason3PartySoftware     RemediationTicketReason = "3party_software"
	RemediationTicketReasonTiDBCloud          RemediationTicketReason = "tidb_cloud"
)

type RemediationTicketStatus string

const (
	RemediationTicketStatusPending   RemediationTicketStatus = "pending"
	RemediationTicketStatusApproving RemediationTicketStatus = "approving"
	RemediationTicketStatusApproved  RemediationTicketStatus = "approved"
	RemediationTicketStatusRejected  RemediationTicketStatus = "rejected"
	RemediationTicketStatusClosed    RemediationTicketStatus = "closed" // used only in RemediationTicketPhaseClosed and RemediationTicketPhaseCanceled
)

type RemediationTicketClusterType = string

const (
	RemediationTicketClusterTypeDedicatedMultiTiDB  RemediationTicketClusterType = "dedicated_multi_tidb"
	RemediationTicketClusterTypeDedicatedSingleTiDB RemediationTicketClusterType = "dedicated_single_tidb"
	RemediationTicketClusterTypeServerless          RemediationTicketClusterType = "serverless"
)

type RemediationTicket struct {
	ID                      uint64                  `json:"id"  binding:"required"`
	AssociatedIncidentId    uint64                  `json:"associated_incident_id"`
	Phase                   *RemediationTicketPhase `json:"phase"`
	Status                  RemediationTicketStatus `json:"status"`
	ApplicantEmail          string                  `json:"applicant_email" binding:"required"`
	CurrentResponsible      string                  `json:"current_responsible_person_email"`
	Month                   string                  `json:"month"` // Should be in the format like `2006/1`
	MonthlyUptimePercentage string                  `json:"monthly_uptime_percentage"`

	// Create params
	BizRegion       *tenant.TenantRegion         `json:"biz_region"`
	Customer        *string                      `json:"customer"`
	ClusterType     RemediationTicketClusterType `json:"cluster_type"`
	TenantID        *uint64                      `json:"tenant_id"`
	ClusterID       *uint64                      `json:"cluster_id"`
	InfoFromCreator string                       `json:"info_from_creator"`

	// Region TSE Fields
	RootCauseFromGS string `json:"root_cause_from_gs"`

	// RDG SLA Owner Fields
	RootCauseFromRDG   string `json:"root_cause_from_rdg"`
	AccidentReportLink string `json:"accident_report_link"`

	// Global Deal Desk Fields
	ClusterBilling    string `json:"cluster_billing"`
	PredefinedPercent string `json:"predefined_percent"`
	ExtraPercent      string `json:"extra_percent"`
	TotalCompensation string `json:"total_compensation"`

	// Deprecated Fields, will be removed
	Reason                 *RemediationTicketReason `json:"reason"`
	ReportLink             *string                  `json:"report_link"`
	CalculatedCompensation *float64                 `json:"calculated_compensation"`
	OverflowPercentage     *float64                 `json:"overflow_percentage"`
	AccumulatedDownMinutes *int                     `json:"accumulated_down_minutes"`

	ApprID uint64 `json:"appr_id"` //// 0 stands for no associated approval

	GeneratedDocURL *string `json:"generated_doc_url"`

	Version int64 `json:"version"`

	CreatedAt int64  `json:"created_at"`
	ClosedAt  *int64 `json:"closed_at"`
	ExpireAt  *int64 `json:"expire_at"`

	// HACK: as js doesn't natively support uint64, we use string-typed cluster and tenant fields for frontend display
	Tenant  string `json:"tenant"`
	Cluster string `json:"cluster"`
}

// Ticket Progress
type RemediationTicketPhaseStatus string

const (
	RemediationTicketPhaseStatusApproved  RemediationTicketPhaseStatus = "approved"
	RemediationTicketPhaseStatusRejected  RemediationTicketPhaseStatus = "rejected"
	RemediationTicketPhaseStatusUnreached RemediationTicketPhaseStatus = "unreached"
)

type RemediationTicketPhaseInfo struct {
	Phase         RemediationTicketPhase       `json:"phase" binding:"required"`
	Status        RemediationTicketPhaseStatus `json:"status" binding:"required"`
	Time          *time.Time                   `json:"time"`
	OperatorEmail *string                      `json:"operator_email"`
	Message       *string                      `json:"message"`
}

// For demo use only, will be removed soon
type RemediationTicketAction string

const (
	RemediationTicketActionApprove RemediationTicketAction = "approve"
	RemediationTicketActionReject  RemediationTicketAction = "reject"
	RemediationTicketActionOther   RemediationTicketAction = "other"
)

type RemediationTicketLog struct {
	Id        uint64                   `json:"id" binding:"required"`
	TicketId  uint64                   `json:"ticket_id" binding:"required"`
	CreatedAt *time.Time               `json:"created_at"`
	Message   *string                  `json:"message"`
	ToPhase   *RemediationTicketPhase  `json:"to_phase"`
	FromPhase *RemediationTicketPhase  `json:"from_phase"`
	Action    *RemediationTicketAction `json:"action"`
}

type RemediationTicketPhaseApproval struct {
	Id         uint64                 `json:"id" binding:"required"`
	CreatedAt  *time.Time             `json:"created_at" binding:"required"`
	TicketId   uint64                 `json:"ticket_id" binding:"required"`
	FromPhase  RemediationTicketPhase `json:"from_phase" binding:"required"`
	ToPhase    RemediationTicketPhase `json:"to_phase" binding:"required"`
	Message    string                 `json:"message"`
	ApprovalID uint64                 `json:"approval_id" binding:"required"`
}

type RemediationApprovalFlowNodeStatus string

const (
	RemediationApprovalFlowNodeStatusPending   RemediationApprovalFlowNodeStatus = "pending"
	RemediationApprovalFlowNodeStatusApproving RemediationApprovalFlowNodeStatus = "approving"
	RemediationApprovalFlowNodeStatusApproved  RemediationApprovalFlowNodeStatus = "approved"
	RemediationApprovalFlowNodeStatusRejected  RemediationApprovalFlowNodeStatus = "rejected"
	RemediationApprovalFlowNodeStatusUnreached RemediationApprovalFlowNodeStatus = "unreached"
	RemediationApprovalFlowNodeStatusSkipped   RemediationApprovalFlowNodeStatus = "skipped"
)

type RemediationApprovalFlowNodeAction string

const (
	RemediationApprovalFlowNodeActionNone             RemediationApprovalFlowNodeAction = "none"
	RemediationApprovalFlowNodeActionApprove          RemediationApprovalFlowNodeAction = "approve"
	RemediationApprovalFlowNodeActionApproveWithInput RemediationApprovalFlowNodeAction = "approve_with_input"
	RemediationApprovalFlowNodeActionSubmitInput      RemediationApprovalFlowNodeAction = "submit_input"
	RemediationApprovalFlowNodeActionWait             RemediationApprovalFlowNodeAction = "wait"
)

type RemediationApprovalFlowApprover struct {
	Source string `json:"source"`
	Type   string `json:"type"`
	ID     string `json:"id"`
	Name   string `json:"name"`
	Email  string `json:"email,omitempty"`
}

type RemediationApprovalFlowNode struct {
	Phase       RemediationTicketPhase             `json:"phase"`
	Label       string                             `json:"label"`
	Conditional bool                               `json:"conditional"`
	Current     bool                               `json:"current"`
	Status      RemediationApprovalFlowNodeStatus  `json:"status"`
	Approvers   []*RemediationApprovalFlowApprover `json:"approvers"`
	ApprovalID  *uint64                            `json:"approval_id,omitempty"`
	Operator    *string                            `json:"operator,omitempty"`
	OperatedAt  *time.Time                         `json:"operated_at,omitempty"`
	Message     *string                            `json:"message,omitempty"`

	RequiresInput bool                              `json:"requires_input"`
	AutoAdvance   bool                              `json:"auto_advance"`
	Action        RemediationApprovalFlowNodeAction `json:"action"`
}

type RemediationApprovalFlow struct {
	TicketID      uint64                         `json:"ticket_id"`
	CurrentPhase  RemediationTicketPhase         `json:"current_phase"`
	CurrentStatus RemediationTicketStatus        `json:"current_status"`
	Nodes         []*RemediationApprovalFlowNode `json:"nodes"`
}
