/**
 * 配送员订单通知 Hook
 * 功能：
 * 1. 轮询获取待配送订单数量
 * 2. 新订单时播放提示音
 * 3. 支持声音开关设置
 */

import { useState, useEffect, useRef, useCallback } from 'react'
import Taro from '@tarojs/taro'
import { pageGltTicketOrder } from '@/api/glt/gltTicketOrder'

// 轮询间隔（毫秒）- 30秒
const POLL_INTERVAL = 30000

// 提示音 URL（使用微信官方提示音）
const NOTIFICATION_SOUND_URL = 'https://res.wx.qq.com/wechatApp/pkg/notice/notice.mp3'

interface RiderNotificationState {
  /** 待配送订单数量 */
  pendingCount: number
  /** 所有配送中订单数量 */
  totalCount: number
  /** 是否正在轮询 */
  isPolling: boolean
  /** 最后更新的订单ID */
  lastOrderId: number | null
  /** 声音是否开启 */
  soundEnabled: boolean
}

interface UseRiderNotificationReturn extends RiderNotificationState {
  /** 开始轮询 */
  startPolling: () => void
  /** 停止轮询 */
  stopPolling: () => void
  /** 刷新数据 */
  refresh: () => Promise<void>
  /** 切换声音开关 */
  toggleSound: () => void
  /** 手动播放提示音 */
  playSound: () => void
}

/**
 * 配送员通知 Hook
 * @param autoStart 是否自动开始轮询，默认 true
 */
export const useRiderNotification = (autoStart = true): UseRiderNotificationReturn => {
  const [state, setState] = useState<RiderNotificationState>({
    pendingCount: 0,
    totalCount: 0,
    isPolling: false,
    lastOrderId: null,
    soundEnabled: true
  })

  const pollTimerRef = useRef<number | null>(null)
  const audioContextRef = useRef<any>(null)
  const lastCountRef = useRef(0)
  const isMountedRef = useRef(true)

  // 获取配送员ID
  const getRiderId = useCallback(() => {
    const riderId = Taro.getStorageSync('UserId')
    return Number(riderId) || undefined
  }, [])

  // 从本地存储加载声音设置
  const loadSoundSetting = useCallback(() => {
    try {
      const enabled = Taro.getStorageSync('rider_sound_enabled')
      return enabled !== '0' // 默认开启
    } catch {
      return true
    }
  }, [])

  // 保存声音设置到本地存储
  const saveSoundSetting = useCallback((enabled: boolean) => {
    try {
      Taro.setStorageSync('rider_sound_enabled', enabled ? '1' : '0')
    } catch (e) {
      console.error('保存声音设置失败', e)
    }
  }, [])

  // 播放提示音
  const playSound = useCallback(() => {
    if (!state.soundEnabled) return

    try {
      // 停止之前的音频
      if (audioContextRef.current) {
        audioContextRef.current.stop()
        audioContextRef.current.destroy()
      }

      // 创建新的音频实例
      const audioContext = Taro.createInnerAudioContext()
      audioContextRef.current = audioContext

      audioContext.src = NOTIFICATION_SOUND_URL
      audioContext.volume = 0.8

      audioContext.play()
      audioContext.onPlay(() => {
        console.log('📢 新订单提示音播放中')
      })

      audioContext.onError((err: any) => {
        console.error('提示音播放失败', err)
        // 播放失败时尝试使用本地提示音
        tryFallbackSound()
      })

      audioContext.onEnded(() => {
        audioContext.destroy()
      })
    } catch (e) {
      console.error('播放提示音异常', e)
    }
  }, [state.soundEnabled])

  // 备用提示音方案（使用微信震动）
  const tryFallbackSound = useCallback(() => {
    try {
      // 震动提示
      Taro.vibrateShort({ type: 'heavy' })
    } catch (e) {
      console.error('震动提示失败', e)
    }
  }, [])

  // 获取未读订单数量
  const fetchUnreadCount = useCallback(async () => {
    const riderId = getRiderId()
    if (!riderId) return

    try {
      const res = await pageGltTicketOrder({
        riderId,
        deliveryStatus: 10, // 待配送状态
        page: 1,
        limit: 1
      } as any)

      const pendingCount = res?.count || 0
      const currentLastId = res?.list?.[0]?.id

      // 如果数量增加，说明有新订单，播放提示音
      if (pendingCount > lastCountRef.current && lastCountRef.current > 0) {
        playSound()
      }

      lastCountRef.current = pendingCount

      if (isMountedRef.current) {
        setState(prev => ({
          ...prev,
          pendingCount,
          lastOrderId: currentLastId || prev.lastOrderId
        }))
      }
    } catch (e) {
      console.error('获取未读订单失败', e)
    }
  }, [getRiderId, playSound])

  // 开始轮询
  const startPolling = useCallback(() => {
    if (pollTimerRef.current) return

    // 立即执行一次
    fetchUnreadCount()

    // 设置定时器
    pollTimerRef.current = setInterval(() => {
      fetchUnreadCount()
    }, POLL_INTERVAL)

    setState(prev => ({ ...prev, isPolling: true }))
  }, [fetchUnreadCount])

  // 停止轮询
  const stopPolling = useCallback(() => {
    if (pollTimerRef.current) {
      clearInterval(pollTimerRef.current)
      pollTimerRef.current = null
    }

    // 停止音频
    if (audioContextRef.current) {
      audioContextRef.current.stop()
      audioContextRef.current.destroy()
      audioContextRef.current = null
    }

    setState(prev => ({ ...prev, isPolling: false }))
  }, [])

  // 刷新数据
  const refresh = useCallback(async () => {
    lastCountRef.current = 0 // 重置计数，强制刷新
    await fetchUnreadCount()
  }, [fetchUnreadCount])

  // 切换声音开关
  const toggleSound = useCallback(() => {
    setState(prev => {
      const newEnabled = !prev.soundEnabled
      saveSoundSetting(newEnabled)
      return { ...prev, soundEnabled: newEnabled }
    })
  }, [saveSoundSetting])

  // 初始化
  useEffect(() => {
    isMountedRef.current = true

    // 加载声音设置
    const soundEnabled = loadSoundSetting()
    setState(prev => ({ ...prev, soundEnabled }))

    // 自动开始轮询
    if (autoStart) {
      startPolling()
    }

    return () => {
      isMountedRef.current = false
      stopPolling()
    }
  }, [autoStart, loadSoundSetting, startPolling, stopPolling])

  // 监听页面显示/隐藏
  useEffect(() => {
    const onShow = () => {
      if (!state.isPolling) {
        startPolling()
      }
    }

    const onHide = () => {
      // 页面隐藏时停止轮询节省电量
      // stopPolling()
    }

    // 微信小程序监听
    if (typeof Taro.onAppShow === 'function') {
      Taro.onAppShow(onShow)
    }
    if (typeof Taro.onAppHide === 'function') {
      Taro.onAppHide(onHide)
    }

    return () => {
      if (typeof Taro.offAppShow === 'function') {
        Taro.offAppShow(onShow)
      }
      if (typeof Taro.offAppHide === 'function') {
        Taro.offAppHide(onHide)
      }
    }
  }, [state.isPolling, startPolling])

  return {
    ...state,
    startPolling,
    stopPolling,
    refresh,
    toggleSound,
    playSound
  }
}

export default useRiderNotification
