//! TypeScript 类型定义 — 与 Rust Record 结构体严格对齐

// ============================================================
// 灵感
// ============================================================

// IdeaRecord.status union 类型 — 值集对齐后端 IdeaStatus serde (df-types/src/types.rs:52)
// snake_case: draft | pending_review | approved | rejected | promoted | archived
export type IdeaStatus = 'draft' | 'pending_review' | 'approved' | 'rejected' | 'promoted' | 'archived'

export interface IdeaRecord {
  id: string
  title: string
  description: string
  status: IdeaStatus
  priority: number
  score: number | null
  tags: string | null // JSON 数组字符串
  source: string | null
  promoted_to: string | null
  ai_analysis: string | null
  scores: string | null
  created_at: string
  updated_at: string
}

export interface CreateIdeaInput {
  title: string
  description?: string
  priority?: number
  tags?: string
  source?: string
}

// ============================================================
// 项目
// ============================================================

// ProjectRecord.status union 类型 — 值集对齐后端 ProjectStatus serde (df-types/src/types.rs:90)
// snake_case: planning | in_progress | testing | releasing | completed | paused | cancelled
// 注:前端 constants/dashboard 的 'active' 是 UI 虚拟派生态(非 record 落库值),不进此 union。
export type ProjectStatus =
  | 'planning' | 'in_progress' | 'testing' | 'releasing' | 'completed' | 'paused' | 'cancelled'

export interface ProjectRecord {
  id: string
  name: string
  description: string
  status: ProjectStatus
  idea_id: string | null
  /** 绑定的本地代码目录绝对路径(null=未绑定) */
  path: string | null
  /** 技术栈 JSON 数组字符串(如 ["rust","vue"],null=未探测) */
  stack: string | null
  created_at: string
  updated_at: string
}

export interface CreateProjectInput {
  name: string
  description?: string
  idea_id?: string
  /** 绑定的本地代码目录(可选) */
  path?: string
  /** 技术栈 JSON 数组字符串(可选,空则后端自动探测) */
  stack?: string
}

/** AI 扫描项目结果(预览用,用户确认后填入) */
export interface AiScanResult {
  /** 项目摘要(空=LLM 未得出,需手填) */
  description: string
  /** 技术栈(规则 ∪ LLM,去重小写) */
  stack: string[]
  /** 项目类型(web/api/cli/library/desktop/mobile/monorepo/other) */
  project_type: string | null
  /** LLM 原始返回(降级时含错误信息) */
  raw: string | null
}

/** 灵感晋升结果（后端 promote_idea 返回） */
export interface PromotionResult {
  idea_id: string
  project_id: string
  promoted: boolean
  reason: string
}

// ============================================================
// 任务
// ============================================================

// TaskRecord.status union 类型 — 值集对齐后端 TaskStatus serde (df-types/src/types.rs:131)
// snake_case: todo | in_progress | in_review | testing | done | blocked | cancelled
// 注:constants/project.ts 的 mapLegacyStatus 兜底老 DB 旧态(completed/review_ready/merged/abandoned),
// 仅在 taskStatusLabel/taskStatusClass 辅助函数内映射,record.status 本身经后端 is_valid 拦截无旧态。
export type TaskStatus =
  | 'todo' | 'in_progress' | 'in_review' | 'testing' | 'done' | 'blocked' | 'cancelled'

export interface TaskRecord {
  id: string
  project_id: string
  title: string
  description: string
  status: TaskStatus
  priority: number // 0=critical, 1=high, 2=medium, 3=low
  branch_name: string | null
  assignee: string | null
  workflow_def_id: string | null
  base_branch: string | null
  /** review 退回累计轮数(in_review→in_progress / testing→in_review 各 +1) */
  review_rounds: number
  /**
   * 任务产出 JSON 字符串(决策 a:task 中心,产出跟 task 走)。
   * schema: { text: string, model?: string, usage?: {...}, review?: {
   *   verdict: 'pass'|'fail'|'unknown', summary: string, suggestions: string[], ... } }
   * 旧任务无产出时为 undefined。前端 parsedOutput try/catch 兜底解析。
   */
  output_json?: string
  created_at: string
  updated_at: string
}

export interface CreateTaskInput {
  project_id: string
  title: string
  description?: string
  priority?: number
  branch_name?: string
  assignee?: string
}

// ============================================================
// 工作流
// ============================================================

