/**
 * 一步大纲生成节点（fullOutlineNode）
 * 一次 AI 调用生成完整树形大纲：章 + 节 + 小节
 * 适用于策略2（one-step-outline）
 */

import { GraphState } from '../graph';
import { bookStore } from '../book-generator.store';
import { callLLMWithMessages, ChatMessage } from '../../../services/llm';
import { callLLMWithRetry, executeNodeWithTimeout, FAULT_TOLERANCE_CONFIG } from '../fault-tolerance';
import { PROGRESS } from '../utils';
import { getScaleConfig } from '../book-type-config';
import { prisma } from '../../../models';

/**
 * 构建一步大纲的提示词
 */
function buildFullOutlinePrompt(
  title: string,
  description: string,
  bookScale: string,
  genLevel: number,
  bookPlan?: any
): ChatMessage[] {
  const config = getScaleConfig(bookScale);
  const totalWords = config?.totalWords || 130000;

  const levelDesc: Record<number, string> = {
    1: '仅章：只生成章节列表，不要节和小节。每章直接展开写。',
    2: '章→节：每章下生成若干节，但节下不要再拆小节。',
    3: '章→节→小节：每章下生成节，节下再生成小节，完整三层结构。',
  };

  // 规划参考
  let planSection = '';
  if (bookPlan) {
    const parts: string[] = [];
    if (bookPlan.writingStyle) parts.push(`写作风格：${bookPlan.writingStyle}`);
    if (bookPlan.structureLogic) parts.push(`结构逻辑：${bookPlan.structureLogic}`);
    if (bookPlan.contentDepth) parts.push(`内容深度：${bookPlan.contentDepth}`);
    if (bookPlan.targetAudienceAnalysis) parts.push(`目标读者：${bookPlan.targetAudienceAnalysis}`);
    if (bookPlan.bookTypeAnalysis) parts.push(`书籍分析：${bookPlan.bookTypeAnalysis}`);
    if (parts.length > 0) planSection = `\n\n## 前序规划参考\n${parts.join('\n')}`;
  }

  const systemPrompt = `你是一位专业的图书策划编辑。请为以下书籍一次性生成完整的树形大纲。

## 大纲层级要求
${levelDesc[genLevel] || levelDesc[2]}

## 约束
- 总字数约${totalWords}字，章节数和字数分配要合理
- 每章 2-4 节，每节 2-4 小节（仅当 genLevel=3 时需要小节）
- 章节之间必须有清晰的逻辑递进关系
- 预估字数要符合章节内容量

## 工作要求
1. 每章必须有摘要和核心知识点
2. 每节/每小节也必须有摘要和知识点
3. 所有内容一次性输出${planSection}

## 输出格式
必须返回合法的 JSON，不要包含任何 markdown 代码块标记或其他文字：

{
  "mainTheme": "主题一句话描述",
  "structureLogic": "章节组织逻辑说明",
  "chapters": [
    {
      "number": 1,
      "title": "章标题",
      "summary": "章摘要",
      "keyPoints": ["知识点1"],
      "estimatedWords": 2000,
      "sections": [
        {
          "number": 1,
          "title": "节标题",
          "summary": "节摘要",
          "keyPoints": ["知识点1"],
          "estimatedWords": 1000,
          "subsections": [
            {
              "number": 1,
              "title": "小节标题",
              "summary": "小节摘要",
              "keyPoints": ["知识点1"],
              "estimatedWords": 500
            }
          ]
        }
      ]
    }
  ]
}

注意：genLevel=1 时每章不要 sections
      genLevel=2 时每章的 sections 下不要 subsections
      genLevel=3 时才需要完整的 sections + subsections`;

  return [
    { role: 'system', content: systemPrompt },
    {
      role: 'user',
      content: `书名：《${title}》\n${description ? `需求描述：${description}\n` : ''}\n请生成完整大纲。`,
    },
  ];
}

/**
 * 解析一步大纲的 JSON
 */
function parseFullOutline(jsonStr: string): any | null {
  try {
    let cleaned = jsonStr.trim();
    const thinkEnd = cleaned.indexOf('</think>');
    if (thinkEnd !== -1) cleaned = cleaned.substring(thinkEnd + 8).trim();
    const match = cleaned.match(/\{[\s\S]*\}/);
    if (!match) return null;

    const data = JSON.parse(match[0]);
    if (!data.chapters || !Array.isArray(data.chapters) || data.chapters.length === 0) {
      return null;
    }
    return data;
  } catch {
    return null;
  }
}

/**
 * 一步大纲生成节点
 * 从章到节到小节一次生成，并全部存入数据库
 */
