import { ImageStoryEntity } from "../domain/Entities";
import { AIGenerateImageStory, getMovieStoryTask } from "@/api/movie_start";
import { MovieStartDTO, CharacterAnalysis } from "@/api/DTO/movie_start_dto";
import { generateCharacterBrief } from "@/api/video_flow";

/**
 * 图片故事用例
 * 负责管理图片故事模式的业务逻辑，包括图片上传、AI分析和故事生成
 */
export class ImageStoryUseCase {
  /** 当前图片故事数据 */
  imageStory: ImageStoryEntity = {
    id: "",
    imageAnalysis: "",
    roleImage: [],
    imageUrl: "",
    imageStory: "",
    storyType: "",
  };

  /** 故事梗概 */
  storyLogline: string = "";

  /** 角色头像及名称数据 */
  charactersAnalysis: CharacterAnalysis[] = [];

  /** 分类数据 */
  potentialGenres: string[] = [];

  /** 是否正在分析图片 */
  isAnalyzing: boolean = false;

  /** 是否正在上传 */
  isUploading: boolean = false;

  constructor() {}

  /**
   * 设置图片故事数据
   * @param {Partial<ImageStoryEntity>} data - 要设置的图片故事数据
   */
  setImageStory(data: Partial<ImageStoryEntity>): void {
    this.imageStory = { ...this.imageStory, ...data };
  }

  /**
   * 重置图片故事数据
   */
  resetImageStory(): void {
    this.imageStory = {
      id: "",
      imageAnalysis: "",
      roleImage: [],
      imageUrl: "",
      imageStory: "",
      storyType: "",
    };
    this.storyLogline = "";
    this.charactersAnalysis = [];
    this.potentialGenres = [];
    this.isAnalyzing = false;
    this.isUploading = false;
  }

  /**
   * 处理图片上传
   * @param {string} imageUrl - 已上传的图片URL
   * @returns {Promise<void>}
   */
  async handleImageUpload(imageUrl: string) {
    try {
      this.isUploading = false; // 图片已上传，设置上传状态为false
      this.isAnalyzing = true;
      console.log("imageUrl", imageUrl);
      // 设置上传后的图片URL
      this.setImageStory({ imageUrl });

      // 调用AI分析接口
      return await this.analyzeImageWithAI();
    } catch (error) {
      console.error("图片分析失败:", error);
      // 分析失败时清空图片URL
      this.setImageStory({ imageUrl: "" });
      throw error;
    } finally {
      this.isAnalyzing = false;
    }
  }

  /**
   * 使用AI分析图片
   * @returns {Promise<string>}
   */
  async analyzeImageWithAI() {
    try {
      //
      // 调用AI分析接口
      const response = await AIGenerateImageStory({
        image_url: this.imageStory.imageUrl || "",
        user_text: this.imageStory.imageStory || "",
      });

      return response.data.task_id;
    } catch (error) {
      console.error("AI分析失败:", error);
      throw error;
    }
  }
  /**
   * 轮询查状态
   * @param taskId - 任务ID
   * @param interval - 轮询间隔时间
   */
  async pollTaskStatus(taskId: string, interval: number = 1000) {
    // 好老套方案，但是有效
    let self = this;
    return {
      async *[Symbol.asyncIterator]() {
        while (true) {

          const response = await getMovieStoryTask(taskId);
          console.log("taskId", taskId,response);
          if (response.successful && response.data) {
            if (response.data.result) {
              response.data.result.characters_analysis?.forEach((character) => {
                character.whisk_caption = JSON.stringify(
                  character.whisk_caption
                );
              });
              // 解析并存储新的数据结构
              self.parseAndStoreAnalysisData(response.data.result);

              // 组合成ImageStoryEntity
              self.composeImageStoryEntity(response.data.result);
            }

            yield {
              status: response.data.status,
              imageStory: self.imageStory,
              progress: response.data.progress,
            };
          } else {
            throw new Error("AI分析失败");
          }
          await new Promise((resolve) => setTimeout(resolve, interval));
        }
      },
    };
  }

  /**
   * 解析并存储分析数据到类属性中
   * @param {MovieStartDTO} data - AI分析返回的数据
   */
  parseAndStoreAnalysisData(data: MovieStartDTO): void {
    // 存储故事梗概
    this.storyLogline = data.story_logline || "";

    // 存储角色头像及名称数据
    this.charactersAnalysis = data.characters_analysis || [];

    // 存储分类数据
    this.potentialGenres = data.potential_genres || [];
  }