// WorkflowRecord.status union 类型 — 值集对齐后端 WorkflowStatus serde (df-types/src/types.rs:195)
// snake_case: pending | running | paused | completed | failed | cancelled
export type WorkflowStatus =
  | 'pending' | 'running' | 'paused' | 'completed' | 'failed' | 'cancelled'

export interface WorkflowRecord {
  id: string
  name: string
  dag_json: string
  status: WorkflowStatus
  triggered_by: string | null
  project_id: string | null
  task_id: string | null
  created_at: string
  completed_at: string | null
}

/** 工作流事件载荷（后端 emit 的结构） */
/** 工作流事件类型字面量联合(对应后端 WorkflowEvent serde tag=type rename_all=snake_case，R7收窄防写错 type 字符串) */
export type WorkflowEventType =
  | 'node_started' | 'node_progress' | 'node_output' | 'node_completed' | 'node_failed' | 'node_cancelled'
  | 'workflow_paused' | 'workflow_completed' | 'workflow_failed'
  | 'human_approval_request' | 'human_approval_response'

export interface WorkflowEventPayload {
  execution_id: string
  event: {
    type: WorkflowEventType
    [key: string]: unknown
  }
}

// ============================================================
// 通用
// ============================================================

export type UpdateField = {
  id: string
  field: string
  value: string
}

// ============================================================
// 数据变更联动刷新(AR-11 方案A)
// ============================================================

/**
 * 后端 AI 工具(create/update/delete/restore/purge/bind_directory 等)执行成功后
 * emit 的 "df-data-changed" 事件负载。前端 store listen 后按 entity 调对应 load 刷新列表。
 */
export interface DfDataChangedPayload {
  /** 变更实体:project / task / idea */
  entity: 'project' | 'task' | 'idea'
  /** 变更动作:create / update / delete */
  action: 'create' | 'update' | 'delete'
}

// ============================================================
// AI 聊天
// ============================================================

export interface AiProviderConfig {
  id: string
  name: string
  provider_type: string
  api_key: string
  base_url: string
  default_model: string
  models: string | null
  /** 模型能力配置数组(F-01:4 维度 + 路由控制;DB TEXT 列 JSON 解析,老库可能缺失) */
  model_configs?: ModelConfig[]
  is_default: boolean
  config: string | null
  created_at: string
  updated_at: string
  /** provider 是否进入负载均衡池(F-260614-04c)。false=仅配置存在,不参与主链路由/选池。老库默认 true。 */
  enabled?: boolean
  /** provider 在负载均衡池中的选择权重(0-100,F-260614-04c)。高权重优先被选为主;同权重近似轮询。老库默认 50。 */
  weight?: number
}

// ============================================================
// F-01 模型能力系统(ModelConfig,与 crates/df-ai-core/src/model.rs 严格对齐)
// ============================================================

/** 维度 1 — 模态(模型能接收什么输入)。serde snake_case 字面量。 */
export type Modality = 'text' | 'vision' | 'audio' | 'video'

/** 维度 2 — 能力(模型能做什么)。serde snake_case 字面量。 */
export type Capability = 'tool_use' | 'embedding' | 'code_gen'

/** 维度 3 — 价格分级(成本)。serde snake_case 字面量。'free' 已删(B-260618-05 死档,预设/启发式从不赋值)。 */
export type CostTier = 'low' | 'medium' | 'high'

/** 维度 4 — 智力分级。serde snake_case 字面量。CR-260618-11#3:与 CostTier 同,cost/intel 已从路由硬过滤(B-260618-03)及前端标签(UX-260618-04)去除,字段保留仅 DB 兼容,不再参与路由选模型。 */
export type IntelligenceTier = 'lite' | 'standard' | 'plus' | 'ultra'

/** 探测来源(只读,由后端探测器填充)。serde snake_case 字面量。 */
export type ProbeSource = 'user_set' | 'preset_table' | 'heuristic' | 'default'

/** 单模型完整配置(4 维度 + 路由控制 + 探测元数据)。 */
export interface ModelConfig {
  /** 模型名(如 "glm-4v-flash") */
  model_id: string
  /** 启用/禁用(false=配了但不参与路由) */
  enabled: boolean
  /** 用户自定义别名(可选) */
  label?: string
  /** 模态集合 */
  modalities: Modality[]
  /** 能力集合 */
  capabilities: Capability[]
  /** 价格分级 */
  cost_tier: CostTier
  /** 智力分级 */
  intelligence: IntelligenceTier
  /** 权重(0-100,同能力候选中优先选权重高的) */
  weight: number
  /** 上下文窗口大小(tokens) */
  context_window: number
  /** 探测来源(可选) */
  probe_source?: ProbeSource
}

