/**
 * @agent-bounty/contracts — Enums
 *
 * 所有狀態機 enum、分類常數的唯一真實來源。
 * MCP server、後端 API、前端 UI 都必須 import 這裡，禁止各自重新定義。
 */

// ─────────────────────────────────────────────
// Task 任務生命週期狀態機
// ─────────────────────────────────────────────

/**
 * TaskStatus：任務在系統中的完整生命週期。
 *
 * 狀態轉換規則（前後端、MCP、Judge Agent 必遵守）：
 *
 * OPEN
 *   → EXECUTING   (claim_task：DB SELECT FOR UPDATE + Stripe Auth-Hold + Redis setex TTL 3600s)
 *   → CANCELLED   (client_cancel)
 *
 * EXECUTING
 *   → VERIFYING          (submit_solution)
 *   → OPEN               (Redis TTL expired → rollback + 釋放 Auth-Hold)
 *   → CANCELLED          (agent_cancel / client_cancel)
 *   → FAILED             (agent_abandon)
 *
 * VERIFYING
 *   → COMPLETED          (judge exit_code=0 → Stripe Capture → Ledger)
 *   → FAILED_RETRYABLE   (judge fail retryable, or timeout ≤ 5min)
 *   → FAILED             (judge fail non-retryable)
 *
 * FAILED_RETRYABLE
 *   → OPEN               (retry_count ≤ 3, auto)
 *   → FAILED             (retry_count > 3)
 *
 * FAILED
 *   → OPEN               (policy=auto_open)
 *   → ARCHIVED           (policy=archive)
 *   → DISPUTED           (client_dispute)
 *
 * COMPLETED
 *   → DISPUTED           (client_dispute, within 72h)
 *   → PAYOUT_READY       (dispute window closed, no dispute)
 *   → PAYOUT_SETTLED     (payout processed)
 *
 * DISPUTED
 *   → OPEN               (dispute_resolved: reopen)
 *   → COMPLETED          (dispute_resolved: keep)
 *   → REFUND_PENDING     (dispute_resolved: refund)
 *   → ARCHIVED           (dispute_resolved: archive)
 *
 * REFUND_PENDING → ARCHIVED
 * CANCELLED      → ARCHIVED
 * PAYOUT_SETTLED → ARCHIVED
 * ARCHIVED       → (終態)
 */
export const TaskStatus = {
  DRAFT: "DRAFT",
  OPEN: "OPEN",
  EXECUTING: "EXECUTING",
  VERIFYING: "VERIFYING",
  COMPLETED: "COMPLETED",
  FAILED: "FAILED",
  FAILED_RETRYABLE: "FAILED_RETRYABLE",
  CANCELLED: "CANCELLED",
  DISPUTED: "DISPUTED",
  REFUND_PENDING: "REFUND_PENDING",
  PAYOUT_READY: "PAYOUT_READY",
  PAYOUT_SETTLED: "PAYOUT_SETTLED",
  ARCHIVED: "ARCHIVED",
} as const;
export type TaskStatus = (typeof TaskStatus)[keyof typeof TaskStatus];

/** 終態集合：進入後不可再轉換（除人工介入） */
export const TERMINAL_TASK_STATUSES: ReadonlySet<TaskStatus> = new Set([
  TaskStatus.ARCHIVED,
]);

/** 可從 FAILED/FAILED_RETRYABLE 自動重開的最大重試次數 */
export const MAX_TASK_RETRY_COUNT = 3;

// ─────────────────────────────────────────────
// Task 難度分級
// ─────────────────────────────────────────────

/**
 * TaskDifficulty：對應種子任務的定價與驗收複雜度。
 * HELLO_WORLD = $1 / COMPONENT = $5 / VIEW = $10 / EPIC = $20+
 */
export const TaskDifficulty = {
  HELLO_WORLD: "HELLO_WORLD",
  COMPONENT: "COMPONENT",
  VIEW: "VIEW",
  EPIC: "EPIC",
} as const;
export type TaskDifficulty = (typeof TaskDifficulty)[keyof typeof TaskDifficulty];

/** 難度對應的預設獎金（USD cents） */
export const TASK_DIFFICULTY_DEFAULT_REWARD_CENTS: Record<TaskDifficulty, number> = {
  HELLO_WORLD: 100,
  COMPONENT: 500,
  VIEW: 1000,
  EPIC: 2000,
};

// ─────────────────────────────────────────────
// Task 驗收模式
// ─────────────────────────────────────────────

export const ValidationMode = {
  VITEST_UNIT: "VITEST_UNIT",
  PLAYWRIGHT_E2E: "PLAYWRIGHT_E2E",
  AST_PARSING: "AST_PARSING",       // 僅用於靜態 HTML/CSS，不得用於 React 元件
  VISUAL_REGRESSION: "VISUAL_REGRESSION",
} as const;
export type ValidationMode = (typeof ValidationMode)[keyof typeof ValidationMode];

// ─────────────────────────────────────────────
// Judge 執行結果
// ─────────────────────────────────────────────

