/**
 * Copyright (c) 2025 TWork Team. All rights reserved.
 * This source code is licensed under the TWork License.
 */

/**
 * 全链路自动化编排 — 类型定义
 * 涵盖节点类型、状态机状态、DTO、配置与结果结构
 */

// ==================== 枚举 ====================

/** 流程节点类型 */
export enum FlowNodeType {
  /** 编辑节点：透传模式，直接调用 complete 提交 */
  EDIT = 'edit',
  /** 审批节点：需判定合格/不合格，调用审批或驳回 API */
  APPROVAL = 'approval',
  /** 发起节点（开始） */
  START = 'start',
  /** 结束节点 */
  END = 'end',
  /** 未知类型（兜底，按编辑节点处理） */
  UNKNOWN = 'unknown',
}

/** 编排器状态机状态 */
export enum AutomationState {
  /** 初始化 */
  INIT = 'init',
  /** 流程已发起 */
  FLOW_STARTED = 'flow_started',
  /** 节点数据已获取 */
  NODE_DATA_FETCHED = 'node_data_fetched',
  /** 文档已下载 */
  DOCUMENTS_DOWNLOADED = 'documents_downloaded',
  /** 等待提示词确认(发起流程模式,Phase 1 前暂停) */
  AWAITING_PROMPT_CONFIRM = 'awaiting_prompt_confirm',
  /** 提示词已确认,继续执行 */
  PROMPT_CONFIRMED = 'prompt_confirmed',
  /** 等待用户在主输入框发送消息(两轮审核模式) */
  AWAITING_USER_INPUT = 'awaiting_user_input',
  /** 智能体已激活 */
  AGENT_ACTIVATED = 'agent_activated',
  /** 内容已生成 */
  CONTENT_GENERATED = 'content_generated',
  /** 入参MD审核通过(两轮审核模式) */
  INPUT_MD_REVIEWED = 'input_md_reviewed',
  /** 出参MD生成完成(两轮审核模式) */
  OUTPUT_MD_GENERATED = 'output_md_generated',
  /** 出参MD审核通过(两轮审核模式) */
  OUTPUT_MD_REVIEWED = 'output_md_reviewed',
  /** 校验通过 */
  VALIDATION_PASSED = 'validation_passed',
  /** 校验失败 */
  VALIDATION_FAILED = 'validation_failed',
  /** 文档已上传 */
  DOCUMENTS_UPLOADED = 'documents_uploaded',
  /** 节点已提交 */
  NODE_SUBMITTED = 'node_submitted',
  /** 节点被驳回(审批不合格) */
  NODE_REJECTED = 'node_rejected',
  /** 等待人工审核(发起流程模式) */
  AWAITING_REVIEW = 'awaiting_review',
  /** 审核通过,准备上传 */
  REVIEW_APPROVED = 'review_approved',
  /** 审核拒绝,流程终止 */
  REVIEW_REJECTED = 'review_rejected',
  /** 流程完成 */
  COMPLETED = 'completed',
  /** 发生错误 */
  ERROR = 'error',
}

// ==================== DTO 接口 ====================

/** 附件信息（来自 flowFormData 响应） */
export interface AttachmentInfo {
  /** 文件名 */
  fileName: string;
  /** 文件 ID，用于构造下载 URL */
  fileId: string;
  /** 已有完整 URL 时直接使用，优先于 fileId */
  fileUrl?: string;
}

/** 流程节点数据（flowFormData 响应主体） */
export interface FlowNodeData {
  /** 部署 ID */
  deployId: string;
  /** 流程实例 ID（发起后返回） */
  procInsId?: string;
  /** 当前任务 ID */
  taskId?: string;
  /** 节点名称 */
  nodeName: string;
  /** 节点类型 */
  nodeType: FlowNodeType;
  /** 入参 MD 文件信息 */
  inputAttachments: AttachmentInfo[];
  /** 出参 MD 文件信息 */
  outputAttachments: AttachmentInfo[];
  /** 表单变量（可选） */
  formVariables?: Record<string, unknown>;
  /** 出参 MD 模板内容（由 flowFormData 返回，供 AgentBridge 构建 Prompt 时引用） */
  outputTemplateMd?: string;
}

