import {
  useState,
  useCallback,
  Dispatch,
  SetStateAction,
  useMemo,
} from "react";
import { ScriptEditUseCase, ScriptEditKey } from "../usecase/ScriptEditUseCase";
import {
  getProjectScript,
  abortVideoTask,
} from "../../../api/video_flow";
import { parseScriptBlock } from "../domain/service";
import { ScriptBlock } from "@/components/script-renderer/types";

/**
 * 剧本服务Hook接口
 * 定义剧本服务Hook的所有状态和操作方法
 */
export interface UseScriptService {
  // 响应式状态
  /** 加载状态 */
  loading: boolean;
  /** 故事梗概 */
  synopsis: string;
  /** 故事分类 */
  categories: string[];
  /** 主角*/
  protagonist: string;
  /** 激励事件 */
  incitingIncident: string;
  /** 问题与新目标 */
  problem: string;
  /** 冲突与障碍 */
  conflict: string;
  /** 赌注 */
  stakes: string;
  /** 人物弧线完成 */
  characterArc: string;
  /** 项目ID */
  projectId: string;
  /** AI优化要求 */
  aiOptimizing: string;
  /** 渲染数据 */
  scriptBlocksMemo: ScriptBlock[];
  // 操作方法
  /** 根据用户想法生成剧本并自动创建项目 */
  generateScriptFromIdea: (idea: string) => Promise<void>;
  /** 根据项目ID初始化已有剧本 */
  initializeFromProject: (projectId: string, script: string) => Promise<void>;
  /** 修改剧本 */
  updateScript: () => Promise<void>;
  /** 应用剧本到视频生成流程 */
  applyScript: () => Promise<void>;
  /** 中断视频任务 */
  abortVideoTask: () => Promise<void>;
  /** 增强剧本 */
  enhanceScript: () => Promise<void>;
  /** 设置AI优化要求 */
  setAiOptimizing: Dispatch<SetStateAction<string>>;

  // 修改字段的set函数
  /** 设置故事梗概 */
  setSynopsis: Dispatch<SetStateAction<string>>;
  /** 设置故事分类 */
  setCategories: Dispatch<SetStateAction<string[]>>;
  /** 设置主角名称 */
  setProtagonist: Dispatch<SetStateAction<string>>;
  /** 设置激励事件 */
  setIncitingIncident: Dispatch<SetStateAction<string>>;
  /** 设置问题与新目标 */
  setProblem: Dispatch<SetStateAction<string>>;
  /** 设置冲突与障碍 */
  setConflict: Dispatch<SetStateAction<string>>;
  /** 设置赌注 */
  setStakes: Dispatch<SetStateAction<string>>;
  /** 设置人物弧线完成 */
  setCharacterArc: Dispatch<SetStateAction<string>>;

  /** 设置项目ID */
  setProjectId: Dispatch<SetStateAction<string>>;
  /** 创建项目 */
  createMovieProjectV1: (
    idea: string,
    userId: string,
    mode: "automatic" | "manual",
    resolution: string,
    language: string,
    video_duration: string
  ) => Promise<void>;
  /** 设置任何属性 */
  setAnyAttribute: any;
}

/**
 * 剧本服务Hook
 * 提供剧本相关的所有状态管理和操作方法
 * 包括剧本生成、项目创建、剧本保存等功能
 */