export const JudgeOverallResult = {
  PASS: "pass",
  FAIL: "fail",
  TIMEOUT: "timeout",
} as const;
export type JudgeOverallResult = (typeof JudgeOverallResult)[keyof typeof JudgeOverallResult];

export const JudgeTestStatus = {
  PASSED: "passed",
  FAILED: "failed",
  SKIPPED: "skipped",
} as const;
export type JudgeTestStatus = (typeof JudgeTestStatus)[keyof typeof JudgeTestStatus];

/**
 * JudgeErrorClassification：標準化失敗分類。
 * 影響後端決策：是否重試 / 扣押 Agent 分數 / 進入人工仲裁。
 */
export const JudgeErrorClassification = {
  TEST_FAIL: "TEST_FAIL",                     // 邏輯/行為不符（可 retryable）
  LINT_FAIL: "LINT_FAIL",                     // lint 錯誤（可 retryable）
  TIMEOUT: "TIMEOUT",                         // 超過 5 分鐘（可 retryable）
  RESOURCE_EXHAUSTED: "RESOURCE_EXHAUSTED",   // CPU/Memory 超限（可 retryable）
  ENVIRONMENT_ERROR: "ENVIRONMENT_ERROR",     // 沙盒或工具層失敗（不計 Agent 分）
  NETWORK_DENIED: "NETWORK_DENIED",           // 試圖違規網路存取（non-retryable）
  SANDBOX_CRASH: "SANDBOX_CRASH",             // E2B 內部崩潰（不計 Agent 分）
  TEST_SETUP_FAIL: "TEST_SETUP_FAIL",         // 映像檔缺少依賴（不計 Agent 分）
  ENV_MISCONFIG: "ENV_MISCONFIG",             // 設定錯誤（不計 Agent 分）
} as const;
export type JudgeErrorClassification = (typeof JudgeErrorClassification)[keyof typeof JudgeErrorClassification];

/** 不計入 Agent 失敗分數的環境層錯誤 */
export const JUDGE_ENVIRONMENT_ERROR_TYPES: ReadonlySet<JudgeErrorClassification> = new Set([
  JudgeErrorClassification.ENVIRONMENT_ERROR,
  JudgeErrorClassification.SANDBOX_CRASH,
  JudgeErrorClassification.TEST_SETUP_FAIL,
  JudgeErrorClassification.ENV_MISCONFIG,
]);

// ─────────────────────────────────────────────
// 金流 / Settlement
// ─────────────────────────────────────────────

export const SettlementPhase = {
  AUTH_HOLD: "auth_hold",
  CAPTURE: "capture",
  RELEASE: "release",
  REFUND: "refund",
  PAYOUT: "payout",
  DISPUTE: "dispute",
  CORRECTION: "correction",
} as const;
export type SettlementPhase = (typeof SettlementPhase)[keyof typeof SettlementPhase];

export const SettlementCaptureMode = {
  STRIPE_AUTH_CAPTURE: "STRIPE_AUTH_CAPTURE",
  BASE_SMART_CONTRACT: "BASE_SMART_CONTRACT",
} as const;
export type SettlementCaptureMode = (typeof SettlementCaptureMode)[keyof typeof SettlementCaptureMode];

export const SupportedCurrency = {
  USD: "USD",
  TWD: "TWD",
  USDC: "USDC",
} as const;
export type SupportedCurrency = (typeof SupportedCurrency)[keyof typeof SupportedCurrency];

// ─────────────────────────────────────────────
// Lead / Scout
// ─────────────────────────────────────────────

export const LeadStatus = {
  DRAFT: "DRAFT",
  CONFIRMED: "CONFIRMED",
  PAYMENT_AUTHORIZED: "PAYMENT_AUTHORIZED",
  TASK_CREATED: "TASK_CREATED",
  EXPIRED: "EXPIRED",
  CANCELLED: "CANCELLED",
} as const;
export type LeadStatus = (typeof LeadStatus)[keyof typeof LeadStatus];

/** Scout 引流歸因模式。Phase 1 強制使用 LAST_CLICK。 */
export const AttributionModel = {
  LAST_CLICK: "LAST_CLICK",
  FIRST_CLICK: "FIRST_CLICK",
  LINEAR: "LINEAR",
} as const;
export type AttributionModel = (typeof AttributionModel)[keyof typeof AttributionModel];

// ─────────────────────────────────────────────
// Error 分類
// ─────────────────────────────────────────────

export const TaskErrorClassification = {
  RETRYABLE: "retryable",
  NON_RETRYABLE: "non_retryable",
} as const;
export type TaskErrorClassification = (typeof TaskErrorClassification)[keyof typeof TaskErrorClassification];

// ─────────────────────────────────────────────
// MCP Tool 名稱（唯一常數來源）
// ─────────────────────────────────────────────

export const MCPToolName = {
  LIST_OPEN_TASKS: "list_open_tasks",
  CLAIM_TASK: "claim_task",
  SUBMIT_SOLUTION: "submit_solution",
  CHECK_PAYOUT_STATUS: "check_payout_status",
} as const;
export type MCPToolName = (typeof MCPToolName)[keyof typeof MCPToolName];