/** 校验规则 */
export interface ValidationRule {
  /** 规则唯一标识 */
  id: string;
  /** 规则描述 */
  description: string;
  /**
   * 校验函数
   * @param content - 文件内容
   * @param fileName - 文件名
   * @returns 校验是否通过
   */
  validate: (content: string, fileName: string) => boolean;
}

/** 编排器配置 */
export interface AutomationConfig {
  /** 云端 API 基础路径（默认从 flowable-api 的 FLOWABLE_BASE 读取） */
  baseUrl?: string;
  /** 本地文件存储目录（默认使用系统临时目录下的 flow-automation 子目录） */
  storageDir?: string;
  /** 目标智能体名称（默认 "OP工作流专家"） */
  agentName?: string;
  /** 合规校验规则列表 */
  validationRules?: ValidationRule[];
  /** 最大重试次数，默认 2 */
  maxRetries?: number;
  /** 请求超时（毫秒），默认 30000 */
  timeout?: number;
  /** ⚠️ 关键修复：会话ID，用于复用已有会话，避免创建多个会话 */
  conversationId?: string;
}

/** 历史办理记录 */
export interface FlowRecord {
  /** 节点名称 */
  nodeName?: string;
  /** 操作类型（如：complete / reject / return） */
  operation?: string;
  /** 操作人 */
  operator?: string;
  /** 操作时间 */
  operateTime?: string;
  /** 备注 / 意见 */
  comment?: string;
  /** 原始数据（兜底透传后端任意字段） */
  [key: string]: unknown;
}

/** 编排结果 */
export interface AutomationResult {
  /** 是否成功 */
  success: boolean;
  /** 流程实例 ID */
  procInsId?: string;
  /** 经过的状态序列(用于链路追踪) */
  states: AutomationState[];
  /** 输出文件本地绝对路径 */
  outputFiles?: string[];
  /** 上传后的云端 URI 列表 */
  cloudUris?: string[];
  /** 错误信息(失败时填充) */
  error?: string;
  /** 历史办理记录 */
  flowRecords?: FlowRecord[];
  /** 当前任务 ID */
  taskId?: string;
  /** 节点处理是否被驳回(审批不合格) */
  rejected?: boolean;
  /** 人工审核是否被拒绝 */
  reviewRejected?: boolean;
  /** 用户是否要求重新生成(非错误状态,由 UI 决定是否重试) */
  regenerate?: boolean;
  /** ⚠️ 新增:是否等待用户输入(新模式:主输入框编辑) */
  awaitingUserInput?: boolean;
  /** ⚠️ 新增:节点数据(等待用户输入时传递) */
  nodeData?: FlowNodeData;
  /** ⚠️ 新增:预下载文档(等待用户输入时传递) */
  preflightDocs?: Array<{ fileName: string; content: ArrayBuffer }>;
}

/** 单节点处理结果 */
export interface NodeProcessResult {
  /** 是否成功 */
  success: boolean;
  /** 上传后的云端 URI */
  cloudUris?: string[];
  /** 输出文件本地路径 */
  outputFiles?: string[];
  /** 是否被驳回 */
  rejected?: boolean;
  /** 错误信息 */
  error?: string;
}

// ==================== 进度与事件 ====================

/** 自动化进度信息（用于 UI 展示当前阶段） */
export interface AutomationProgress {
  /** 当前状态 */
  state: AutomationState;
  /** 状态描述（人类可读） */
  description: string;
  /** 进度百分比（0-100，基于状态机阶段估算） */
  percent: number;
  /** 当前处理的文件名（若有） */
  currentFile?: string;
  /** 总体已耗时（毫秒，从 pipeline 启动开始计算） */
  elapsedMs: number;
  /** 当前阶段已耗时（毫秒，从上一个状态转换开始计算） */
  stepDurationMs: number;
  /** 批量处理：当前任务序号（从 1 开始，0 表示非批量模式） */
  batchIndex?: number;
  /** 批量处理：总任务数 */
  batchTotal?: number;
}

