package dispatch

import (
	"time"

	triageent "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/entity/ticket-manager/triage"
)

type (
	ExecutionMode         string
	ExecutionStatus       string
	Outcome               string
	ActionExecutionStatus string
)

const (
	ExecutionModeLive   ExecutionMode = "live"
	ExecutionModeDryRun ExecutionMode = "dry_run"

	ExecutionStatusCreated   ExecutionStatus = "created"
	ExecutionStatusExecuting ExecutionStatus = "executing"
	ExecutionStatusSucceeded ExecutionStatus = "succeeded"
	ExecutionStatusFailed    ExecutionStatus = "failed"

	OutcomeNotEvaluated Outcome = "not_evaluated"
	OutcomeNotMatched   Outcome = "not_matched"
	OutcomeMatched      Outcome = "matched"
	OutcomeSystemError  Outcome = "system_error"

	ActionExecutionStatusPending   ActionExecutionStatus = "pending"
	ActionExecutionStatusExecuting ActionExecutionStatus = "executing"
	ActionExecutionStatusSucceeded ActionExecutionStatus = "succeeded"
	ActionExecutionStatusFailed    ActionExecutionStatus = "failed"
	ActionExecutionStatusSkipped   ActionExecutionStatus = "skipped"

	TriageProjectionStatusApplied        TriageProjectionStatus = "applied"
	TriageProjectionStatusAlreadyApplied TriageProjectionStatus = "already_applied"
	TriageProjectionStatusStaleSkipped   TriageProjectionStatus = "stale_skipped"

	ExecutionFailureCodeTriageRunnerTimeout = "TRIAGE_RUNNER_TIMEOUT"
)

type TriageProjectionStatus string

type ActionExecutionContextAssign struct {
	ReceiverName           string     `json:"receiver_name,omitempty"`
	ReceiverMappingValue   *string    `json:"receiver_mapping_value,omitempty"`
	Assignee               *string    `json:"assignee,omitempty"`
	Candidates             []string   `json:"candidates,omitempty"`
	OncallQueryAt          *time.Time `json:"oncall_query_at,omitempty"`
	Reason                 string     `json:"reason,omitempty"`
	RemoveAutoAssignLabels []string   `json:"remove_auto_assign_labels,omitempty"`
}

type ActionExecutionContextEscalate struct {
	EscalateTo             EscalateTo `json:"escalate_to"`
	TargetStatus           string     `json:"target_status"`
	TransitionID           string     `json:"transition_id,omitempty"`
	RemoveAutoAssignLabels []string   `json:"remove_auto_assign_labels,omitempty"`
}

type ActionExecutionContextRetrigger struct {
	AvailableAt       *time.Time `json:"available_at,omitempty"`
	DispatchTriggerID *uint64    `json:"dispatch_trigger_id,omitempty"`
}

type ActionExecutionContextTriage struct {
	InputSchemaVersion      string                      `json:"input_schema_version"`
	InputHash               string                      `json:"input_hash,omitempty"`
	IssueKey                string                      `json:"issue_key,omitempty"`
	ProjectKey              string                      `json:"project_key,omitempty"`
	IssueUpdatedAt          int64                       `json:"issue_updated_at,omitempty"`
	OnCallTier              string                      `json:"on_call_tier,omitempty"`
	ComponentCandidates     []triageent.ComponentOption `json:"component_candidates,omitempty"`
	SourceIssueKeys         []string                    `json:"source_issue_keys,omitempty"`
	SourceCommentCount      int                         `json:"source_comment_count,omitempty"`
	SourceCommentsTruncated bool                        `json:"source_comments_truncated,omitempty"`
	SourcesTruncated        bool                        `json:"sources_truncated,omitempty"`

	// Deprecated: retained so historical v2 execution contexts can still be decoded.
	EscalationIssueKeys         []string `json:"escalation_issue_keys,omitempty"`
	EscalationCommentCount      int      `json:"escalation_comment_count,omitempty"`
	EscalationCommentsTruncated bool     `json:"escalation_comments_truncated,omitempty"`
	EscalationsTruncated        bool     `json:"escalations_truncated,omitempty"`

	// Deprecated: retained so historical v1 execution contexts can still be decoded.
	ParentIssueKeys   []string `json:"parent_issue_keys,omitempty"`
	ChildIssueKeys    []string `json:"child_issue_keys,omitempty"`
	CommentCount      int      `json:"comment_count,omitempty"`
	CommentsTruncated bool     `json:"comments_truncated,omitempty"`
	ParentsTruncated  bool     `json:"parents_truncated,omitempty"`
	ChildrenTruncated bool     `json:"children_truncated,omitempty"`

	Result                *triageent.Result      `json:"result,omitempty"`
	AgentGatewaySessionID string                 `json:"agent_gateway_session_id,omitempty"`
	AgentGatewayTaskID    string                 `json:"agent_gateway_task_id,omitempty"`
	SkillVersion          string                 `json:"skill_version,omitempty"`
	GeneratedAt           *time.Time             `json:"generated_at,omitempty"`
	ProjectionStatus      TriageProjectionStatus `json:"projection_status,omitempty"`
}

