import type { DictionaryItem } from '@/service/types'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { computed, readonly } from 'vue'
import { dictionaryItemsUsingGet } from '@/service'
import { useUserId } from './useUserId'

export type DictOptions = Array<{ label: string, value: string }>

export enum DictCode {
  TASK_TYPE = 'task_type',
  TASK_STATUS = 'task_status',
  ALLOCATION_METHOD = 'allocation_method',
  MARKING_STATUS = 'marking_status',
  SCAN_ANOMALY_STATUS = 'scan_anomaly_status',
  PROBLEM_TYPE = 'problem_type',
  EVALUATE_METHOD = 'evaluate_method',
}

/**
 * 字典数据访问组合函数
 * 使用vue-query提供缓存和状态管理
 */
export function useDict() {
  const queryClient = useQueryClient()

  /**
   * 获取字典选项查询
   * @param dictCode 字典编码
   * @returns vue-query查询结果
   */
  const useDictOptionsQuery = (dictCode: string) => {
    return useQuery({
      queryKey: ['dict', dictCode, useUserId()],
      queryFn: async (): Promise<DictOptions> => {
        try {
          const response = await dictionaryItemsUsingGet({
            params: { code: dictCode },
          })

          if (response && Array.isArray(response)) {
            return response.map((item: DictionaryItem) => ({
              label: item.key || '',
              value: item.value || '',
            }))
          }

          return []
        }
        catch (error) {
          console.error(`获取字典选项失败 [${dictCode}]:`, error)
          throw error
        }
      },
      staleTime: 1000 * 60 * 30, // 30分钟内数据保持新鲜
      gcTime: 1000 * 60 * 60 * 24, // 24小时后垃圾回收
      retry: 3,
      retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),
    })
  }

  /**
   * 获取字典选项列表（兼容旧版本API）
   * @param dictCode 字典编码
   * @returns Promise<Array<{ label: string; value: string }>>
   */
  const getDictOptions = async (dictCode: string): Promise<DictOptions> => {
    // 尝试从缓存获取
    const cachedData = queryClient.getQueryData<DictOptions>(['dict', dictCode])
    if (cachedData) {
      return cachedData
    }

    // 通过query获取数据
    return queryClient.fetchQuery({
      queryKey: ['dict', dictCode, useUserId()],
      queryFn: async (): Promise<DictOptions> => {
        try {
          const response = await dictionaryItemsUsingGet({
            params: { code: dictCode },
          })

          if (response && Array.isArray(response)) {
            return response.map((item: DictionaryItem) => ({
              label: item.key || '',
              value: item.value || '',
            }))
          }

          return []
        }
        catch (error) {
          console.error(`获取字典选项失败 [${dictCode}]:`, error)
          throw error
        }
      },
      staleTime: 1000 * 60 * 30,
      gcTime: 1000 * 60 * 60 * 24,
    })
  }

  /**
   * 获取字典选项的计算属性（使用vue-query）
   * @param dictCode 字典编码
   * @returns 响应式的字典选项
   */
  const getDictOptionsComputed = (dictCode: string) => {
    const query = useDictOptionsQuery(dictCode)

    return {
      options: computed(() => query.data.value || []),
      loading: computed(() => query.isLoading.value),
      error: computed(() => query.error.value),
      reload: query.refetch,
      isError: computed(() => query.isError.value),
      isSuccess: computed(() => query.isSuccess.value),
    }
  }

  /**
   * 获取字典选项和标签查找函数
   * @param dictCode 字典编码
   * @returns [响应式选项, 标签查找函数]
   */
  const getDictOptionsAndGetLabel = (dictCode: string) => {
    const query = useDictOptionsQuery(dictCode)

    const options = computed(() => query.data.value || [])
    const loading = computed(() => query.isLoading.value)

    const getLabelFn = (value: any) => {
      let isLabelEqual = false
      const valueString = String(value)
      const result = options.value.find((item) => {
        if (item.value === valueString) {
          isLabelEqual = false
          return true
        }
        else if (item.label === valueString) {
          isLabelEqual = true
          return true
        }
        return false
      })
      return isLabelEqual ? result?.value || '' : result?.label
    }

    return [{
      options: readonly(options),
      loading: readonly(loading),
      reload: query.refetch,
      error: computed(() => query.error.value),
      isError: computed(() => query.isError.value),
    }, getLabelFn] as const
  }

  /**
   * 根据字典编码和值获取标签
   * @param dictCode 字典编码
   * @param dictValue 字典值
   * @returns Promise<string>
   */
  const getDictLabel = async (dictCode: string, dictValue: string): Promise<string> => {
    const options = await getDictOptions(dictCode)
    return options.find(item => item.value === dictValue)?.label || ''
  }

  /**
   * 根据字典编码和标签获取值
   * @param dictCode 字典编码
   * @param dictLabel 字典标签
   * @returns Promise<string>
   */
  const getDictValue = async (dictCode: string, dictLabel: string): Promise<string> => {
    const options = await getDictOptions(dictCode)
    return options.find(item => item.label === dictLabel)?.value || ''
  }

  /**
   * 创建字典格式化函数（基于vue-query）
   * @param dictCode 字典编码
   * @returns 响应式格式化函数
   */
  const createDictFormatter = (dictCode: string) => {
    const query = useDictOptionsQuery(dictCode)

    return {
      format: (dictValue: string) => {
        const options = query.data.value || []
        return options.find(item => item.value === dictValue)?.label || ''
      },
      formatAsync: async (dictValue: string) => {
        return await getDictLabel(dictCode, dictValue)
      },
      loading: computed(() => query.isLoading.value),
      options: computed(() => query.data.value || []),
    }
  }

  /**
   * 创建响应式字典选项（基于vue-query）
   * @param dictCode 字典编码
   * @returns 响应式的字典选项列表
   */
  const createDictOptions = (dictCode: string) => {
    const query = useDictOptionsQuery(dictCode)

    return {
      options: computed(() => query.data.value || []),
      loading: computed(() => query.isLoading.value),
      error: computed(() => query.error.value),
      reload: query.refetch,
      isError: computed(() => query.isError.value),
      isSuccess: computed(() => query.isSuccess.value),
    }
  }

  /**
   * 批量获取字典选项（使用vue-query）
   * @param dictCodes 字典编码数组
   * @returns Promise<Record<string, DictOptions>>
   */
  const getBatchDictOptions = async (dictCodes: string[]) => {
    const result: Record<string, DictOptions> = {}

    await Promise.all(
      dictCodes.map(async (code) => {
        try {
          result[code] = await getDictOptions(code)
        }
        catch (error) {
          console.error(`获取字典选项失败 [${code}]:`, error)
          result[code] = []
        }
      }),
    )

    return result
  }

  /**
   * 刷新字典缓存（基于vue-query）
   * @param dictCode 字典编码，如果不传则清空所有字典缓存
   */
  const refreshDict = (dictCode?: string) => {
    if (dictCode) {
      queryClient.invalidateQueries({ queryKey: ['dict', dictCode] })
    }
    else {
      queryClient.invalidateQueries({ queryKey: ['dict'] })
    }
  }

  /**
   * 移除字典缓存
   * @param dictCode 字典编码，如果不传则移除所有字典缓存
   */
  const removeDict = (dictCode?: string) => {
    if (dictCode) {
      queryClient.removeQueries({ queryKey: ['dict', dictCode] })
    }
    else {
      queryClient.removeQueries({ queryKey: ['dict'] })
    }
  }

  /**
   * 获取缓存统计信息
   */
  const getCacheStats = computed(() => {
    const cache = queryClient.getQueryCache()
    const dictQueries = cache.findAll({ queryKey: ['dict'] })

    return {
      size: dictQueries.length,
      keys: dictQueries.map(query => query.queryKey[1] as string).filter(Boolean),
      queries: dictQueries.map(query => ({
        key: query.queryKey,
        state: query.state,
        dataUpdatedAt: query.state.dataUpdatedAt,
      })),
    }
  })

  return {
    // 基础API
    useDictOptionsQuery,
    getDictOptions,
    getDictOptionsComputed,
    getDictLabel,
    getDictValue,
    getDictOptionsAndGetLabel,

    // 高级功能
    createDictFormatter,
    createDictOptions,
    getBatchDictOptions,

    // 缓存管理
    refreshDict,
    removeDict,
    getCacheStats,
  }
}
