import { ImageStoryEntity } from "../domain/Entities";
import { useUploadFile } from "../domain/service";
import { ImageStoryUseCase } from "../usecase/imageStoryUseCase";
import {
  useState,
  useCallback,
  useMemo,
  Dispatch,
  SetStateAction,
} from "react";
import {
  CharacterAnalysis,
  CreateMovieProjectV2Request,
  CreateMovieProjectResponse,
} from "@/api/DTO/movie_start_dto";
import { MovieProjectService, MovieProjectMode } from "./MovieProjectService";

interface UseImageStoryService {
  /** 当前图片故事数据 */
  imageStory: Partial<ImageStoryEntity>;
  /** 当前活跃的图片地址 */
  activeImageUrl: string;
  /** 故事内容（用户输入或AI分析结果） */
  storyContent: string;
  /** 角色头像及名称数据 */
  charactersAnalysis: CharacterAnalysis[];
  /** 分类数据 */
  potentialGenres: string[];
  /** 当前选中的分类 */
  selectedCategory: string;
  /** 是否正在加载中（上传或分析） */
  isLoading: boolean;
  /** 是否已经分析过图片 */
  hasAnalyzed: boolean;
  /** 计算后的角色头像数据 */
  avatarComputed: Array<{ name: string; url: string }>;
  /** 原始用户描述 */
  originalUserDescription: string;
  /** 分析任务进度 */
  taskProgress: number;
  /** 上传图片并分析 */
  uploadAndAnalyzeImage: () => Promise<void>;
  /** 触发文件选择 */
  triggerFileSelection: () => Promise<void>;
  /** 更新故事类型 */
  updateStoryType: (storyType: string) => void;
  /** 更新故事内容 */
  updateStoryContent: (content: string) => void;
  /** 更新角色名称并同步到相关数据 */
  updateCharacterName: (oldName: string, newName: string) => void;
  /** 同步角色名称到故事内容 */
  syncRoleNameToContent: (oldName: string, newName: string) => void;
  /** 重置图片故事数据 */
  resetImageStory: (showAnalysisState?: boolean) => void;
  /** 生成动作电影 */
  actionMovie: (
    user_id: string,
    mode?: "auto" | "manual",
    resolution?: "720p" | "1080p" | "4k",
    language?: string
  ) => Promise<{ project_id: string } | undefined>;
  /** 设置角色分析 */
  setCharactersAnalysis: Dispatch<SetStateAction<CharacterAnalysis[]>>;
  /** 设置原始用户描述 */
  setOriginalUserDescription: Dispatch<SetStateAction<string>>;
  /** 上传人物头像并分析特征，替换旧的角色数据 */
  uploadCharacterAvatarAndAnalyzeFeatures: (
    characterName: string
  ) => Promise<void>;
}

