/**
 * 状态系统 - 阶段管理器
 * 线性阶段模型：统一的状态字段 + 阶段索引比较
 */

import { prisma } from '../../models';
import { ChapterGenStage, BookGenStage } from './book-generator.types';

// 重新导出通用类型（统一从 book-generator.types.ts 获取定义）
export type { ChapterGenStage, BookGenStage };

// ============ 阶段索引（用于比较大小） ============

const CHAPTER_STAGE_ORDER: ChapterGenStage[] = [
  'idle',                // 0
  'outline_completed',   // 1
  'content_generating',  // 2
  'content_completed',   // 3
  'audio_generating',    // 4
  'audio_completed',     // 5
  'video_generating',    // 6
  'video_completed',     // 7
  'failed',              // 8（终态）
];

export function chapterStageIndex(s: ChapterGenStage): number {
  return CHAPTER_STAGE_ORDER.indexOf(s);
}

// ============ 章节转移矩阵 ============

const CHAPTER_VALID_TRANSITIONS: Record<ChapterGenStage, ChapterGenStage[]> = {
  'idle': ['content_generating', 'failed'],
  'outline_completed': ['content_generating', 'failed'],
  'content_generating': ['content_completed', 'failed'],
  'content_completed': ['audio_generating', 'audio_completed', 'content_generating', 'failed'],
  'audio_generating': ['audio_completed', 'content_completed', 'failed'],  // 允许音频失败回退到 content_completed
  'audio_completed': ['video_generating', 'audio_generating', 'content_generating', 'failed'],
  'video_generating': ['video_completed', 'failed'],
  'video_completed': ['video_generating', 'audio_generating', 'content_generating', 'failed'],
  'failed': ['content_generating', 'audio_generating', 'video_generating', 'idle'],
};

// ============ 资源清理规则 ============

/**
 * 判断本次章节转移是否需要清理下游资源。
 * 如果目标阶段比某资源的阶段索引更小，则清除该资源。
 */
export function getCleanupForChapterRegression(
  targetStage: ChapterGenStage,
): { audioUrl?: null; audioDuration?: number; videoUrl?: null; videoDuration?: number | null } {
  const targetIdx = chapterStageIndex(targetStage);
  const audioStageIdx = chapterStageIndex('audio_completed');    // 4
  const videoStageIdx = chapterStageIndex('video_completed');    // 6

  const clean: any = {};
  if (targetIdx < audioStageIdx) {
    clean.audioUrl = null;
    clean.audioDuration = 0;
  }
  if (targetIdx < videoStageIdx) {
    clean.videoUrl = null;
    clean.videoDuration = null;
  }
  return clean;
}

// ============ 安全转移函数 ============

/**
 * 安全转移章节状态
 * 验证转移矩阵 + 乐观锁 + 资源清理
 */
export async function safeTransitionChapter(
  chapterId: number,
  currentStage: ChapterGenStage,
  targetStage: ChapterGenStage,
): Promise<void> {
  // ① 验证是否在转移矩阵中
  const allowed = CHAPTER_VALID_TRANSITIONS[currentStage];
  if (!allowed || !allowed.includes(targetStage)) {
    throw new Error(
      `非法状态转移：Chapter ${chapterId} 当前 ${currentStage}，` +
      `不允许转到 ${targetStage}。允许的转移：[${allowed?.join(', ') || '无'}]`
    );
  }

  // ② 判断是否需要清理下游资源
  const cleanData = getCleanupForChapterRegression(targetStage);

  // ③ 乐观锁写入
  const result = await prisma.bookChapter.updateMany({
    where: { id: chapterId, genStage: currentStage },
    data: { genStage: targetStage, ...cleanData },
  });

  if (result.count === 0) {
    // 如果状态已经被其他操作改变，查询当前实际状态
    const currentChapter = await prisma.bookChapter.findUnique({
      where: { id: chapterId },
      select: { genStage: true }
    });
    const actualStage = currentChapter?.genStage || 'unknown';

    // 如果目标阶段和实际阶段相同，说明已经转移过了，这不是错误
    if (actualStage === targetStage) {
      console.log(`[safeTransition] 章节 ${chapterId} 已处于 ${targetStage}，跳过`);
      return;
    }

    // 如果是回退到 failed 状态（可能之前已经失败了），也跳过
    if (currentStage === 'failed' && targetStage !== 'idle') {
      console.log(`[safeTransition] 章节 ${chapterId} 已在 failed 状态，跳过转移到 ${targetStage}`);
      return;
    }

    // 其他情况：记录警告但不崩溃
    console.warn(`[safeTransition] 章节 ${chapterId} 状态冲突：预期 ${currentStage}，实际 ${actualStage}，目标 ${targetStage}`);
    return;
  }
}

/**
 * 安全转移书籍状态
 */
// ============ 上层封装 ============

/**
 * 前进：推进到下一个阶段。只能前进不能回退。
 * 例：content_completed → audio_generating
 */
export async function advanceChapter(
  chapterId: number,
  targetStage: ChapterGenStage,
): Promise<void> {
  const chapter = await prisma.bookChapter.findUniqueOrThrow({
    where: { id: chapterId },
  });

  const cur = chapter.genStage as ChapterGenStage;
  const curIdx = chapterStageIndex(cur);
  const tgtIdx = chapterStageIndex(targetStage);

  if (tgtIdx <= curIdx) {
    // 不允许回退或同级跳转（由 regenerateChapter 处理）
    throw new Error(
      `advanceChapter 不能用于回退：当前 ${cur}，目标 ${targetStage}。` +
      `请使用 regenerateChapter()`
    );
  }

  await safeTransitionChapter(chapterId, cur, targetStage);
}

/**
 * 重新生成：回退到上游阶段（或同级 generating 状态）以重新生成。
 * 自动清除下游资源。
 * 例：audio_completed → audio_generating（重新生成音频）
 *     audio_completed → content_generating（从内容重新开始）
 *     failed → audio_generating（失败重试）
 */
export async function regenerateChapter(
  chapterId: number,
  targetStage: ChapterGenStage,
): Promise<void> {
  const chapter = await prisma.bookChapter.findUniqueOrThrow({
    where: { id: chapterId },
  });

  const cur = chapter.genStage as ChapterGenStage;
  await safeTransitionChapter(chapterId, cur, targetStage);
}

// ============ Book 联动回退逻辑 ============