  /**
   * 组合成ImageStoryEntity
   * @param {MovieStartDTO} data - AI分析返回的数据
   */
  composeImageStoryEntity(data: MovieStartDTO): void {
    // 将角色数据转换为ImageStoryEntity需要的格式
    const roleImage =
      data.characters_analysis?.map((character) => ({
        name: character.role_name,
        avatar_url: "", // 这里需要根据实际情况设置头像URL
        region: {
          x: character.region?.x || 0,
          y: character.region?.y || 0,
          width: character.region?.width || 0,
          height: character.region?.height || 0,
        },
      })) || [];

    // 更新ImageStoryEntity
    this.setImageStory({
      ...this.imageStory,
      imageAnalysis: data.story_logline || "",
      storyType: data.potential_genres?.[0] || "", // 使用第一个分类作为故事类型
      roleImage,
    });
  }

  /**
   * 更新故事类型
   * @param {string} storyType - 新的故事类型
   */
  updateStoryType(storyType: string): void {
    this.setImageStory({ storyType });
  }

  /**
   * 更新故事内容
   * @param {string} storyContent - 新的故事内容
   */
  updateStoryContent(storyContent: string): void {
    this.setImageStory({ imageStory: storyContent });
  }
  /**
   * 处理角色数据，解析并存储到类属性中
   * @param {CharacterAnalysis[]} characters - 角色分析数据
   */
  processCharacterData(characters: CharacterAnalysis[]): void {
    this.charactersAnalysis = characters.map((character) => ({
      ...character,
      region: {
        x: character.region?.x || 0,
        y: character.region?.y || 0,
        width: character.region?.width || 0,
        height: character.region?.height || 0,
      },
    }));
  }

  /**
   * 获取指定角色的区域坐标
   * @param {string} characterName - 角色名称
   * @returns {CharacterAnalysis['region'] | null} 角色区域坐标，如果未找到则返回null
   */
  getCharacterRegion(
    characterName: string
  ): CharacterAnalysis["region"] | null {
    const character = this.charactersAnalysis.find(
      (char) => char.role_name === characterName
    );
    return character ? character.region : null;
  }

  /**
   * 更新角色头像URL
   * @param {string} characterName - 角色名称
   * @param {string} avatarUrl - 头像URL
   */
  updateCharacterAvatar(characterName: string, avatarUrl: string): void {
    const character = this.charactersAnalysis.find(
      (char) => char.role_name === characterName
    );
    if (character) {
      // 更新角色头像URL（这里需要根据实际的数据结构来调整）
      // 由于CharacterAnalysis接口中没有avatar_url字段，这里只是示例
      console.log(`更新角色 ${characterName} 的头像URL: ${avatarUrl}`);
    }
  }

  /**
   * 获取所有角色名称
   * @returns {string[]} 角色名称数组
   */
  getAllCharacterNames(): string[] {
    return this.charactersAnalysis.map((char) => char.role_name);
  }

  /**
   * 上传人物头像并分析特征，替换旧的角色数据
   * @param {Function} uploadFile - 文件上传函数
   * @returns {Promise<{crop_url: string, whisk_caption: string}>} 返回新的头像URL和特征描述
   */
  async uploadCharacterAvatarAndAnalyzeFeatures(
    uploadFile: (file: File) => Promise<string>
  ): Promise<{ crop_url: string; whisk_caption: string }> {
    return new Promise((resolve, reject) => {
      // 创建文件输入元素
      const fileInput = document.createElement("input");
      fileInput.type = "file";
      fileInput.accept = "image/*";
      fileInput.style.display = "none";

      fileInput.onchange = async (e) => {
        try {
          const target = e.target as HTMLInputElement;
          if (target.files && target.files[0]) {
            const file = target.files[0];

            // 直接在这里处理上传和分析逻辑
            try {
              // 1. 上传人物头像图片
              const imageUrl = await uploadFile(file);

              // 2. 调用AI分析接口获取人物特征描述
              const analysisResult = await generateCharacterBrief({
                image_url: imageUrl,
              });

              if (!analysisResult.successful || !analysisResult.data) {
                throw new Error("人物特征分析失败");
              }

              // 3. 返回新的头像URL和特征描述，用于替换旧数据
              const result = {
                crop_url: imageUrl,
                whisk_caption: JSON.stringify(
                  analysisResult.data.character_brief
                ),
              };

              // 清理临时元素
              document.body.removeChild(fileInput);
              resolve(result);
            } catch (error) {
              // 清理临时元素
              if (document.body.contains(fileInput)) {
                document.body.removeChild(fileInput);
              }
              reject(error);
            }
          } else {
            reject(new Error("未选择文件"));
          }
        } catch (error) {
          // 清理临时元素
          if (document.body.contains(fileInput)) {
            document.body.removeChild(fileInput);
          }
          reject(error);
        }
      };

      fileInput.oncancel = () => {
        document.body.removeChild(fileInput);
        reject(new Error("用户取消选择"));
      };

      // 添加到DOM并触发点击
      document.body.appendChild(fileInput);
      fileInput.click();
    });
  }
}
