import { useState, useRef, useCallback, useEffect } from 'react'
import { useFetchVoiceTtsV2 } from './useCommon'
import { FetchVoiceTtsV2Request } from '@/services/common/types'
import { ChatPriceType, COIN_INSUFFICIENT_ERROR_CODE, useUpdateWalletBalance } from './useWallet'
import { useSetAtom } from 'jotai'
import { isCoinInsufficientAtom } from '@/atoms/im'
import { ApiError } from '@/types/api'

interface VoiceTTSCache {
  [key: string]: string // 缓存配置的hash作为key，blob url作为value
}

interface UseVoiceTTSOptions {
  cacheEnabled?: boolean // 是否启用缓存，默认为true
  needCheckSufficient?: boolean // 是否需要检查余额，默认为false
  onGenerateStart?: (config: FetchVoiceTtsV2Request) => void
  onGenerateEnd?: (config: FetchVoiceTtsV2Request, blobUrl: string) => void
  onError?: (error: string) => void
  aiId?: number
}

interface UseVoiceTTSReturn {
  isGenerating: boolean
  error: string | null
  generateAudioUrl: (config: FetchVoiceTtsV2Request) => Promise<string>
  clearCache: () => void
  getCachedBlobUrl: (config: FetchVoiceTtsV2Request) => string | null
}

/**
 * 语音合成缓存的自定义Hook
 *
 * 功能特性：
 * 1. 智能缓存：相同配置的语音只生成一次，存储 Blob URL 在内存中
 * 2. 错误处理：完善的错误处理和状态管理
 * 3. 配置哈希：通过配置内容生成唯一标识，用于缓存
 * 4. 内存管理：自动清理 Blob URLs 防止内存泄漏
 */
export function useVoiceTTS(options: UseVoiceTTSOptions = {}): UseVoiceTTSReturn {
  const {
    cacheEnabled = true,
    needCheckSufficient,
    onGenerateStart,
    onGenerateEnd,
    onError,
  } = options

  const [isGenerating, setIsGenerating] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const cacheRef = useRef<VoiceTTSCache>({})

  const { checkSufficientByType } = useUpdateWalletBalance()
  const setIsCoinInsufficient = useSetAtom(isCoinInsufficientAtom)

  // 生成配置的哈希值，用于缓存标识
  const generateConfigHash = useCallback((config: FetchVoiceTtsV2Request): string => {
    const configString = JSON.stringify({
      text: config.text,
      voiceType: config.voiceType,
      speechRate: config.speechRate,
      pitchRate: config.pitchRate,
      aiId: config.aiId,
    })
    // 简单的哈希函数
    let hash = 0
    for (let i = 0; i < configString.length; i++) {
      const char = configString.charCodeAt(i)
      hash = (hash << 5) - hash + char
      hash = hash & hash // 转换为32位整数
    }
    return Math.abs(hash).toString(36)
  }, [])

  // 创建mutation实例
  const fetchVoiceTtsV2Mutation = useFetchVoiceTtsV2()

  // 从缓存中获取Blob URL
  const getCachedBlobUrl = useCallback(
    (config: FetchVoiceTtsV2Request): string | null => {
      if (!cacheEnabled) return null
      const hash = generateConfigHash(config)
      return cacheRef.current[hash] || null
    },
    [generateConfigHash, cacheEnabled]
  )

  // 生成语音URL
  const generateAudioUrl = useCallback(
    async (config: FetchVoiceTtsV2Request): Promise<string> => {
      try {
        setError(null)

        // 检查缓存
        const cachedBlobUrl = getCachedBlobUrl(config)
        if (cachedBlobUrl) {
          return cachedBlobUrl
        }

        if (needCheckSufficient && !checkSufficientByType(ChatPriceType.VOICE)) {
          setIsCoinInsufficient(true)
          return ''
        }

        setIsGenerating(true)
        onGenerateStart?.(config)

        // 调用语音合成API，获取Blob
        const audioBlob = await fetchVoiceTtsV2Mutation.mutateAsync(config)

        if (!audioBlob || audioBlob.size === 0) {
          throw new Error('语音合成失败：未返回音频数据')
        }

        // 创建Blob URL
        const blobUrl = URL.createObjectURL(audioBlob)

        // 存储到缓存
        if (cacheEnabled) {
          const hash = generateConfigHash(config)
          cacheRef.current[hash] = blobUrl
        }

        onGenerateEnd?.(config, blobUrl)

        return blobUrl
      } catch (err) {
        if (needCheckSufficient) {
          if (err instanceof ApiError && err.errorCode === COIN_INSUFFICIENT_ERROR_CODE) {
            setIsCoinInsufficient(true)
            return ''
          }
        }
        const errorMessage = err instanceof Error ? err.message : '语音合成失败'
        setError(errorMessage)
        onError?.(errorMessage)
        console.error('语音合成失败:', err)
        return ''
      } finally {
        setIsGenerating(false)
      }
    },
    [
      getCachedBlobUrl,
      fetchVoiceTtsV2Mutation,
      generateConfigHash,
      cacheEnabled,
      onGenerateStart,
      onGenerateEnd,
      onError,
    ]
  )

  // 清除缓存
  const clearCache = useCallback(() => {
    // 释放所有Blob URL以避免内存泄漏
    Object.values(cacheRef.current).forEach((blobUrl) => {
      URL.revokeObjectURL(blobUrl)
    })
    cacheRef.current = {}
  }, [])

  // 组件卸载时清理所有Blob URLs
  useEffect(() => {
    return () => {
      Object.values(cacheRef.current).forEach((blobUrl) => {
        URL.revokeObjectURL(blobUrl)
      })
    }
  }, [])

  return {
    isGenerating,
    error,
    generateAudioUrl,
    clearCache,
    getCachedBlobUrl,
  }
}
