/**
 * LangGraph 书籍生成器 - 主入口（策略门面）
 *
 * 使用策略模式，通过 strategies/selector.ts 配置切换不同生成方案
 *
 * 当前支持策略：
 *   1. sequential          - 串行（原始方案）
 *   2. one-step-outline     - 一步大纲 + 并行内容
 *   3. per-chapter          - 逐章内聚
 *   4. deep-plan-parallel   - DeepPlan+RichOutline+Concurrent+Edit（当前推荐，默认策略）
 *
 * 大纲层级（genLevel）：
 *   1 = 仅章（短文/小说/故事类）
 *   2 = 章→节（科普/商业/大众类）
 *   3 = 章→节→小节（教材/技术教程/专业类）
 *
 * 成本追踪：通过 AsyncLocalStorage 上下文，所有 LLM/TTS 调用自动携带 bookId/chapterId
 */

import { bookStore } from './book-generator.store';
import { getScaleConfig } from './book-type-config';
import { getCurrentStrategy, setCurrentStrategy, getAllStrategies, getCurrentStrategyName } from './strategies/selector';
import type { StrategyName } from './strategies/selector';
import { runWithContext } from '../../services/llm-context';

// ============ 书籍类型 → 大纲层级映射 ============

const BOOK_TYPE_GEN_LEVEL: Record<string, number> = {
  '教材': 3,
  '技术教程': 3,
  '小说': 1,
  '传记': 1,
  '商业': 2,
  '科普': 2,
  '历史': 2,
  '学术': 3,
  '心理学': 2,
};

/**
 * 将书籍类型映射为大纲层级
 */
export function mapBookTypeToGenLevel(bookType: string): number {
  return BOOK_TYPE_GEN_LEVEL[bookType] ?? 2;
}

/**
 * 根据书籍规模和话题文本自动推荐大纲层级
 * 增强版：如未指定 genLevel，会从话题文本推断书籍类型→层级
 */
export function resolveGenLevel(bookScale: string, userGenLevel?: number | string, topic?: string): number {
  if (userGenLevel !== undefined && userGenLevel !== null) {
    const n = typeof userGenLevel === 'string' ? parseInt(userGenLevel) : userGenLevel;
    if ([1, 2, 3].includes(n)) return n;
  }
  const config = getScaleConfig(bookScale);
  if (!config) return 2;
  if (config.isShortArticle) return 1;

  // 从话题文本推断书籍类型，增强 genLevel 推荐准确度
  if (topic) {
    const text = topic.toLowerCase();
    if (/教材|教程|编程|开发|实战|教学|课程/i.test(text)) return 3;
    if (/小说|故事|传记|散文|诗歌/i.test(text)) return 1;
  }

  return 2;
}

// ============ 策略切换 API（外部可调用） ============

export { setCurrentStrategy, getCurrentStrategyName, getAllStrategies } from './strategies/selector';
export type { StrategyName } from './strategies/selector';

// ============ 主类（策略门面） ============

export class LangGraphBookGenerator {
  async generate(
    bookId: string,
    topic: string,
    bookScale: string = '1000',
    genLevel?: number,
    userId?: number,
  ): Promise<void> {
    const userSpecified = genLevel !== undefined;
    const level = genLevel ?? resolveGenLevel(bookScale, undefined, topic);

    const strategy = getCurrentStrategy();
    console.log(`[LangGraph] 开始生成: bookId=${bookId}, userId=${userId ?? '-'}, scale=${bookScale}, genLevel=${level}, strategy=${strategy.name}`);

    // 设置异步上下文，后续所有 LLM/TTS 调用自动携带 userId / bookId
    await runWithContext({ userId, bookId: parseInt(bookId) }, async () => {
      await strategy.generate(bookId, topic, bookScale, level, userSpecified ? level : undefined);
    });
  }
}

export const langGraphGenerator = new LangGraphBookGenerator();

// 重新导出 book-type-config 中的函数供外部使用
export { getScaleConfig } from './book-type-config';

// ============ 独立大纲生成函数（供 API 预览调用，不依赖完整策略） ============

import { callLLMWithMessages } from '../../services/llm';
import { buildOutlineMessages } from './prompts/builder';
import { parseOutline } from './parsers/outline.parser';

/**
 * 独立的大纲生成函数（供 API 预览调用，不依赖策略系统）
 * 用于让用户在正式开始生成前预览大纲结构
 */
export async function generateOutline(bookId: string, topic: string, bookScale: string = '1000'): Promise<any> {
  console.log('[generateOutline] 预览大纲, bookId:', bookId, 'scale:', bookScale);

  const messages = buildOutlineMessages(topic, bookScale);
  const response = await callLLMWithMessages(messages);
  const outline = parseOutline(response);

  if (!outline) {
    throw new Error('大纲解析失败');
  }

  return outline;
}