type ActionExecutionContextTransitionIssue struct {
	TargetStatus string `json:"target_status"`
	TransitionID string `json:"transition_id,omitempty"`
}

type ActionExecutionContextSendWebRequest struct {
	URL        string            `json:"url"`
	Method     WebRequestMethod  `json:"method"`
	Body       string            `json:"body,omitempty"`
	Headers    map[string]string `json:"headers,omitempty"`
	StatusCode *int              `json:"status_code,omitempty"`
}

type ActionExecutionContextSendAssignmentNotification struct {
	Role                      AssignmentRole `json:"role"`
	Label                     string         `json:"label"`
	ExpectedTargetAccountID   string         `json:"expected_target_account_id,omitempty"`
	ExpectedTargetEmail       string         `json:"expected_target_email,omitempty"`
	ExpectedTargetName        string         `json:"expected_target_name,omitempty"`
	ExpectedTargetActive      bool           `json:"expected_target_active"`
	TargetLarkOpenID          string         `json:"target_lark_open_id,omitempty"`
	ProjectKey                string         `json:"project_key,omitempty"`
	Priority                  string         `json:"priority,omitempty"`
	Severity                  string         `json:"severity,omitempty"`
	Status                    string         `json:"status,omitempty"`
	UrgencyField              string         `json:"urgency_field,omitempty"`
	UrgencyValues             []string       `json:"urgency_values,omitempty"`
	CardPhase                 string         `json:"card_phase,omitempty"`
	CardStatus                string         `json:"card_status,omitempty"`
	MessageID                 string         `json:"message_id,omitempty"`
	NotificationCommentPhase  string         `json:"notification_comment_phase,omitempty"`
	NotificationCommentStatus string         `json:"notification_comment_status,omitempty"`
	LabelPhase                string         `json:"label_phase,omitempty"`
	Warning                   string         `json:"warning,omitempty"`
}

type ActionExecutionContextMarkAssignmentMessageUrgent struct {
	Phase             string `json:"phase,omitempty"`
	Status            string `json:"status,omitempty"`
	TerminationReason string `json:"termination_reason,omitempty"`
	AckCommentPhase   string `json:"ack_comment_phase,omitempty"`
	AckCommentStatus  string `json:"ack_comment_status,omitempty"`
	Warning           string `json:"warning,omitempty"`
}

