import { useState, useEffect, useCallback } from 'react'

/**
 * 红点管理 Hook
 * 功能：
 * 1. 管理各种功能的红点显示状态
 * 2. 使用 localStorage 持久化存储
 * 3. 默认显示红点，查看后消失（localStorage 不存在记录时显示红点）
 */

type RedDotKey = string

interface UseRedDotOptions {
  /**
   * localStorage 的前缀，用于避免键名冲突
   */
  prefix?: string
}

interface UseRedDotReturn {
  /**
   * 检查指定功能是否显示红点
   */
  hasRedDot: (key: RedDotKey) => boolean

  /**
   * 标记某个功能为已查看（消除红点）
   */
  markAsViewed: (key: RedDotKey) => void

  /**
   * 显示红点（设置新功能时使用）
   */
  showRedDot: (key: RedDotKey) => void

  /**
   * 批量标记多个功能为已查看
   */
  markMultipleAsViewed: (keys: RedDotKey[]) => void

  /**
   * 清除所有红点
   */
  clearAllRedDots: () => void

  /**
   * 获取所有有红点的功能键
   */
  getAllRedDotKeys: () => RedDotKey[]
}

const DEFAULT_PREFIX = 'red_dot_'

export const useRedDot = (options: UseRedDotOptions = {}): UseRedDotReturn => {
  const { prefix = DEFAULT_PREFIX } = options

  // 状态：存储当前所有红点的状态
  const [redDotState, setRedDotState] = useState<Record<RedDotKey, boolean>>({})

  // 生成完整的 localStorage 键名
  const getStorageKey = useCallback(
    (key: RedDotKey): string => {
      return `${prefix}${key}`
    },
    [prefix]
  )

  // 从 localStorage 加载红点状态
  const loadRedDotState = useCallback(() => {
    try {
      const state: Record<RedDotKey, boolean> = {}

      // 遍历 localStorage 中所有以 prefix 开头的键
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i)
        if (key && key.startsWith(prefix)) {
          const redDotKey = key.replace(prefix, '')
          const value = localStorage.getItem(key)
          // 如果存在记录且值为 'viewed'，则不显示红点（已查看）
          state[redDotKey] = value !== 'viewed'
        }
      }

      setRedDotState(state)
    } catch (error) {
      console.warn('Failed to load red dot state from localStorage:', error)
    }
  }, [prefix])

  // 保存红点状态到 localStorage
  const saveRedDotState = useCallback(
    (key: RedDotKey, viewed: boolean) => {
      try {
        const storageKey = getStorageKey(key)
        if (viewed) {
          // 标记为已查看
          localStorage.setItem(storageKey, 'viewed')
        } else {
          // 移除记录，恢复默认显示红点状态
          localStorage.removeItem(storageKey)
        }

        // 触发自定义事件，通知同页面内的其他组件实例
        const event = new CustomEvent('redDotStateChange', {
          detail: { key, viewed, prefix },
        })
        window.dispatchEvent(event)
      } catch (error) {
        console.warn('Failed to save red dot state to localStorage:', error)
      }
    },
    [getStorageKey, prefix]
  )

  // 初始化时加载状态
  useEffect(() => {
    loadRedDotState()
  }, [loadRedDotState])

  // 监听状态变化，同步不同组件实例的状态
  useEffect(() => {
    // 处理同页面内的自定义事件
    const handleRedDotStateChange = (e: CustomEvent) => {
      const { key, viewed, prefix: eventPrefix } = e.detail

      // 只处理与当前前缀相关的变化
      if (eventPrefix === prefix) {
        setRedDotState((prev) => {
          const newState = { ...prev }

          if (viewed) {
            // 标记为已查看
            newState[key] = false
          } else {
            // 恢复默认显示红点
            delete newState[key]
          }

          return newState
        })
      }
    }

    // 处理跨标签页的 localStorage 变化
    const handleStorageChange = (e: StorageEvent) => {
      // 只处理与当前前缀相关的变化
      if (e.key && e.key.startsWith(prefix)) {
        const redDotKey = e.key.replace(prefix, '')

        setRedDotState((prev) => {
          const newState = { ...prev }

          if (e.newValue === 'viewed') {
            // 标记为已查看
            newState[redDotKey] = false
          } else if (e.newValue === null) {
            // 移除了 localStorage 记录，恢复默认显示红点
            delete newState[redDotKey]
          }

          return newState
        })
      }
    }

    // 添加事件监听器
    window.addEventListener('redDotStateChange', handleRedDotStateChange as EventListener)
    window.addEventListener('storage', handleStorageChange)

    // 清理函数
    return () => {
      window.removeEventListener('redDotStateChange', handleRedDotStateChange as EventListener)
      window.removeEventListener('storage', handleStorageChange)
    }
  }, [prefix])

  // 检查是否显示红点
  const hasRedDot = useCallback(
    (key: RedDotKey): boolean => {
      // 如果 redDotState 中没有这个 key，说明 localStorage 中也没有记录，应该显示红点
      // 如果 redDotState 中有这个 key 且为 true，说明 localStorage 中没有 'viewed' 记录，应该显示红点
      // 如果 redDotState 中有这个 key 且为 false，说明 localStorage 中有 'viewed' 记录，不显示红点
      return redDotState[key] !== false
    },
    [redDotState]
  )

  // 标记为已查看（消除红点）
  const markAsViewed = useCallback(
    (key: RedDotKey) => {
      setRedDotState((prev) => ({
        ...prev,
        [key]: false, // 设置为 false 表示已查看，不显示红点
      }))
      saveRedDotState(key, true) // true 表示已查看，在 localStorage 中存储 'viewed'
    },
    [saveRedDotState]
  )

  // 显示红点（重置为未查看状态）
  const showRedDot = useCallback(
    (key: RedDotKey) => {
      setRedDotState((prev) => {
        const newState = { ...prev }
        delete newState[key] // 删除状态，恢复默认显示红点
        return newState
      })
      saveRedDotState(key, false) // false 表示移除 localStorage 记录，恢复默认显示红点
    },
    [saveRedDotState]
  )

  // 批量标记为已查看
  const markMultipleAsViewed = useCallback(
    (keys: RedDotKey[]) => {
      setRedDotState((prev) => {
        const newState = { ...prev }
        keys.forEach((key) => {
          newState[key] = false // 设置为 false 表示已查看
          saveRedDotState(key, true) // 在 localStorage 中标记为已查看
        })
        return newState
      })
    },
    [saveRedDotState]
  )

  // 清除所有红点（重置为默认显示状态）
  const clearAllRedDots = useCallback(() => {
    try {
      // 清除 localStorage 中的所有红点数据
      const keysToRemove: string[] = []
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i)
        if (key && key.startsWith(prefix)) {
          keysToRemove.push(key)
        }
      }
      keysToRemove.forEach((key) => localStorage.removeItem(key))

      // 清除状态，恢复默认显示红点
      setRedDotState({})
    } catch (error) {
      console.warn('Failed to clear red dots from localStorage:', error)
    }
  }, [prefix])

  // 获取所有有红点的功能键
  const getAllRedDotKeys = useCallback((): RedDotKey[] => {
    // 返回所有应该显示红点的键
    // 包括：1. redDotState 中不存在的键（默认显示）
    // 包括：2. redDotState 中存在且值为 true 的键
    // 由于我们现在用 hasRedDot 来判断，这里简化逻辑
    const allPossibleKeys = Object.keys(RED_DOT_KEYS).map(
      (key) => RED_DOT_KEYS[key as keyof typeof RED_DOT_KEYS]
    )
    return allPossibleKeys.filter((key) => hasRedDot(key))
  }, [hasRedDot])

  return {
    hasRedDot,
    markAsViewed,
    showRedDot,
    markMultipleAsViewed,
    clearAllRedDots,
    getAllRedDotKeys,
  }
}

// 预定义的红点类型常量，方便使用
export const RED_DOT_KEYS = {
  CHAT_BUBBLE: 'chat_bubble',
  CHAT_BACKGROUND: 'chat_background',
  CHAT_MODEL: 'chat_model',
  PROFILE_SETTING: 'profile_setting',
  // 可以根据需要添加更多
} as const

export type RedDotKeyType = (typeof RED_DOT_KEYS)[keyof typeof RED_DOT_KEYS]