/**
 * AI 错误分类字面量集(B-260615-42)。
 * 与后端 `commands::ai::ErrorType` 的 serde(rename_all = "snake_case") 严格对齐。
 * 前端消费方 switch 于此常量集做差异化提示(auth 引导填 key / network 提示连接 / 等)。
 */
export type AiErrorType = 'auth' | 'network' | 'timeout' | 'provider_config' | 'unknown'

/** AI 聊天事件（后端 emit 的结构，conversation_id 用于多对话流式路由） */
export type AiChatEvent = ({
  type: 'AiTextDelta'; delta: string
} | {
  type: 'AiToolCallStarted'; id: string; name: string; args: unknown
} | {
  type: 'AiToolCallCompleted'; id: string; result: unknown
} | {
  // AE-2025-04 会话级信任:同会话已批准过同类操作(同工具+同目录)自动放行,前端显示轻量 toast。
  // 不写消息/不动 pending(Started/Completed 仍独立发),仅提示性事件。
  type: 'AiToolAutoApproved'; id: string; tool: string; dir: string
} | {
  type: 'AiApprovalRequired'; id: string; name: string; args: unknown; reason: string; diff?: string
} | {
  type: 'AiApprovalResult'; id: string; approved: boolean
} | {
  // UX-2025-04 / CR-30-2 / 决策 F-260616-07 a1: incomplete 标记流中途失败保文(网络中断),
  // 前端据此差异化展示(如系统提示「⚠ 响应因网络中断不完整」)。正常完成/停止均为 undefined。
  type: 'AiCompleted'; total_tokens: number; prompt_tokens: number; completion_tokens: number; incomplete?: boolean
} | {
  type: 'AiError'; error: string; error_type?: AiErrorType
} | {
  type: 'AiAgentRound'; round: number
} | {
  type: 'AiHeartbeat'
} | {
  // F-260616-03: 达 max_iterations 暂停态(后端仍 generating=true),前端展示操作卡询问继续/停止
  type: 'AiMaxRoundsReached'
} | {
  // F-260616-07: 流式调用自动重试提示(前端可在错误气泡内显示「重试 n/m」)
  type: 'AiStreamRetry'; attempt: number; max_attempts: number
}) & {
  conversation_id?: string
}

/**
 * 多模态消息内容片(F-260614-05 Phase 2b 前端类型,对齐后端 df-ai-core ContentPart)。
 *
 * 后端 serde:`#[serde(tag = "type", rename_all = "snake_case")]`,
 * 前端 discriminator 用字面量 `type` 字段('text' | 'image'),与后端 wire 格式严格对齐。
 * Image 片:url / base64 二选一(base64 非空时 url 忽略),media_type 仅 base64 模式必填。
 */
export type ContentPart =
  | { type: 'text'; text: string }
  | {
      type: 'image'
      url?: string | null
      base64?: string | null
      /** base64 模式必填(image/png|jpeg|webp|gif);url 模式可空 */
      media_type?: string | null
      /** 可选 alt(vision 模型/降级文本时用) */
      alt?: string | null
    }

/** AI 消息（前端渲染用，isError 标记错误消息用于差异化样式） */
export interface AiMessage {
  id: string
  role: 'user' | 'assistant' | 'tool' | 'system'
  content: string
  isError?: boolean
  toolCalls?: AiToolCallInfo[]
  /** 生成该消息的 model(仅 assistant 消息,历史消息从 DB 读) */
  model?: string
  /**
   * 多模态内容片(F-260614-05 Phase 2b)。
   * undefined/空=纯文本消息(content 即全部载荷);非空含 Image 片=多模态消息,
   * 用户气泡内渲染 <img>(base64 data URI 或 url)。仅 user 消息有(parts 来自粘贴/拖拽输入)。
   * 历史消息从 DB JSON 反序列化时透传(useAiConversations switchConversation)。
   */
  parts?: ContentPart[]
  timestamp: number
}

// AiToolCallInfo.status union 类型 — 前端构建(后端无对应 struct,经 audit log/stream event 组装)。
// 值集核验:grep src/composables/ai + src/components 实际使用点 = {running,pending_approval,completed,rejected}。
// 前端为权威源(无后端 enum 约束),保持现状仅抽 alias 便于复用。
export type AiToolCallStatus = 'running' | 'pending_approval' | 'completed' | 'rejected'

