/**
 * 基础策略 - 共享的 graph 执行、进度监控、错误处理逻辑
 */

import { StateGraph, END } from '@langchain/langgraph';
import { GraphState } from '../graph';
import { bookStore } from '../book-generator.store';
import { startProgressMonitor } from '../fault-tolerance';

/** 基础策略选项 */
export interface BaseStrategyOptions {
  name: string;
  description: string;
  buildGraph: () => ReturnType<typeof buildAndCompile>;
}

function buildAndCompile() {
  const workflow = new StateGraph(GraphState);
  return { workflow, addEdge: workflow.addEdge.bind(workflow) };
}

/**
 * 运行一个 LangGraph 工作流并处理结果
 * 所有策略的 graph 执行逻辑相同，只是 graph 结构不同
 */
export async function runGraphWorkflow(
  bookId: string,
  initialState: typeof GraphState.State,
  workflow: StateGraph<typeof GraphState.State, any, any, any, any>
): Promise<void> {
  await bookStore.update(bookId, { genStage: 'outlining', progress: 0 });

  const stopMonitor = startProgressMonitor(bookId);

  try {
    const graph = workflow.compile();
    const stream = await graph.stream(initialState);
    for await (const step of stream) {
      const stepName = Object.keys(step).join(',');
      if (stepName !== 'progress') {
        console.log(`[Graph] Step:`, stepName);
      }
    }

    // 检查最终状态
    const finalBook = await bookStore.getById(bookId);
    if (finalBook && finalBook.genStage !== 'failed') {
      const finalStage = finalBook.genStage || 'content_completed';
      const stageUpdate: any = { progress: 100 };
      if (['content_completed', 'audio_generating', 'audio_completed'].includes(finalStage)) {
        stageUpdate.genStage = finalStage;
      }
      await bookStore.update(bookId, stageUpdate);
      // 只有最终态 video_completed 才自动发布
      if (finalStage === 'video_completed') {
        await bookStore.publishAlbum(bookId);
      }
      console.log(`[Strategy] 生成完成，genStage: ${finalStage}`);
    } else {
      console.log('[Strategy] 生成失败，保持 failed 状态');
    }
  } catch (error) {
    console.error('[Strategy] 生成失败:', error);
    // 尝试从数据库获取当前真实阶段，作为 failedStage
    let failedStage = 'outlining';
    try {
      const currentBook = await bookStore.getById(bookId);
      if (currentBook?.genStage) {
        failedStage = currentBook.genStage;
      }
    } catch { /* 取不到就用默认值 */ }
    await bookStore.update(bookId, {
      genStage: 'failed',
      failedStage,
      errorMsg: error instanceof Error ? error.message : '生成失败',
    });
  } finally {
    stopMonitor();
  }
}
