import { logger } from '../../utils/logger';
import { WebhookService } from '../../core/integrations/WebhookService';

export enum TaskStatus {
  DRAFTED = 'DRAFTED', // 选品完成，待审核
  PENDING_REVIEW = 'PENDING_REVIEW', // 进入审核流程
  APPROVED = 'APPROVED', // 审核通过，待下发节点
  EXECUTING = 'EXECUTING', // 节点执行中
  PUBLISHED = 'PUBLISHED', // 发布成功
  FAILED_RETRYABLE = 'FAILED_RETRYABLE', // 可重试失败 (如网络)
  FAILED_MANUAL = 'FAILED_MANUAL', // 需人工干预 (如风控、账号锁定)
  RECONCILED = 'RECONCILED' // 已对账
}

export interface TaskRecord {
  id: string;
  tenantId: string;
  traceId: string;
  status: TaskStatus;
  retryCount: number;
  lastError?: string;
}

/**
 * [CORE_NODE_03] 任务状态机 (Task FSM)
 * @description 发布、审核、对账流程落入统一 FSM
 */
export class TaskFSM {
  private static readonly TRANSITIONS: Record<TaskStatus, TaskStatus[]> = {
    [TaskStatus.DRAFTED]: [TaskStatus.PENDING_REVIEW, TaskStatus.FAILED_MANUAL],
    [TaskStatus.PENDING_REVIEW]: [TaskStatus.APPROVED, TaskStatus.FAILED_MANUAL, TaskStatus.DRAFTED],
    [TaskStatus.APPROVED]: [TaskStatus.EXECUTING, TaskStatus.FAILED_RETRYABLE, TaskStatus.FAILED_MANUAL],
    [TaskStatus.EXECUTING]: [TaskStatus.PUBLISHED, TaskStatus.FAILED_RETRYABLE, TaskStatus.FAILED_MANUAL],
    [TaskStatus.PUBLISHED]: [TaskStatus.RECONCILED],
    [TaskStatus.FAILED_RETRYABLE]: [TaskStatus.EXECUTING, TaskStatus.FAILED_MANUAL],
    [TaskStatus.FAILED_MANUAL]: [TaskStatus.PENDING_REVIEW, TaskStatus.DRAFTED],
    [TaskStatus.RECONCILED]: []
  };

  /**
   * 执行状态转移
   */
  static async transit(task: TaskRecord, nextStatus: TaskStatus): Promise<void> {
    const currentStatus = task.status;
    const allowed = this.TRANSITIONS[currentStatus].includes(nextStatus);

    if (!allowed) {
      throw new Error(`Invalid transition from ${currentStatus} to ${nextStatus}`);
    }

    logger.info(`[FSM] Task ${task.id} transiting: ${currentStatus} -> ${nextStatus}`);

    // 1. 更新数据库 (Mock)
    // await db('cf_tasks').where({ id: task.id }).update({ status: nextStatus, updatedAt: Date.now() });

    // 2. 触发 Webhook 通知 (如果重要状态变化)
    if ([TaskStatus.PUBLISHED, TaskStatus.FAILED_MANUAL].includes(nextStatus)) {
      await WebhookService.trigger({
        tenantId: task.tenantId,
        eventType: nextStatus === TaskStatus.PUBLISHED ? 'TASK_PUBLISHED' : 'TASK_FAILED',
        payload: { taskId: task.id, status: nextStatus, error: task.lastError },
        traceId: task.traceId,
        timestamp: Date.now()
      });
    }

    // 3. 逻辑分发 (如发布成功触发对账、重试失败触发告警)
    if (nextStatus === TaskStatus.PUBLISHED) {
      // await FinanceService.reconcileOrder(task.id);
    }
  }
}