type ActionExecutionContextPageAssignment struct {
	Attempt                   int        `json:"attempt"`
	AckPendingStatuses        []string   `json:"ack_pending_statuses"`
	AckTimeout                string     `json:"ack_timeout"`
	PollInterval              string     `json:"poll_interval"`
	Deadline                  *time.Time `json:"deadline,omitempty"`
	PagePhase                 string     `json:"page_phase,omitempty"`
	PageStatus                string     `json:"page_status,omitempty"`
	CallMethod                string     `json:"call_method,omitempty"`
	CallError                 string     `json:"call_error,omitempty"`
	LastObservedAt            *time.Time `json:"last_observed_at,omitempty"`
	TerminationReason         string     `json:"termination_reason,omitempty"`
	NotificationCommentPhase  string     `json:"notification_comment_phase,omitempty"`
	NotificationCommentStatus string     `json:"notification_comment_status,omitempty"`
	AckCommentPhase           string     `json:"ack_comment_phase,omitempty"`
	AckCommentStatus          string     `json:"ack_comment_status,omitempty"`
	Warning                   string     `json:"warning,omitempty"`
}

type ActionExecutionContextEscalateAssignmentToLeader struct {
	Phase             string `json:"phase,omitempty"`
	Outcome           string `json:"outcome,omitempty"`
	LeaderAccountID   string `json:"leader_account_id,omitempty"`
	LeaderEmail       string `json:"leader_email,omitempty"`
	TerminationReason string `json:"termination_reason,omitempty"`
	AckCommentPhase   string `json:"ack_comment_phase,omitempty"`
	AckCommentStatus  string `json:"ack_comment_status,omitempty"`
	Warning           string `json:"warning,omitempty"`
}

type ActionExecutionContext struct {
	Assign                      *ActionExecutionContextAssign                      `json:"assign,omitempty"`
	Escalate                    *ActionExecutionContextEscalate                    `json:"escalate,omitempty"`
	Retrigger                   *ActionExecutionContextRetrigger                   `json:"retrigger,omitempty"`
	TransitionIssue             *ActionExecutionContextTransitionIssue             `json:"transition_issue,omitempty"`
	SendWebRequest              *ActionExecutionContextSendWebRequest              `json:"send_web_request,omitempty"`
	Triage                      *ActionExecutionContextTriage                      `json:"triage,omitempty"`
	SendAssignmentNotification  *ActionExecutionContextSendAssignmentNotification  `json:"send_assignment_notification,omitempty"`
	MarkAssignmentMessageUrgent *ActionExecutionContextMarkAssignmentMessageUrgent `json:"mark_assignment_message_urgent,omitempty"`
	PageAssignment              *ActionExecutionContextPageAssignment              `json:"page_assignment,omitempty"`
	EscalateAssignmentToLeader  *ActionExecutionContextEscalateAssignmentToLeader  `json:"escalate_assignment_to_leader,omitempty"`
}

type ActionExecution struct {
	Index   int                     `json:"index"`
	Status  ActionExecutionStatus   `json:"status"`
	Planned bool                    `json:"planned,omitempty"`
	Context *ActionExecutionContext `json:"context"`
}

type RuleEvaluation struct {
	Outcome Outcome `json:"outcome"`
	Reason  string  `json:"reason"`
}

type RuleExecution struct {
	ID       uint64 `json:"id"`
	Sequence int    `json:"sequence"`

	Evaluation       RuleEvaluation    `json:"evaluation"`
	ActionExecutions []ActionExecution `json:"action_executions"`

	ExecutionID uint64 `json:"execution_id"`
	RuleID      uint64 `json:"rule_id"`
}

type ExecutionOverwriteData struct {
	Now *time.Time `json:"now,omitempty"`
}

type Execution struct {
	ID       uint64 `json:"id,omitempty"`
	IssueKey string `json:"issue_key"`

	Mode     ExecutionMode   `json:"mode"`
	PolicyID *uint64         `json:"policy_id,omitempty"`
	Status   ExecutionStatus `json:"status"`

	RuleExecutions []RuleExecution        `json:"rule_executions"`
	FailureCode    string                 `json:"failure_code,omitempty"`
	FailureReason  string                 `json:"failure_reason,omitempty"`
	OverwriteData  ExecutionOverwriteData `json:"overwrite_data,omitempty"`

	CreatedAt   time.Time  `json:"created_at,omitempty"`
	UpdatedAt   *time.Time `json:"updated_at,omitempty"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
}
