import { useState, useCallback, useMemo } from "react";
import { RoleEntity, AITextEntity } from "../domain/Entities";
import { RoleEditUseCase } from "../usecase/RoleEditUseCase";
import { getUploadToken, uploadToQiniu } from "@/api/common";
import {
  checkShotVideoStatus,
} from "@/api/video_flow";
import { SaveEditUseCase } from "../usecase/SaveEditUseCase";

/**
 * 角色服务Hook返回值接口
 */
interface UseRoleService {
  // 响应式数据
  /** 角色列表 */
  roleList: RoleEntity[];
  /** 当前选中的角色 */
  selectedRole: RoleEntity | null;
  /** 当前角色的AI文本 */
  currentRoleText: string | null;
  /** 角色图片URL */
  roleImageUrl: string;
  /** 用户角色库 */
  userRoleLibrary: RoleEntity[];
  // 操作方法
  /** 获取角色列表 */
  fetchRoleList: (projectId: string) => Promise<void>;
  /** 选择角色 */
  selectRole: (role: RoleEntity) => Promise<void>;
  /** 优化AI文本 */
  optimizeRoleText: (userSuggestion: string) => Promise<void>;
  /** 修改AI文本 */
  updateRoleText: (newContent: string) => Promise<void>;
  /** 重新生成角色 */
  regenerateRole: () => Promise<void>;
  /** 获取用户角色库 */
  fetchUserRoleLibrary: (generateText?: string) => Promise<void>;
  /** 替换角色 */
  replaceRoleWithLibrary: (replaceRoleId: string) => Promise<void>;
  /** 上传图片并更新角色信息 */
  uploadImageAndUpdateRole: (file: File) => Promise<void>;
  /** 保存重新生成的角色到角色库 */
  saveRoleToLibrary: () => Promise<void>;
  /** 保存数据 */
  saveData: () => Promise<void>;
  /** 切换标签页回调函数 */
  changeTabCallback: (callback: (isChange: Boolean) => void) => void;
}

/**
 * 角色服务Hook
 * 提供角色相关的所有响应式功能和业务逻辑
 */