/** 工具调用信息 */
export interface AiToolCallInfo {
  id: string
  name: string
  args: unknown
  status: AiToolCallStatus
  result?: unknown
  /** 审批风险说明（AiApprovalRequired 时填充） */
  reason?: string
  /** AE-2025-03：write_file 行级 unified diff（旧文件 vs 新内容），审批卡即时预览。
   *  旧文件不存在（新建）或非 write_file 为 undefined，前端回退显新 content。 */
  diff?: string
}

/** 对话列表摘要 */
export interface AiConversationSummary {
  id: string
  title: string | null
  provider_id: string | null
  model: string | null
  archived: boolean
  pinned?: boolean
  prompt_tokens?: number | null
  completion_tokens?: number | null
  created_at: string
  updated_at: string
}

/** 审批选择类型(F-260615-01: single=单选默认,multiple=多选) */
export type ApprovalSelectType = 'single' | 'multiple'

/** 人工审批请求 */
export interface HumanApprovalRequest {
  execution_id: string
  node_id: string
  title: string
  description: string
  options: string[]
  /** F-260615-01: 缺省 single(向后兼容),multiple 时允许多选 */
  select_type?: ApprovalSelectType
}

/** 人工审批响应 */
export interface HumanApprovalResponse {
  execution_id: string
  node_id: string
  decision: string
  /** F-260615-01: 多选结果(single 时长度=1,multiple 时长度≥1) */
  decisions?: string[]
  comment?: string
}

/** 切换对话返回（含 messages JSON） */
export interface AiConversationDetail {
  id: string
  title: string | null
  messages: string  // JSON string of ChatMessage[]
  /** 生成中返回 true(后端 ai_conversation_switch 在 generating 时置)，前端据此禁编辑(FR-C5) */
  readonly?: boolean
}

/** 技能信息（本机 Claude skill，供 `/` 联想 + 注入） */
export interface SkillInfo {
  name: string
  description: string
  argument_hint?: string
  /** skill | command | plugin */
  source: string
  /** SKILL.md 绝对路径（后端注入时读全文） */
  path: string
}

// ============================================================
// 知识库
// ============================================================

/** 知识条目（与 Rust KnowledgeRecord 严格对齐） */
export interface KnowledgeRecord {
  id: string
  kind: string // review_rule | prompt_template | pitfall | architecture_pattern | diagnosis | deployment_note | workflow_optimization
  title: string
  content: string
  tags: string | null // JSON 数组字符串
  status: string // candidate | pending_review | published | archived
  confidence: string | null // high | medium | low
  reuse_count: number
  verified: boolean
  source_project: string | null
  source_ref: string | null
  /** AI 提炼判断依据("为何值得沉淀"),手动录入为 null */
  reasoning: string | null
  created_at: string
  updated_at: string
}

/** 创建知识入参 */
export interface CreateKnowledgeInput {
  kind: string
  title: string
  content: string
  tags?: string
  source_project?: string
  source_ref?: string
  confidence?: string
}

/** 检索知识入参 */
export interface KnowledgeSearchInput {
  query: string
  kind?: string
  limit?: number
}

/** 知识生命线事件记录(产生/审核/引用/归档审计) */
export interface KnowledgeEventRecord {
  id: string
  knowledge_id: string
  /** created | extracted | status_changed | referenced */
  event_type: string
  source_ref: string | null
  /** JSON 字符串,内容因 event_type 而异(见后端 KnowledgeTimeline) */
  context_json: string | null
  timestamp: string
}

/** 知识详情聚合负载(基本信息 + 全部生命线事件) */
export interface KnowledgeDetailPayload {
  knowledge: KnowledgeRecord
  events: KnowledgeEventRecord[]
}

/** 编辑知识入参(部分更新,仅传需改字段) */
export interface UpdateKnowledgeInput {
  title?: string
  content?: string
  tags?: string
  confidence?: string
  reasoning?: string
}

/** 知识库行为配置（提取 + 注入 + 向量检索） */
export interface KnowledgeConfig {
  auto_extract: boolean
  trigger_mode: 'on_complete' | 'on_idle' | 'manual_only'
  min_messages: number
  idle_timeout_ms: number
  auto_inject: boolean
  /** 语义检索(向量)开关,默认 false——关闭时纯 LIKE 零外部依赖 */
  vector_enabled: boolean
  /** embedding 用的 provider id(仅 openai_compat 类型) */
  embedding_provider_id: string | null
  /** embedding 模型名(如 embedding-3) */
  embedding_model: string | null
}