export const useImageStoryServiceHook = (): UseImageStoryService => {
  // 基础状态
  const [imageStory, setImageStory] = useState<Partial<ImageStoryEntity>>({
    imageUrl: "",
    storyType: "",
  });

  // 图片相关状态
  const [activeImageUrl, setActiveImageUrl] = useState<string>("");

  // 故事内容状态（统一管理用户输入和AI分析结果）
  const [storyContent, setStoryContent] = useState<string>("");
  // 原始用户描述
  const [originalUserDescription, setOriginalUserDescription] =
    useState<string>("");

  // 分析结果状态
  /** 角色头像及名称 */
  const [charactersAnalysis, setCharactersAnalysis] = useState<
    CharacterAnalysis[]
  >([]);
  /** 分类数组 */
  const [potentialGenres, setPotentialGenres] = useState<string[]>([]);

  // 分类状态
  const [selectedCategory, setSelectedCategory] = useState<string>("");

  // 流程状态
  const [isLoading, setIsLoading] = useState(false);
  const [hasAnalyzed, setHasAnalyzed] = useState(false);
  /** 分析任务进度 */
  const [taskProgress, setTaskProgress] = useState(0);
  // 使用上传文件Hook
  const { uploadFile } = useUploadFile();
  const [taskId, setTaskId] = useState<string>("");

  /** 图片故事用例实例 */
  const imageStoryUseCase = useMemo(() => new ImageStoryUseCase(), []);

  /**
   * 根据角色区域信息生成头像URL
   * @param character - 角色信息
   * @param imageUrl - 源图片URL
   */
  const generateAvatarFromRegion = useCallback(
    (character: CharacterAnalysis, imageUrl: string) => {
      if (
        !character.region ||
        !character.region.width ||
        !character.region.height
      ) {
        return;
      }
      // 创建图片对象
      const img = new Image();
      img.crossOrigin = "anonymous"; // 处理跨域问题

      img.onload = () => {
        try {
          // 根据百分比计算实际的像素坐标
          const cropX = Math.round(character.region!.x * img.width);
          const cropY = Math.round(character.region!.y * img.height);
          const cropWidth = Math.round(character.region!.width * img.width);
          const cropHeight = Math.round(character.region!.height * img.height);
          console.log(cropX, cropY, cropWidth, cropHeight);

          // 验证裁剪区域是否有效
          if (cropWidth <= 0 || cropHeight <= 0) {
            console.error("裁剪区域无效:", { cropWidth, cropHeight });
            return;
          }

          if (
            cropX + cropWidth > img.width ||
            cropY + cropHeight > img.height
          ) {
            console.error("裁剪区域超出图片边界");
            return;
          }

          // 创建canvas元素用于图片裁剪
          const canvas = document.createElement("canvas");
          const ctx = canvas.getContext("2d");

          if (!ctx) {
            console.error("无法创建canvas上下文");
            return;
          }

          // 设置canvas尺寸为裁剪后的尺寸
          canvas.width = cropWidth;
          canvas.height = cropHeight;

          // 清除canvas内容
          ctx.clearRect(0, 0, cropWidth, cropHeight);

          // 在canvas上绘制裁剪后的图片部分
          ctx.drawImage(
            img,
            cropX,
            cropY,
            cropWidth,
            cropHeight, // 源图片裁剪区域
            0,
            0,
            cropWidth,
            cropHeight // 目标canvas区域
          );

          // 将canvas转换为blob并创建临时URL
          canvas.toBlob(
            (blob) => {
              if (blob) {
                const url = URL.createObjectURL(blob);
                console.log("成功生成头像URL:", url, "大小:", blob.size);

                // 更新角色头像URL
                setCharactersAnalysis((prev) =>
                  prev.map((char) =>
                    char.role_name === character.role_name
                      ? { ...char, avatarUrl: url }
                      : char
                  )
                );
              } else {
                console.error("Canvas转Blob失败");
              }
            },
            "image/jpeg",
            0.9
          );

          // 清理canvas
          canvas.remove();
        } catch (error) {
          console.error("生成角色头像失败:", error);
        }
      };

      img.onerror = () => {
        console.error("加载图片失败:", imageUrl);
      };

      // 开始加载图片
      img.src = imageUrl;
    },
    [setCharactersAnalysis]
  );

  /**
   * 根据角色框选数据计算头像URL
   * 从图片中裁剪出对应的角色头像部分
   */
  const avatarComputed = useMemo(() => {
    if (!activeImageUrl || charactersAnalysis.length === 0) {
      return [];
    }

    return charactersAnalysis
      .map((character) => {
        console.log("character", character);
        // 如果已经有头像URL，直接返回
        if (character.crop_url) {
          return {
            name: character.role_name,
            url: character.crop_url,
          };
        }

        // // 异步生成头像URL
        // generateAvatarFromRegion(character, activeImageUrl);

        // return {
        //   name: character.role_name,
        //   url: "", // 初始为空，异步生成完成后会更新
        // };
      })
      .filter(Boolean) as { name: string; url: string }[];
  }, [charactersAnalysis, activeImageUrl, generateAvatarFromRegion]);
  /**
   * 上传图片并分析
   * @param {string} imageUrl - 已上传的图片URL
   */
  const uploadAndAnalyzeImage = useCallback(async (): Promise<void> => {
    try {
      setIsLoading(true);
      setTaskProgress(1);

      const setData = () => {
        setOriginalUserDescription(storyContent);
        // 获取更新后的数据
        const updatedStory = imageStoryUseCase.storyLogline;
        const updatedCharacters = imageStoryUseCase.charactersAnalysis;
        const updatedGenres = imageStoryUseCase.potentialGenres;
        const updatedImageStory = imageStoryUseCase.imageStory;
        setSelectedCategory(imageStoryUseCase.potentialGenres[0]);
        // 更新所有响应式状态
        setCharactersAnalysis(updatedCharacters);
        setPotentialGenres(updatedGenres);
        setImageStory(updatedImageStory);

        // 将AI分析的故事内容直接更新到统一的故事内容字段
        updateStoryContent(updatedStory || "");

        // 标记已分析
        setHasAnalyzed(true);
      };

      // 调用用例处理图片上传和分析
      const taskId = await imageStoryUseCase.handleImageUpload(activeImageUrl);
      setTaskId(taskId);
      for await (const result of await imageStoryUseCase.pollTaskStatus(
        taskId
      )) {
        setTaskProgress(result.progress);
        switch (result.status) {
          case "submitted":
            break;
          case "processing":
            setData();
            break;
          case "completed":
            setData();
            setHasAnalyzed(true);
            setTaskProgress(0);
            return
          case "failed":
            setHasAnalyzed(false);
            setTaskProgress(0);
            return
          default:
            break;
        }
      }
    } catch (error) {
      console.error("图片上传分析失败:", error);
      setHasAnalyzed(false);

      throw error;
    } finally {
      setIsLoading(false);
    }
  }, [imageStoryUseCase, activeImageUrl, storyContent]);

  /**
   * 更新故事类型
   * @param {string} storyType - 新的故事类型
   */
  const updateStoryType = useCallback(
    (storyType: string): void => {
      imageStoryUseCase.updateStoryType(storyType);
      setImageStory((prev) => ({ ...prev, storyType }));
      setSelectedCategory(storyType);
    },
    [imageStoryUseCase]
  );

  /**
   * 更新故事内容
   * @param {string} content - 新的故事内容
   */
  const updateStoryContent = useCallback(
    (content: string): void => {
      setStoryContent(content);
      imageStoryUseCase.updateStoryContent(content);
    },
    [imageStoryUseCase]
  );

  /**
   * 同步角色名称到故事内容
   * @param {string} oldName - 旧的角色名称
   * @param {string} newName - 新的角色名称
   */
  const syncRoleNameToContent = useCallback(
    (oldName: string, newName: string) => {
      // 更新故事内容中的角色标签
      setStoryContent((prev) => {
        // 匹配新的角色标签格式 <role id="C1">Dezhong Huang</role>
        const regex = new RegExp(`<role[^>]*>${oldName}<\/role>`, "g");
        const content = prev.replace(regex, `<role >${newName}</role>`);
        imageStoryUseCase.updateStoryContent(content);
        return content;
      });
    },
    [imageStoryUseCase]
  );

  /**
   * 更新角色名称并同步到相关数据
   * @param {string} oldName - 旧的角色名称
   * @param {string} newName - 新的角色名称
   */
  const updateCharacterName = useCallback(
    (oldName: string, newName: string): void => {
      // 更新角色分析数据中的名称
      setCharactersAnalysis((prev) =>
        prev.map((char) =>
          char.role_name === oldName ? { ...char, role_name: newName } : char
        )
      );

      // 同步更新故事内容中的角色名称
      syncRoleNameToContent(oldName, newName);
    },
    [syncRoleNameToContent]
  );

  /**
   * 重置图片故事数据
   */
  const resetImageStory = useCallback((): void => {
    imageStoryUseCase.resetImageStory();

    // 清理生成的头像URL，避免内存泄漏
    setCharactersAnalysis([]);

    // 重置所有状态
    setImageStory({
      imageUrl: "",
      storyType: "",
    });
    setActiveImageUrl("");
    updateStoryContent("");
    setPotentialGenres([]);
    setSelectedCategory("");
    setHasAnalyzed(false);
    setIsLoading(false);
    setOriginalUserDescription("");
  }, [imageStoryUseCase]);

  /**
   * 触发文件选择并自动分析
   */
  const triggerFileSelection = useCallback(async (): Promise<void> => {
    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]) {
            setIsLoading(true);

            // 使用传入的文件上传函数
            const uploadedImageUrl = await uploadFile(
              target.files[0],
              (progress) => {
                console.log("上传进度:", progress);
              }
            );

            // 设置图片URL
            setActiveImageUrl(uploadedImageUrl);
            setImageStory((prev) => ({
              ...prev,
              imageUrl: uploadedImageUrl,
            }));
          }
          resolve();
        } catch (error) {
          reject(error);
        } finally {
          setIsLoading(false);
          // 清理DOM
          document.body.removeChild(fileInput);
        }
      };

      fileInput.oncancel = () => {
        document.body.removeChild(fileInput);
        reject();
      };

      document.body.appendChild(fileInput);
      fileInput.click();
    });
  }, [uploadFile]);

  const actionMovie = useCallback(
    async (
      user_id: string,
      mode: "auto" | "manual" = "auto",
      resolution: "720p" | "1080p" | "4k" = "720p",
      language: string = "English"
    ) => {
      try {
        if (hasAnalyzed) {
          // 从charactersAnalysis中提取whisk_caption字段组成数组
          const character_briefs = charactersAnalysis.map((char) => {
            return {
              name: char.role_name,
              image_url: char.crop_url,
              character_analysis: char.role_name+":"+JSON.parse(char.whisk_caption)
                ?.character_analysis?.brief,
            };
          });

          const params: CreateMovieProjectV2Request = {
            script: storyContent,
            user_id,
            mode,
            resolution,
            genre: selectedCategory,
            character_briefs,
            language,
            image_url: activeImageUrl,
            project_id:taskId
          };

          // 调用create_movie_project_v2接口
          const result = await MovieProjectService.createProject(
            MovieProjectMode.IMAGE,
            params
          );
          return { project_id: result.project_id };
        }
      } catch (error) {
        console.error("创建电影项目失败:", error);
        throw error;
      }
    },
    [
      hasAnalyzed,
      storyContent,
      charactersAnalysis,
      selectedCategory,
      activeImageUrl,
    ]
  );

  /**
   * 上传人物头像并分析特征，替换旧的角色数据
   * @param {string} characterName - 角色名称
   */
  const uploadCharacterAvatarAndAnalyzeFeatures = useCallback(
    async (characterName: string): Promise<void> => {
      try {
        setIsLoading(true);

        // 调用用例处理人物头像上传和特征分析
        const result =
          await imageStoryUseCase.uploadCharacterAvatarAndAnalyzeFeatures(
            uploadFile
          );

        // 用新的头像和特征描述替换旧的角色数据
        setCharactersAnalysis((prev) =>
          prev.map((char) =>
            char.role_name === characterName
              ? {
                  ...char,
                  crop_url: result.crop_url,
                  whisk_caption: result.whisk_caption,
                }
              : char
          )
        );

        console.log("人物头像和特征描述更新成功:", result);
      } catch (error) {
        console.error("人物头像上传和特征分析失败:", error);
        throw error;
      } finally {
        setIsLoading(false);
      }
    },
    [imageStoryUseCase, uploadFile]
  );

  return {
    imageStory,
    activeImageUrl,
    storyContent,
    charactersAnalysis,
    potentialGenres,
    selectedCategory,
    isLoading,
    hasAnalyzed,
    avatarComputed,
    originalUserDescription,
    taskProgress,
    setCharactersAnalysis,
    uploadAndAnalyzeImage,
    triggerFileSelection,
    updateStoryType,
    updateStoryContent,
    updateCharacterName,
    syncRoleNameToContent,
    resetImageStory,
    setOriginalUserDescription,
    actionMovie,
    uploadCharacterAvatarAndAnalyzeFeatures,
  };
};