export const useRoleServiceHook = (): UseRoleService => {
  // 响应式状态
  const [roleList, setRoleList] = useState<RoleEntity[]>([]);
  const [selectedRole, setSelectedRole] = useState<RoleEntity | null>(null);
  const [currentRoleText, setCurrentRoleText] = useState<string | null>(null);
  const [userRoleLibrary, setUserRoleLibrary] = useState<RoleEntity[]>([]);
  const [projectId, setProjectId] = useState<string>(""); // 添加项目ID状态

  // UseCase实例 - 在角色选择时初始化
  const [roleEditUseCase, setRoleEditUseCase] =
    useState<RoleEditUseCase | null>(null);

  // 计算属性
  /**
   * 角色图片URL
   * @description 获取当前选中角色的图片URL
   */
  const roleImageUrl = useMemo(() => {
    return selectedRole?.imageUrl || "";
  }, [selectedRole]);

  /**
   * 获取角色列表
   * @description 根据项目ID获取所有角色列表
   * @param projectId 项目ID
   * @throws {Error} 当API调用失败时抛出错误
   * @returns {Promise<void>} 获取完成后的Promise
   */
  const fetchRoleList = useCallback(async (projectId: string) => {
    try {
      // 保存项目ID到状态
      setProjectId(projectId);

      // 初始化角色编辑UseCase实例
      const newRoleEditUseCase = new RoleEditUseCase();
      const roleList = await newRoleEditUseCase.getRoleList(projectId);

      setRoleList(roleList);
      setRoleEditUseCase(newRoleEditUseCase);
    } catch (error) {
      console.error("获取角色列表失败:", error);
      throw error;
    }
  }, []);

  /**
   * 选择角色
   * @description 根据角色ID选择角色，并初始化相关的UseCase实例
   * @param roleId 角色ID
   */
  const selectRole = useCallback(
    async (role: RoleEntity) => {
      console.log("selectRole", role);
      setRoleList((prev) => prev.map((r) => (r.name === role.name ? role : r)));
      setSelectedRole(role);

      // 调用selectRole方法
      roleEditUseCase!.selectRole(role);
    },
    [roleEditUseCase]
  );

  /**
   * 优化AI文本
   * @description 对当前角色的AI文本进行优化
   * @throws {Error} 当没有可优化的文本内容或UseCase未初始化时抛出错误
   * @returns {Promise<void>} 优化完成后的Promise
   */
  const optimizeRoleText = useCallback(async () => {
    if (!roleEditUseCase) {
      throw new Error("角色编辑UseCase未初始化");
    }

    if (!currentRoleText) {
      throw new Error("没有可优化的文本内容");
    }

    if (!selectedRole) {
      throw new Error("没有选中的角色");
    }

    try {
      const { optimizedDescription, keywords } =
        await roleEditUseCase.optimizeRoleDescription(selectedRole);
      setCurrentRoleText(optimizedDescription);
      // 更新角色列表中的对应角色描述和标签
      setRoleList((prev) =>
        prev.map((role) =>
          role.id === selectedRole?.id
            ? {
                ...role,
                generateText: optimizedDescription,
                tags: keywords.map((keyword) => ({
                  id: `tag_${Date.now()}_${Math.random()
                    .toString(36)
                    .substr(2, 9)}`,
                  /** 名称 */
                  name: keyword,
                  /** 内容 */
                  content: keyword,
                })),
              }
            : role
        )
      );

      // 更新当前选中角色
      if (selectedRole) {
        selectRole({
          ...selectedRole,
          generateText: optimizedDescription,
          tags: keywords.map((keyword) => ({
            id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
            /** 名称 */
            name: keyword,
            /** 内容 */
            content: keyword,
          })),
        });
      }
    } catch (error) {
      console.error("优化角色文本失败:", error);
      throw error;
    }
  }, [roleEditUseCase, currentRoleText, selectedRole, selectRole]);

  /**
   * 修改AI文本
   * @description 手动修改当前角色的AI文本内容
   * @param newContent 新的文本内容
   * @throws {Error} 当没有可编辑的文本或UseCase未初始化时抛出错误
   * @returns {Promise<void>} 修改完成后的Promise
   */
  const updateRoleText = useCallback(
    async (newContent: string) => {
      if (!roleEditUseCase) {
        throw new Error("角色编辑UseCase未初始化");
      }

      setCurrentRoleText(newContent);

      // 更新角色列表中的对应角色描述
      setRoleList((prev) =>
        prev?.map((role) =>
          role.id === selectedRole?.id
            ? { ...role, generateText: newContent }
            : role
        )
      );

      // 更新当前选中角色
      if (selectedRole) {
        selectRole({ ...selectedRole, generateText: newContent });
      }
    },
    [roleEditUseCase, selectRole, selectedRole]
  );

  /**
   * 重新生成角色
   * @description 使用AI文本重新生成角色
   * @throws {Error} 当缺少重新生成角色所需的数据或UseCase未初始化时抛出错误
   * @returns {Promise<void>} 重新生成完成后的Promise
   */
  const regenerateRole = useCallback(async () => {
    if (!roleEditUseCase) {
      throw new Error("角色编辑UseCase未初始化");
    }

    if (!selectedRole || !currentRoleText) {
      throw new Error("缺少重新生成角色所需的数据");
    }

    if (!projectId) {
      throw new Error("缺少项目ID，无法重新生成角色");
    }

    try {
      const newRoleEntity = await roleEditUseCase.AIgenerateRole(
        projectId,
        selectedRole.name,
        currentRoleText
      );
      selectRole(newRoleEntity);

      // 更新角色列表
      setRoleList((prev) =>
        prev.map((role) =>
          role.id === newRoleEntity.id ? newRoleEntity : role
        )
      );
    } catch (error) {
      console.error("重新生成角色失败:", error);
      throw error;
    }
  }, [roleEditUseCase, selectedRole, currentRoleText, projectId, selectRole]);

  /**
   * 获取用户角色库
   * @description 获取当前用户的角色库列表
   * @throws {Error} 当API调用失败时抛出错误
   * @returns {Promise<void>} 获取完成后的Promise
   */
  const fetchUserRoleLibrary = useCallback(async (generateText?: string) => {
    try {
      let useCase = roleEditUseCase;

      // 如果没有初始化RoleEditUseCase，创建一个新的实例
      if (!useCase) {
        useCase = new RoleEditUseCase();
        setRoleEditUseCase(useCase);
      }

      // 从localStorage获取当前用户信息
      const User = JSON.parse(localStorage.getItem("currentUser") || "{}");

      if (!User.id) {
        throw new Error("无法获取用户ID，请重新登录");
      }

      // 获取当前选中角色的描述
      const userDescription =generateText|| selectedRole?.generateText || "";

      const roleLibraryList = await useCase!.getRoleLibraryList(
        User.id,
        userDescription
      );
      setUserRoleLibrary(roleLibraryList);
    } catch (error) {
      console.error("获取用户角色库失败:", error);
      throw error;
    }
  }, [roleEditUseCase, selectedRole]);

  /**
   * 替换角色
   * @description 使用角色库中的角色替换当前角色，并重新获取角色详细数据
   * @param replaceRoleId 替换的角色ID
   * @throws {Error} 当未选择角色、API调用失败或UseCase未初始化时抛出错误
   * @returns {Promise<void>} 替换完成后的Promise
   */
  const replaceRoleWithLibrary = useCallback(
    async (replaceRoleId: string) => {
      if (!selectedRole) {
        throw new Error("请先选择角色");
      }

      if (!roleEditUseCase) {
        throw new Error("角色编辑UseCase未初始化");
      }

      try {
        await roleEditUseCase.replaceRoleById(selectedRole.id, replaceRoleId);

        // 更新角色列表
        const libraryRole = userRoleLibrary.find(
          (role) => role.id === replaceRoleId
        );
        if (libraryRole) {
          const updatedRole = {
            ...selectedRole,
            name: libraryRole.name,
            generateText: libraryRole.generateText,
            imageUrl: libraryRole.imageUrl,
            fromDraft: false,
            isChangeRole: true
          };

          selectRole(updatedRole);
          setRoleList((prev) =>
            prev.map((role) =>
              role.id === selectedRole.id ? updatedRole : role
            )
          );
        }
      } catch (error) {
        console.error("替换角色失败:", error);
        throw error;
      }
    },
    [selectedRole, roleEditUseCase, userRoleLibrary, selectRole]
  );

  /**
   * 上传图片并更新角色信息
   * @description 上传图片文件到七牛云存储，然后调用AI接口分析图片生成描述和高亮标签，最后更新当前选中角色的图片、描述和标签
   * @param file 要上传的文件
   * @returns {Promise<void>} 上传和分析完成后的Promise
   */
  const uploadImageAndUpdateRole = useCallback(
    async (file: File) => {
      if (!selectedRole) {
        throw new Error("请先选择要更新的角色");
      }

      if (!roleEditUseCase) {
        throw new Error("角色编辑UseCase未初始化");
      }

      try {
        // 1. 上传图片到七牛云
        const { token } = await getUploadToken();
        const imageUrl = await uploadToQiniu(file, token);

        // 2. 调用用例中的图片分析方法
        const updatedRole = await roleEditUseCase.analyzeImageAndUpdateRole(imageUrl, selectedRole);

        // 3. 更新选中的角色
        selectRole(updatedRole);

        // 更新角色列表中的对应角色
        setRoleList((prev) =>
          prev.map((role) => (role.id === selectedRole.id ? updatedRole : role))
        );

        console.log("角色图片和描述更新成功:", updatedRole);
      } catch (error) {
        console.error("上传图片并分析失败:", error);
        throw error;
      }
    },
    [selectedRole, roleEditUseCase, selectRole]
  );

  /**
   * 保存重新生成的角色到角色库
   * @description 将当前选中的角色保存到角色库中
   * @throws {Error} 当没有选中角色、UseCase未初始化或缺少项目ID时抛出错误
   * @returns {Promise<void>} 保存完成后的Promise
   */
  const saveRoleToLibrary = useCallback(async () => {
    if (!selectedRole) {
      throw new Error("请先选择要保存的角色");
    }

    if (!roleEditUseCase) {
      throw new Error("角色编辑UseCase未初始化");
    }

    if (!projectId) {
      throw new Error("缺少项目ID，无法保存角色到角色库");
    }

    try {
      // 从localStorage获取当前用户信息
      const User = JSON.parse(localStorage.getItem("currentUser") || "{}");

      if (!User.id) {
        throw new Error("无法获取用户ID，请重新登录");
      }

      // 调用保存重新生成角色到角色库的方法
      const result = await roleEditUseCase.saveRegeneratedCharacterToLibrary(
        selectedRole,
        projectId,
        String(User.id)
      );
      selectRole({
        ...selectedRole,
        id: result.character_id,
        fromDraft: true,
      });

      SaveEditUseCase.setCharacterId([
        ...SaveEditUseCase.characterId,
        {
          character_id: result.character_id,
          name: selectedRole.name,
        },
      ]);
      console.log("角色保存到角色库成功:", result);
    } catch (error) {
      console.error("保存角色到角色库失败:", error);
      throw error;
    }
  }, [selectedRole, roleEditUseCase, projectId]);

  /**
   * 保存数据
   * @description 调用接口保存当前项目数据
   * @throws {Error} 当缺少项目ID或API调用失败时抛出错误
   * @returns {Promise<void>} 保存完成后的Promise
   */
  const saveData = useCallback(async () => {
    if (!projectId) {
      throw new Error("缺少项目ID，无法保存数据");
    }

    try {
      const result = await checkShotVideoStatus({
        project_id: projectId,
      });

      if (!result.successful) {
        throw new Error(`保存数据失败: ${result.message}`);
      }

      console.log("数据保存成功");
    } catch (error) {
      console.error("保存数据失败:", error);
      throw error;
    }
  }, [projectId]);

  /**
   * @description 切换标签页回调函数，传入当前角色是否更改
   * @param callback 回调函数，接收当前角色是否更改
   */
  const changeTabCallback = useCallback((callback: (isChange: Boolean) => void) => {

    // 执行回调函数，传入已更改的角色列表
    callback(selectedRole!.isChangeRole);
  }, [selectedRole]);

  return {
    // 响应式数据
    roleList,
    selectedRole,
    currentRoleText,
    roleImageUrl,
    userRoleLibrary,

    // 操作方法
    fetchRoleList,
    selectRole,
    optimizeRoleText,
    updateRoleText,
    regenerateRole,
    fetchUserRoleLibrary,
    replaceRoleWithLibrary,
    uploadImageAndUpdateRole,
    saveRoleToLibrary,
    saveData,
    changeTabCallback,
  };
};
