import { useState, useEffect, useCallback, useMemo } from 'react';
import { LLM_MODEL_TYPES, type LlmModelType } from "@/constants/knowledge";
import type { IThirdOAIModelCollection, IThirdOAIModel } from "@/interfaces/database/llm";
import userService from "@/services/user_service";

/**
 * 获取LLM模型列表的Hook
 * @param modelType 可选的模型类型过滤
 * @returns LLM模型数据和相关状态
 */
export function useLlmList(modelType?: LlmModelType) {
  const [data, setData] = useState<IThirdOAIModelCollection>({});
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchLlmList = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      
      const response = await userService.llm_list({ model_type: modelType });
      
      if (response.data?.code === 0) {
        setData(response.data?.data ?? {});
      } else {
        setError(response.data?.message || '获取LLM列表失败');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : '获取LLM列表失败');
    } finally {
      setLoading(false);
    }
  }, [modelType]);

  useEffect(() => {
    fetchLlmList();
  }, [fetchLlmList]);

  return {
    data,
    loading,
    error,
    refresh: fetchLlmList,
  };
}

/**
 * 获取可用的LLM选项列表
 * @param modelType 可选的模型类型过滤
 * @returns 格式化的选项列表
 */
export function useLlmOptions(modelType?: LlmModelType) {
  const { data: llmInfo, loading, error } = useLlmList(modelType);

  const options = useMemo(() => {
    return Object.entries(llmInfo).map(([key, value]) => {
      return {
        label: key,
        options: value
          .filter((x) => x.available) // 只显示可用的模型
          .map((x) => ({
            label: x.llm_name,
            value: `${x.llm_name}@${x.fid}`,
            disabled: !x.available,
            model: x,
          })),
      };
    }).filter((group) => group.options.length > 0); // 过滤掉空组
  }, [llmInfo]);

  return {
    options,
    loading,
    error,
  };
}

/**
 * 根据模型类型获取分组的LLM选项
 * @returns 按模型类型分组的选项
 */
export function useLlmOptionsByModelType() {
  const { data: llmInfo, loading, error } = useLlmList();

  const getOptionsByModelType = useCallback((modelType: LlmModelType) => {
    return Object.entries(llmInfo)
      .filter(([, value]) =>
        modelType
          ? value.some((x) => x.model_type.includes(modelType))
          : true,
      )
      .map(([key, value]) => {
        return {
          label: key,
          options: value
            .filter(
              (x) =>
                (modelType ? x.model_type.includes(modelType) : true) &&
                x.available,
            )
            .map((x) => ({
              label: x.llm_name,
              value: `${x.llm_name}@${x.fid}`,
              disabled: !x.available,
              model: x,
            })),
        };
      })
      .filter((x) => x.options.length > 0);
  }, [llmInfo]);

  return {
    getOptionsByModelType,
    loading,
    error,
  };
}

/**
 * 获取嵌入模型选项
 * @returns 嵌入模型选项列表
 */
export function useEmbeddingModelOptions() {
  return useLlmOptions(LLM_MODEL_TYPES.Embedding);
}

/**
 * 获取聊天模型选项
 * @returns 聊天模型选项列表
 */
export function useChatModelOptions() {
  return useLlmOptions(LLM_MODEL_TYPES.Chat);
}

/**
 * 获取重排序模型选项
 * @returns 重排序模型选项列表
 */
export function useRerankModelOptions() {
  return useLlmOptions(LLM_MODEL_TYPES.Rerank);
}

/**
 * 获取图像转文本模型选项
 * @returns 图像转文本模型选项列表
 */
export function useImage2TextModelOptions() {
  return useLlmOptions(LLM_MODEL_TYPES.Image2text);
}

/**
 * 获取语音转文本模型选项
 * @returns 语音转文本模型选项列表
 */
export function useSpeech2TextModelOptions() {
  return useLlmOptions(LLM_MODEL_TYPES.Speech2text);
}

/**
 * 获取文本转语音模型选项
 * @returns 文本转语音模型选项列表
 */
export function useTTSModelOptions() {
  return useLlmOptions(LLM_MODEL_TYPES.TTS);
}

/**
 * 根据模型ID获取模型详情
 * @param modelId 模型ID (格式: llm_name@fid)
 * @returns 模型详情
 */
export function useLlmModelDetail(modelId?: string) {
  const { data: llmInfo, loading, error } = useLlmList();

  const modelDetail = useMemo(() => {
    if (!modelId || !llmInfo) return null;

    const [llmName, fid] = modelId.split('@');
    
    for (const models of Object.values(llmInfo)) {
      const model = models.find(
        (m) => m.llm_name === llmName && m.fid === fid
      );
      if (model) return model;
    }
    
    return null;
  }, [modelId, llmInfo]);

  return {
    modelDetail,
    loading,
    error,
  };
}