/** 自动化事件类型（用于事件监听） */
export enum AutomationEventType {
  /** 状态变更 */
  STATE_CHANGE = 'state_change',
  /** 进度更新 */
  PROGRESS = 'progress',
  /** 错误发生 */
  ERROR = 'error',
  /** 流程完成 */
  COMPLETED = 'completed',
}

/** 自动化事件 */
export interface AutomationEvent {
  type: AutomationEventType;
  state: AutomationState;
  description?: string;
  error?: string;
  timestamp: number;
  /** 进度详情（仅 PROGRESS 类型事件携带，供 UI 直接展示 elapsedMs / currentFile） */
  progress?: AutomationProgress;
}

/** 进度回调函数类型 */
export type ProgressCallback = (progress: AutomationProgress) => void;

/** 事件监听回调类型 */
export type EventCallback = (event: AutomationEvent) => void;

/**
 * 状态机状态到进度百分比的映射
 *
 * 设计说明：
 * - NODE_SUBMITTED / NODE_REJECTED 是流程的实际终态（后续不再有其他状态转换），
 *   因此映射到 100%，确保进度条在流程结束时完整填满。
 * - COMPLETED 保留为语义扩展点（未来若编排器需要在终态后再发射一个"完成"事件）。
 * - ERROR 映射为 -1，调用方通过 `percent >= 0 ? percent : 0` 兜底为 0%，
 *   错误状态由 Alert 组件的 type="error" 样式表达，不依赖进度条百分比。
 */
export const STATE_PROGRESS_MAP: Readonly<Record<AutomationState, number>> = {
  [AutomationState.INIT]: 0,
  [AutomationState.FLOW_STARTED]: 10,
  [AutomationState.NODE_DATA_FETCHED]: 20,
  [AutomationState.DOCUMENTS_DOWNLOADED]: 35,
  [AutomationState.AWAITING_PROMPT_CONFIRM]: 40,
  [AutomationState.PROMPT_CONFIRMED]: 45,
  [AutomationState.AWAITING_USER_INPUT]: 48,
  [AutomationState.AGENT_ACTIVATED]: 55,
  [AutomationState.CONTENT_GENERATED]: 60,
  [AutomationState.INPUT_MD_REVIEWED]: 65,
  [AutomationState.OUTPUT_MD_GENERATED]: 72,
  [AutomationState.OUTPUT_MD_REVIEWED]: 85,
  [AutomationState.VALIDATION_PASSED]: 75,
  [AutomationState.VALIDATION_FAILED]: 75,
  [AutomationState.DOCUMENTS_UPLOADED]: 88,
  [AutomationState.NODE_SUBMITTED]: 100,
  [AutomationState.NODE_REJECTED]: 100,
  [AutomationState.AWAITING_REVIEW]: 72,
  [AutomationState.REVIEW_APPROVED]: 82,
  [AutomationState.REVIEW_REJECTED]: 75,
  [AutomationState.COMPLETED]: 100,
  [AutomationState.ERROR]: -1,
};

// ==================== 提示词确认回调 ====================

/** 提示词确认结果（PromptPreviewDialog 返回） */
export interface PromptConfirmResult {
  /** 是否确认（false 表示用户取消整个流程） */
  confirmed: boolean;
  /** 最终提示词（可能经过用户编辑） */
  prompt: string;
}

/**
 * 提示词确认回调函数类型
 *
 * 由 UI 层（flowable-definition-list）注入，编排器在 Phase 1 之前调用：
 * 1. 下载文档并构建完整 Prompt
 * 2. 调用此回调，弹出 PromptPreviewDialog 供用户预览/编辑/确认
 * 3. 根据返回结果决定是否继续执行 AI 生成
 */
export type PromptConfirmCallback = (
  generatedPrompt: string,
  nodeData: FlowNodeData,
) => Promise<PromptConfirmResult>;
