/**
 * @agent-bounty/contracts — TypeScript Types
 *
 * 從 Zod schema 推導出的 TypeScript 型別。
 * 永遠不要手寫這些型別——只從 z.infer 推導，確保型別與 schema 永遠同步。
 */

import type { z } from "zod";
import type {
  TaskBountySchema,
  TaskSummarySchema,
  AcceptanceCriteriaSchema,
  ClaimTaskRequestSchema,
  ClaimTaskResponseSchema,
  SubmitSolutionRequestSchema,
  SubmitSolutionResponseSchema,
  SubmitBidRequestSchema,
  SubmitBidResponseSchema,
  JudgeResultSchema,
  JudgeTestResultSchema,
  SettlementLedgerEntrySchema,
  LeadSchema,
  ListOpenTasksRequestSchema,
  ListOpenTasksResponseSchema,
} from "../schemas/index.js";
import type { VWError } from "../errors/index.js";

// ─────────────────────────────────────────────
// Task
// ─────────────────────────────────────────────

export type TaskBounty = z.infer<typeof TaskBountySchema>;
export type TaskSummary = z.infer<typeof TaskSummarySchema>;
export type AcceptanceCriteria = z.infer<typeof AcceptanceCriteriaSchema>;

// ─────────────────────────────────────────────
// MCP Tool I/O
// ─────────────────────────────────────────────

export type ClaimTaskRequest = z.infer<typeof ClaimTaskRequestSchema>;
export type ClaimTaskResponse = z.infer<typeof ClaimTaskResponseSchema>;
export type SubmitSolutionRequest = z.infer<typeof SubmitSolutionRequestSchema>;
export type SubmitSolutionResponse = z.infer<typeof SubmitSolutionResponseSchema>;
export type SubmitBidRequest = z.infer<typeof SubmitBidRequestSchema>;
export type SubmitBidResponse = z.infer<typeof SubmitBidResponseSchema>;
export type ListOpenTasksRequest = z.infer<typeof ListOpenTasksRequestSchema>;
export type ListOpenTasksResponse = z.infer<typeof ListOpenTasksResponseSchema>;

// ─────────────────────────────────────────────
// Judge
// ─────────────────────────────────────────────

export type JudgeResult = z.infer<typeof JudgeResultSchema>;
export type JudgeTestResult = z.infer<typeof JudgeTestResultSchema>;

// ─────────────────────────────────────────────
// Settlement
// ─────────────────────────────────────────────

export type SettlementLedgerEntry = z.infer<typeof SettlementLedgerEntrySchema>;

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

export type Lead = z.infer<typeof LeadSchema>;

// ─────────────────────────────────────────────
// 通用 API Response Envelope
// ─────────────────────────────────────────────

/** 統一 API 成功回應格式 */
export interface ApiSuccess<T> {
  ok: true;
  data: T;
  /** 請求追蹤 ID，供 SRE 查 log */
  request_id: string;
}

/** 統一 API 錯誤回應格式 */
export interface ApiFailure {
  ok: false;
  error: VWError;
  request_id: string;
}

export type ApiResponse<T> = ApiSuccess<T> | ApiFailure;

// ─────────────────────────────────────────────
// State Machine 合法轉換圖（型別層面防護）
// ─────────────────────────────────────────────

import type { TaskStatus } from "../enums/index.js";

/**
 * 合法的狀態轉換對。
 * 後端 API 層應驗證每次轉換是否在此集合內。
 */
export type TaskStateTransition =
  | { from: "OPEN"; to: "EXECUTING" }
  | { from: "OPEN"; to: "CANCELLED" }
  | { from: "EXECUTING"; to: "VERIFYING" }
  | { from: "EXECUTING"; to: "OPEN" }       // Redis TTL timeout rollback
  | { from: "EXECUTING"; to: "CANCELLED" }
  | { from: "EXECUTING"; to: "FAILED" }     // agent_abandon
  | { from: "VERIFYING"; to: "PENDING_REVIEW" }
  | { from: "VERIFYING"; to: "COMPLETED" }
  | { from: "VERIFYING"; to: "FAILED_RETRYABLE" }
  | { from: "VERIFYING"; to: "FAILED" }
  | { from: "PENDING_REVIEW"; to: "COMPLETED" }
  | { from: "PENDING_REVIEW"; to: "FAILED" }
  | { from: "PENDING_REVIEW"; to: "DISPUTED" }
  | { from: "FAILED_RETRYABLE"; to: "OPEN" }
  | { from: "FAILED_RETRYABLE"; to: "FAILED" }
  | { from: "FAILED"; to: "OPEN" }
  | { from: "FAILED"; to: "ARCHIVED" }
  | { from: "FAILED"; to: "DISPUTED" }
  | { from: "COMPLETED"; to: "DISPUTED" }
  | { from: "COMPLETED"; to: "PAYOUT_READY" }
  | { from: "PAYOUT_READY"; to: "PAYOUT_SETTLED" }
  | { from: "PAYOUT_SETTLED"; to: "ARCHIVED" }
  | { from: "DISPUTED"; to: "OPEN" }
  | { from: "DISPUTED"; to: "COMPLETED" }
  | { from: "DISPUTED"; to: "REFUND_PENDING" }
  | { from: "DISPUTED"; to: "ARCHIVED" }
  | { from: "REFUND_PENDING"; to: "ARCHIVED" }
  | { from: "CANCELLED"; to: "ARCHIVED" };

/** 取得從某狀態出發的合法下一狀態集合（runtime 用） */
export function getAllowedNextStatuses(current: TaskStatus): TaskStatus[] {
  const map: Partial<Record<TaskStatus, TaskStatus[]>> = {
    OPEN: ["EXECUTING", "CANCELLED"],
    EXECUTING: ["VERIFYING", "OPEN", "CANCELLED", "FAILED"],
    VERIFYING: ["PENDING_REVIEW", "COMPLETED", "FAILED_RETRYABLE", "FAILED"],
    PENDING_REVIEW: ["COMPLETED", "FAILED", "DISPUTED"],
    FAILED_RETRYABLE: ["OPEN", "FAILED"],
    FAILED: ["OPEN", "ARCHIVED", "DISPUTED"],
    COMPLETED: ["DISPUTED", "PAYOUT_READY"],
    PAYOUT_READY: ["PAYOUT_SETTLED"],
    PAYOUT_SETTLED: ["ARCHIVED"],
    DISPUTED: ["OPEN", "COMPLETED", "REFUND_PENDING", "ARCHIVED"],
    REFUND_PENDING: ["ARCHIVED"],
    CANCELLED: ["ARCHIVED"],
    ARCHIVED: [],
  };
  return map[current] ?? [];
}

/** 驗證某狀態轉換是否合法 */
export function isValidStateTransition(
  from: TaskStatus,
  to: TaskStatus
): boolean {
  return getAllowedNextStatuses(from).includes(to);
}