export async function generateFullOutlineNode(state: typeof GraphState.State): Promise<Partial<typeof GraphState.State>> {
  console.log('[FullOutline] 一步生成完整大纲, bookId:', state.bookId, 'genLevel:', state.genLevel);

  // 读取规划结果
  let bookPlan: any = null;
  if (state.bookPlan) {
    try { bookPlan = JSON.parse(state.bookPlan); } catch { /* ignore */ }
  }

  try {
    const book = await bookStore.getById(state.bookId);
    const title = book?.title || state.topic;
    const description = book?.description || '';

    const response = await executeNodeWithTimeout(
      state.bookId,
      'generate_outline',
      async () => {
        return callLLMWithRetry(
          buildFullOutlinePrompt(title, description, state.bookScale, state.genLevel, bookPlan),
          undefined,
          { bookId: state.bookId, nodeId: 'generate_full_outline', attempt: 0, maxAttempts: FAULT_TOLERANCE_CONFIG.aiRetry.maxRetries }
        );
      },
      FAULT_TOLERANCE_CONFIG.nodeTimeout.generate_outline
    );

    const outline = parseFullOutline(response);
    if (!outline) throw new Error('一步大纲解析失败');

    // 存入数据库
    const totalChapters = outline.chapters.length;

    // 保存 outlineJson（必须，因为 GET 接口依赖此字段）
    await bookStore.update(state.bookId, {
      totalChapters,
      outlineJson: JSON.stringify(outline),
      progress: PROGRESS.OUTLINE_DONE,
      // 清理旧的失败状态（重试成功时）
      failedStage: null,
      errorMsg: null,
    });

    // 将所有层级（章+节+小节）的章节记录存入数据库
    const allRecords: Array<{
      number: number; title: string; summary: string; keyPoints: string[];
      estimatedWords: number; parentId: number; level: number;
    }> = [];

    for (let i = 0; i < outline.chapters.length; i++) {
      const chapter = outline.chapters[i];
      // 先占位创建章
      const chapterId = await createChapterRecord(state.bookId, {
        number: chapter.number ?? (i + 1), title: chapter.title,
        summary: chapter.summary, keyPoints: chapter.keyPoints,
        estimatedWords: chapter.estimatedWords,
      }, 0, 1);

      if (chapter.sections && state.genLevel >= 2) {
        for (let j = 0; j < chapter.sections.length; j++) {
          const section = chapter.sections[j];
          const sectionId = await createChapterRecord(state.bookId, {
            number: section.number ?? (j + 1), title: section.title,
            summary: section.summary || '', keyPoints: section.keyPoints || [],
            estimatedWords: section.estimatedWords || 0,
          }, chapterId, 2);

          if (section.subsections && state.genLevel >= 3) {
            for (let k = 0; k < section.subsections.length; k++) {
              const subsection = section.subsections[k];
              await createChapterRecord(state.bookId, {
                number: subsection.number ?? (k + 1), title: subsection.title,
                summary: subsection.summary || '', keyPoints: subsection.keyPoints || [],
                estimatedWords: subsection.estimatedWords || 0,
              }, sectionId, 3);
            }
          }
        }
      }
    }

    console.log('[FullOutline] 完整大纲生成完成，章节数:', totalChapters);
    return { progress: PROGRESS.OUTLINE_DONE };
  } catch (error) {
    console.error('[FullOutline] 生成失败:', error);
    await bookStore.update(state.bookId, {
      genStage: 'failed', failedStage: 'outlining',
      errorMsg: error instanceof Error ? error.message : '一步大纲生成失败',
    });
    return { error: error instanceof Error ? error.message : '失败', finished: true };
  }
}

/**
 * 清理失败的旧状态（重试成功后调用）
 */
async function clearOldFailureState(bookId: string) {
  try {
    await prisma.book.update({
      where: { id: parseInt(bookId) },
      data: {
        failedStage: null,
        errorMsg: null,
      },
    });
  } catch (e) {
    console.warn('[FullOutline] 清理旧失败状态失败:', e);
  }
}

/**
 * 辅助：创建或更新单条章节记录并返回 id
 * level=1 的章用 createChapters（已有方法），level=2/3 用 createChapterItem
 */
async function createChapterRecord(
  bookId: string,
  data: { number: number; title: string; summary: string; keyPoints: string[]; estimatedWords: number },
  parentId: number,
  level: number
): Promise<number> {
  // level=1（章）使用 bulk create 方法
  if (level === 1) {
    await bookStore.createChapters(bookId, [data]);
    // 查询刚创建的记录获取 id
    const record = await prisma.bookChapter.findFirst({
      where: { bookId: parseInt(bookId), number: data.number, level: 1, parentId: 0 },
    });
    if (!record?.id) {
      console.warn(`[FullOutline] 章节记录未找到: bookId=${bookId} number=${data.number}`);
      return 0;
    }
    return record.id;
  }

  // level=2（节）/ level=3（小节）使用 createChapterItem
  return bookStore.createChapterItem(parseInt(bookId), data, parentId, level);
}
