import { ScriptSlice, ScriptValueObject } from "../domain/valueObject";
import {
  generateScriptStream,
  applyScriptToShot,
  createMovieProjectV1,
  saveScript,
  enhanceScriptStream,
  pauseMovieProjectPlan,
  resumeMovieProjectPlan,
} from "@/api/video_flow";

export type ScriptEditKey = 'synopsis' | 'categories' | 'protagonist' | 'incitingIncident' | 'problem' | 'conflict' | 'stakes' | 'characterArc';

export class ScriptEditUseCase {
  loading: boolean = false;
  private scriptValueObject: ScriptValueObject;
  private abortController: AbortController | null = null;

  constructor(script: string) {
    this.scriptValueObject = new ScriptValueObject(script);
  }

  /**
   * @description: AI生成剧本方法
   * @param prompt 剧本提示词
   * @param stream_callback 流式数据回调函数
   * @returns Promise<void>
   */
  async generateScript(
    prompt: string,
    stream_callback?: (data: any) => void
  ): Promise<void> {
    try {
      this.loading = true;

      // 创建新的中断控制器
      this.abortController = new AbortController();

      // 使用API接口生成剧本
      await generateScriptStream(
        {
          text: prompt,
        },
        (content) => {
          stream_callback?.(content);
          this.scriptValueObject.parseFromString(content);
        }
      );
    } catch (error) {
      if (this.abortController?.signal.aborted) {
        console.log("剧本生成被中断");
        return;
      }
      console.error("AI生成剧本出错:", error);
      throw error;
    } finally {
      this.loading = false;
      this.abortController = null;
    }
  }

  /**
   * @description: 中断剧本生成
   */
  abortGenerateScript(): void {
    if (this.abortController) {
      this.abortController.abort();
      this.loading = false;
    }
  }

  /**
   * @description: 增强剧本方法
   * @param scriptData 剧本数据
   * @param stream_callback 流式数据回调函数
   * @returns Promise<void>
   */
  async enhanceScript(
   aiOptimizing: string,
   stream_callback?: (data: any) => void
  ): Promise<void> {
    try {
      this.loading = true;

      // 创建新的中断控制器
      this.abortController = new AbortController();

      // 获取当前剧本文本
      const originalScript = this.scriptValueObject.toString();
      // 清空当前剧本
      this.scriptValueObject = new ScriptValueObject("");
      // 使用API接口增强剧本
      await enhanceScriptStream(
        {
          original_script: originalScript,
          aiOptimizing,
        },
        (content) => {
          stream_callback?.(content);
          this.scriptValueObject.parseFromString(content);
        }
      );
    } catch (error) {
      if (this.abortController?.signal.aborted) {
        console.log("剧本增强被中断");
        return;
      }
      console.error("AI增强剧本出错:", error);
      throw error;
    } finally {
      this.loading = false;
      this.abortController = null;
    }
  }

  /**
   * @description: 创建项目
   * @param prompt 用户提示词
   * @param userId 用户ID
   * @param mode automatic | manual
   * @param resolution 分辨率：720p | 1080p | 4k
   * @returns Promise<string> 返回项目ID
   */
  async createProject(
    prompt: string,
    userId: string ,
    mode: "automatic" | "manual" = "automatic",
    resolution: "720p" | "1080p" | "4k" = "720p",
    language: string,
    video_duration: string
  ) {
    try {
      // 调用创建项目API
      const response = await createMovieProjectV1({
        script: prompt,
        user_id: userId,
        mode,
        resolution,
        language,
        video_duration,
      });

      if (!response.successful) {
        throw new Error(response.message || "创建项目失败");
      }
      return response.data;
    } catch (error) {
      console.error("创建项目失败:", error);
      throw error;
    }
  }

  /**
   * @description: 保存剧本
   * @param projectId 项目ID
   * @param scriptData 剧本数据
   * @returns Promise<void>
   */
  async saveScript(
    projectId: string,
  ): Promise<void> {
    try {
      this.loading = true;

      // 获取当前剧本文本
      const scriptText = this.scriptValueObject.toString();
      const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
      // 调用保存剧本API
      const response = await saveScript({
        project_id: projectId,
        generated_script: scriptText,
        user_id: String(User?.id) || "",
      });

      if (!response.successful) {
        throw new Error(response.message || "保存剧本失败");
      }
      return response.data;
    } catch (error) {
      console.error("保存剧本失败:", error);
      throw error;
    } finally {
      this.loading = false;
    }
  }
  /**
   * @description: 应用剧本方法
   * @returns Promise<void>
   */
  async applyScript(projectId: string): Promise<void> {
    try {
      this.loading = true;

      // 调用应用剧本接口
      const response = await applyScriptToShot({
        project_id: projectId
      });

      if (!response.successful) {
        throw new Error(response.message || "应用剧本失败");
      }

      console.log("剧本应用成功");
    } catch (error) {
      console.error("应用剧本失败:", error);
      throw error;
    } finally {
      this.loading = false;
    }
  }

  /**
   * @description: 获取当前剧本故事详情
   * @returns StoryDetails
   */
  getStoryDetails() {
    return this.scriptValueObject.storyDetails.toObject();
  }
  /**
   * @description: 更新剧本
   * @param scriptText 新的剧本文本
   */
  updateScript(scriptText: string): void {
    this.scriptValueObject = new ScriptValueObject(scriptText);
  }

  /**
   * @description: 更新故事详情字段
   * @param field 字段名
   * @param value 字段值
   */
  updateStoryField(field: ScriptEditKey, value: string | string[]): void {
    const storyDetails = this.scriptValueObject.storyDetails;
    if(field === 'categories'){
      storyDetails.categories = value as string[];
    }else{
      storyDetails[field] = value as string;
    }
  }

  /**
   * @description: 获取加载状态
   * @returns boolean
   */
  isLoading(): boolean {
    return this.loading;
  }

  /**
   * @description: 将当前剧本片段转换为字符串
   * @returns string
   */
  toString(): string {
    return this.scriptValueObject.toString();
  }

  /**
   * @description: 当前剧本进行字符串替换
   * @returns string
   */
  replaceScript(old: string, newScript: string): void {
         // 获取当前剧本文本
         const scriptText = this.scriptValueObject.toString();
         // 替换剧本文本
         const newScriptText = scriptText.replace(old, newScript);
         // 更新剧本
         this.scriptValueObject = new ScriptValueObject(newScriptText);
  }

  /**
   * @description: 暂停电影项目计划
   * @param projectId 项目ID
   * @returns Promise<void>
   */
  async pauseProject(projectId: string): Promise<void> {
    try {
      this.loading = true;

      // 调用暂停项目API
      const response = await pauseMovieProjectPlan({
        project_id: projectId,
      });

      if (!response.successful) {
        throw new Error(response.message || "暂停项目失败");
      }

      console.log("项目暂停成功:", response.data.message);
    } catch (error) {
      console.error("暂停项目失败:", error);
      throw error;
    } finally {
      this.loading = false;
    }
  }

  /**
   * @description: 继续电影项目计划
   * @param projectId 项目ID
   * @returns Promise<void>
   */
  async resumeProject(projectId: string): Promise<void> {
    try {
      this.loading = true;

      // 调用继续项目API
      const response = await resumeMovieProjectPlan({
        project_id: projectId,
      });

      if (!response.successful) {
        throw new Error(response.message || "继续项目失败");
      }

      console.log("项目继续成功:", response.data.message);
    } catch (error) {
      console.error("继续项目失败:", error);
      throw error;
    } finally {
      this.loading = false;
    }
  }

}