export const useScriptService = (): UseScriptService => {
  // 响应式状态
  const [loading, setLoading] = useState<boolean>(false);
  const [synopsis, setSynopsis] = useState<string>("");
  const [categories, setCategories] = useState<string[]>([]);
  const [protagonist, setProtagonist] = useState<string>("");
  const [incitingIncident, setIncitingIncident] = useState<string>("");
  const [problem, setProblem] = useState<string>("");
  const [conflict, setConflict] = useState<string>("");
  const [stakes, setStakes] = useState<string>("");
  const [characterArc, setCharacterArc] = useState<string>("");
  const [projectId, setProjectId] = useState<string>("");
  const [aiOptimizing, setAiOptimizing] = useState<string>("");
  const [fieldOld, setFieldOld] = useState<string>("");//旧的剧本内容

  // UseCase实例
  const [scriptEditUseCase, setScriptEditUseCase] = useState<ScriptEditUseCase>(
    new ScriptEditUseCase("")
  );
  /**
   * 根据用户想法生成剧本并自动创建项目
   * @param idea 用户想法
   */
  const generateScriptFromIdea = useCallback(
    async (idea: string,project_id?:string): Promise<void> => {
      try {
        setLoading(true);
        if(project_id){
          setProjectId(project_id);
        }
        // 调用AI生成剧本
        await scriptEditUseCase.generateScript(idea, (content) => {
          // 获取解析后的故事详情
          const storyDetails = scriptEditUseCase.getStoryDetails();
          setSynopsis(storyDetails.synopsis || "");
          setCategories(storyDetails.categories || []);
          setProtagonist(storyDetails.protagonist || "");
          setIncitingIncident(storyDetails.incitingIncident || "");
          setProblem(storyDetails.problem || "");
          setConflict(storyDetails.conflict || "");
          setStakes(storyDetails.stakes || "");
          setCharacterArc(storyDetails.characterArc || "");
        });

        // 自动保存剧本到项目
        // await scriptEditUseCase.saveScript((projectId||project_id) as string);
      } catch (error) {
        console.error("生成剧本失败:", error);
        throw error;
      } finally {
        setLoading(false);
      }
    },
    [projectId, scriptEditUseCase]
  );

  const createMovieProjectV1 = useCallback(
    async (
      idea: string,
      userId: string,
      mode: "automatic" | "manual",
      resolution: string,
      language: string,
      video_duration: string
    ): Promise<void> => {
      try {
        setLoading(true);

        // 剧本生成完成后，自动创建项目
        const projectData = await scriptEditUseCase.createProject(
          idea,
          userId,
          mode as "automatic" | "manual",
          resolution as "720p" | "1080p" | "4k",
          language,
          video_duration
        );

        setProjectId(projectData.project_id);
      } catch (error) {
        console.error("创建项目失败:", error);
        throw error;
      } finally {
        setLoading(false);
      }
    },
    [scriptEditUseCase]
  );
  /**
   * 根据项目ID初始化已有剧本
   * @param projectId 项目ID
   */
  const initializeFromProject = useCallback(
    async (projectId: string,script:string): Promise<void> => {
      try {
        setLoading(true);

        // 设置项目ID
        setProjectId(projectId);

        // 调用API获取项目剧本数据
        const response = await getProjectScript({ project_id: projectId });
        if(response.data.generated_script===''){
           await generateScriptFromIdea(script,projectId)
          return
        }
        if (!response.successful) {
          throw new Error(response.message || "获取项目剧本失败");
        }

        const { generated_script } = response.data;

        // 创建新的剧本编辑用例并初始化数据
        const newScriptEditUseCase = new ScriptEditUseCase(generated_script);
        setScriptEditUseCase(newScriptEditUseCase);

        // 获取解析后的故事详情
        const storyDetails = newScriptEditUseCase.getStoryDetails();
        setSynopsis(storyDetails.synopsis || "");
        setCategories(storyDetails.categories || []);
        setProtagonist(storyDetails.protagonist || "");
        setIncitingIncident(storyDetails.incitingIncident || "");
        setProblem(storyDetails.problem || "");
        setConflict(storyDetails.conflict || "");
        setStakes(storyDetails.stakes || "");
        setCharacterArc(storyDetails.characterArc || "");
      } catch (error) {
        console.error("初始化项目剧本失败:", error);
        throw error;
      } finally {
        setLoading(false);
      }
    },
    [generateScriptFromIdea]
  );

  /**
   * 修改剧本
   * @param scriptText 新的剧本文本
   */
  const updateScript = useCallback(async (): Promise<void> => {
    if (scriptEditUseCase) {
      // 更新解析后的故事详情
      const storyDetails = scriptEditUseCase.getStoryDetails();
      // 如果有项目ID，则保存剧本
      // if (projectId) {
      //   await scriptEditUseCase.saveScript(projectId);
      // }
    }
  }, [scriptEditUseCase, projectId]);

  /**
   * 应用剧本到视频生成流程
   */
  const applyScript = useCallback(async (): Promise<void> => {
    try {
      setLoading(true);

      if (!scriptEditUseCase) {
        throw new Error("剧本编辑用例未初始化");
      }

      if (!projectId) {
        throw new Error("项目ID或计划ID未设置");
      }

      await scriptEditUseCase.applyScript(projectId);
    } catch (error) {
      console.error("应用剧本失败:", error);
      throw error;
    } finally {
      setLoading(false);
    }
  }, [scriptEditUseCase, projectId]);

  /**
   * 中断视频任务
   */
  const abortVideoTaskHandler = useCallback(async (): Promise<void> => {
    try {
      if (!projectId) {
        throw new Error("项目ID或计划ID未设置");
      }

      // 调用中断视频任务API
      const response = await abortVideoTask({
        project_id: projectId,
      });

      if (!response.successful) {
        throw new Error(response.message || "中断视频任务失败");
      }

      console.log("视频任务中断成功");
    } catch (error) {
      console.error("中断视频任务失败:", error);
      throw error;
    }
  }, [projectId]);

  // 封装的setter函数，同时更新hook状态和scriptEditUseCase中的值对象
  const setSynopsisWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue = typeof value === "function" ? value(synopsis) : value;
      console.log('setSynopsisWrapper', newValue);
      setSynopsis(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("synopsis", newValue);
      }
    },
    [synopsis, scriptEditUseCase]
  );

  const setCategoriesWrapper = useCallback(
    (value: SetStateAction<string[]>, needUpdate: boolean=true) => {
      const newValue = typeof value === "function" ? value(categories) : value;
      setCategories(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("categories", newValue);
      }
    },
    [categories, scriptEditUseCase]
  );

  const setProtagonistWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue = typeof value === "function" ? value(protagonist) : value;
      setProtagonist(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("protagonist", newValue);
      }
    },
    [protagonist, scriptEditUseCase]
  );

  const setIncitingIncidentWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue =
        typeof value === "function" ? value(incitingIncident) : value;
      setIncitingIncident(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("incitingIncident", newValue);
      }
    },
    [incitingIncident, scriptEditUseCase]
  );

  const setProblemWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue = typeof value === "function" ? value(problem) : value;
      setProblem(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("problem", newValue);
      }
    },
    [problem, scriptEditUseCase]
  );

  const setConflictWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue = typeof value === "function" ? value(conflict) : value;
      setConflict(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("conflict", newValue);
      }
    },
    [conflict, scriptEditUseCase]
  );

  const setStakesWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue = typeof value === "function" ? value(stakes) : value;
      setStakes(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("stakes", newValue);
      }
    },
    [stakes, scriptEditUseCase]
  );

  const setCharacterArcWrapper = useCallback(
    (value: SetStateAction<string>, needUpdate: boolean=true) => {
      const newValue =
        typeof value === "function" ? value(characterArc) : value;
      setCharacterArc(newValue);
      if (scriptEditUseCase && needUpdate) {
        scriptEditUseCase.updateStoryField("characterArc", newValue);
      }
    },
    [characterArc, scriptEditUseCase]
  );

  const setAnyAttributeWrapper = useCallback(
    (type: string, value: string,needUpdate: boolean=true,callback: (old: string) => void=() => {}) => {
      console.log('setAnyAttributeWrapper', type);
      if (type === 'synopsis') {
        setFieldOld(synopsis)
        scriptEditUseCase.replaceScript(fieldOld,value )
        setSynopsisWrapper(value, needUpdate);
      } else if (type === 'categories') {
        setFieldOld(categories.join(','))
        scriptEditUseCase.replaceScript(fieldOld,value)
        setCategoriesWrapper(value.split(',') || [], needUpdate);
      } else if (type === 'protagonist') {
        setFieldOld(protagonist)
        scriptEditUseCase.replaceScript(fieldOld,value)
        setProtagonistWrapper(value, needUpdate);
      } else if (type === 'incitingIncident') {
        setFieldOld(incitingIncident)
        scriptEditUseCase.replaceScript(fieldOld,value)
        setIncitingIncidentWrapper(value, needUpdate);
      } else if (type === 'problem') {
        setFieldOld(problem)
        scriptEditUseCase.replaceScript(fieldOld,value)
        setProblemWrapper(value, needUpdate);
      } else if (type === 'conflict') {
        setFieldOld(conflict)
        scriptEditUseCase.replaceScript(fieldOld,value)
        setConflictWrapper(value, needUpdate);
      } else if (type === 'stakes') {
        setFieldOld(stakes)
        scriptEditUseCase.replaceScript(fieldOld,value)
        setStakesWrapper(value, needUpdate);
      } else if (type === 'characterArc') {
        setFieldOld(characterArc)
        scriptEditUseCase.replaceScript(fieldOld,value)
        setCharacterArcWrapper(value, needUpdate);
      }
      callback(fieldOld)
    },
    [categories, characterArc, conflict, fieldOld, incitingIncident, problem, protagonist, scriptEditUseCase, setCategoriesWrapper, setCharacterArcWrapper, setConflictWrapper, setIncitingIncidentWrapper, setProblemWrapper, setProtagonistWrapper, setStakesWrapper, setSynopsisWrapper, stakes, synopsis]
  );
  /**
   * 增强剧本
   */
  const enhanceScript = useCallback(async (): Promise<void> => {
    try {
      setLoading(true);

      if (!scriptEditUseCase) {
        throw new Error("剧本编辑用例未初始化");
      }

      // 调用增强剧本方法
      await scriptEditUseCase.enhanceScript(
        aiOptimizing,
        (content: any) => {
          // 获取解析后的故事详情
          const storyDetails = scriptEditUseCase.getStoryDetails();
          setSynopsis(storyDetails.synopsis || "");
          setCategories(storyDetails.categories || []);
          setProtagonist(storyDetails.protagonist || "");
          setIncitingIncident(storyDetails.incitingIncident || "");
          setProblem(storyDetails.problem || "");
          setConflict(storyDetails.conflict || "");
          setStakes(storyDetails.stakes || "");
          setCharacterArc(storyDetails.characterArc || "");
        }
      );

      // 如果有项目ID，则保存增强后的剧本
      // if (projectId) {
      //   await scriptEditUseCase.saveScript(projectId);
      // }
    } catch (error) {
      console.error("增强剧本失败:", error);
      throw error;
    } finally {
      setLoading(false);
    }
  }, [scriptEditUseCase, aiOptimizing, projectId]);

  // 在ScriptService中添加一个方法来获取渲染数据
  const scriptBlocksMemo = useMemo((): ScriptBlock[] => {
    const arr = [
      parseScriptBlock("synopsis", "Logline", synopsis || ""),
      parseScriptBlock('categories', 'GENRE', categories.join(', ') || '', 'tag'),
      parseScriptBlock("protagonist", "Core Identity", protagonist || ""),
      parseScriptBlock(
        "incitingIncident",
        "The Inciting Incident",
        incitingIncident || ""
      ),
      parseScriptBlock("problem", "The Problem & New Goal", problem || ""),
      parseScriptBlock("conflict", "Conflict & Obstacles", conflict || ""),
      parseScriptBlock("stakes", "The Stakes", stakes || ""),
      parseScriptBlock(
        "characterArc",
        "Character Arc Accomplished",
        characterArc || ""
      ),
    ];
    // 筛选出有内容的block
    const filteredArr = arr.filter(item => (item.content.length > 0 && item.content[0].text !== ''));
    console.log('scriptBlocksMemo', JSON.parse(JSON.stringify(filteredArr)));
    return filteredArr;
  }, [
    synopsis,
    categories,
    protagonist,
    incitingIncident,
    problem,
    conflict,
    stakes,
    characterArc,

  ]);

  return {
    // 响应式状态
    loading,
    synopsis,
    categories,
    protagonist,
    incitingIncident,
    problem,
    conflict,
    stakes,
    characterArc,
    projectId,
    aiOptimizing,
    scriptBlocksMemo,
    // 操作方法
    generateScriptFromIdea,
    initializeFromProject,
    updateScript,
    applyScript,
    abortVideoTask: abortVideoTaskHandler,
    enhanceScript,
    setAiOptimizing,
    setProjectId,
    createMovieProjectV1,
    // 封装的set函数
    setSynopsis: setSynopsisWrapper,
    setCategories: setCategoriesWrapper,
    setProtagonist: setProtagonistWrapper,
    setIncitingIncident: setIncitingIncidentWrapper,
    setProblem: setProblemWrapper,
    setConflict: setConflictWrapper,
    setStakes: setStakesWrapper,
    setCharacterArc: setCharacterArcWrapper,
    // 封装统一的set函数
    setAnyAttribute: setAnyAttributeWrapper,
  };
};
