import { SoundOutlined } from '@ant-design/icons'
import { Switch, Typography } from 'antd'
import { useEffect, useRef, useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'

import {
  isWorkerSpeechEnabled,
  setWorkerSpeechEnabled,
  speakWorkerText,
} from '@/utils/worker-speech'

/**
 * 打手端新订单语音播报：开关持久化到 localStorage（默认关闭），
 * 通过对比抢单大厅缓存中新出现的工单 ID 触发浏览器语音播报。
 */
export default function WorkerNewOrderSpeech() {
  const queryClient = useQueryClient()
  const [enabled, setEnabled] = useState(isWorkerSpeechEnabled)
  const enabledRef = useRef(enabled)

  useEffect(() => {
    enabledRef.current = enabled
  }, [enabled])

  function toggle(checked: boolean) {
    setEnabled(checked)
    setWorkerSpeechEnabled(checked)
    if (checked) speakWorkerText('新订单播报已开启')
  }

  useEffect(() => {
    if (!enabled) return
    // 首次观察到的大厅快照全部视为已知订单，避免打开开关时播报存量订单。
    let seenIds: Set<number> | null = null
    let flushTimer: ReturnType<typeof setTimeout> | null = null
    const readHallIds = () => {
      const ids = new Set<number>()
      for (const [, data] of queryClient.getQueriesData({ queryKey: ['worker-hall-orders'] })) {
        const pages = (data as { pages?: unknown } | undefined)?.pages
        if (!Array.isArray(pages)) continue
        for (const page of pages) {
          const items = (page as { data?: { items?: unknown } } | null)?.data?.items
          if (!Array.isArray(items)) continue
          for (const item of items) {
            const id = Number((item as { workOrderId?: unknown } | null)?.workOrderId || 0)
            if (id > 0) ids.add(id)
          }
        }
      }
      return ids
    }
    const unsubscribe = queryClient.getQueryCache().subscribe(() => {
      if (!enabledRef.current) return
      const ids = readHallIds()
      if (!seenIds) {
        seenIds = ids
        return
      }
      let hasNew = false
      for (const id of ids) {
        if (!seenIds.has(id)) hasNew = true
      }
      seenIds = ids
      // 大厅刷新事件可能连发，聚合 2 秒内的多批新订单只播报一次。
      if (!hasNew || flushTimer) return
      flushTimer = setTimeout(() => {
        flushTimer = null
        speakWorkerText('您有新的订单，请及时抢单')
      }, 2000)
    })
    return () => {
      if (flushTimer) clearTimeout(flushTimer)
      unsubscribe()
    }
  }, [enabled, queryClient])

  return (
    <div className="worker-speech-toggle">
      <SoundOutlined />
      <Typography.Text>新订单播报</Typography.Text>
      <Switch size="small" checked={enabled} onChange={toggle} />
    </div>
  )
}
