import { local } from '@/utils'
import { useCommandCenterStore } from '@/store/commandCenter'
import { createCommandCenterSocket, destroyCommandCenterSocket } from '@/utils/socket'
import { ONLINE_TIMEOUT_MS, SOCKET_EMIT_EVENT, SOCKET_ON_EVENT } from '@/views/businessOperations/commandCenter/command-center.constants'
import type { CommandCenterKpiVo, CommandCenterVehicleDetailVo, PassengerCallVo, VehicleMonitorVo, WeatherVo } from '@/views/businessOperations/commandCenter/command-center.types'

/**
 * 指挥中心 WebSocket 连接管理 composable
 * @returns isOnline - 是否在线；connect/disconnect - 连接/断开方法；subscribeCity/unsubscribeCity - 订阅/取消订阅城市
 */
export function useCommandCenterSocket() {
  const store = useCommandCenterStore()
  const socket = createCommandCenterSocket()

  /** 判断是否在线（已连接且 5 秒内有推送） */
  const isOnline = computed(() => {
    return store.socketStatus.connected && (Date.now() - store.socketStatus.lastPushAt < ONLINE_TIMEOUT_MS)
  })

  /** 建立 WebSocket 连接并监听事件 */
  const connect = () => {
    socket.connect()
    console.log('[CC-Socket] connecting...')

    socket.on('connect', () => {
      console.log('[CC-Socket] ✅ connected, sid:', socket.id)
      store.socketStatus.connected = true
      const token = local.get('accessToken')
      console.log('[CC-Socket] ⬆ emit auth, token:', token ? `${token.slice(0, 10)}...` : 'null')
      socket.emit(SOCKET_EMIT_EVENT.AUTH, { token })
    })

    socket.on('disconnect', (reason) => {
      console.warn('[CC-Socket] ❌ disconnected, reason:', reason)
      store.socketStatus.connected = false
    })

    socket.on(SOCKET_ON_EVENT.AUTH_SUCCESS, (payload) => {
      console.log('[CC-Socket] ⬇ auth_success', payload)
      console.log('[CC-Socket] ⬆ emit subscribe, cityCode:', store.cityCode)
      socket.emit(SOCKET_EMIT_EVENT.SUBSCRIBE, { cityCode: store.cityCode })
    })

    socket.on(SOCKET_ON_EVENT.AUTH_FAILED, (payload: { message: string }) => {
      console.error('[CC-Socket] ⬇ auth_failed', payload)
      window.$message?.error(`鉴权失败：${payload.message}`)
      socket.disconnect()
    })

    socket.on(SOCKET_ON_EVENT.VEHICLES, (list: VehicleMonitorVo[]) => {
      console.log('[CC-Socket] ⬇ vehicles :', list)
      store.vehicles = list
      store.socketStatus.lastPushAt = Date.now()
    })

    socket.on(SOCKET_ON_EVENT.VEHICLE_DETAIL, (data: CommandCenterVehicleDetailVo) => {
      console.log('[CC-Socket] ⬇ vehicle_detail :', data)
      if (data.vehicleId === store.selectedVehicleId) {
        store.vehicleDetail = data
      }
      store.socketStatus.lastPushAt = Date.now()
    })

    socket.on(SOCKET_ON_EVENT.KPI, (data: CommandCenterKpiVo) => {
      console.log('[CC-Socket] ⬇ kpi', data)
      store.kpi = data
      store.socketStatus.lastPushAt = Date.now()
    })

    socket.on(SOCKET_ON_EVENT.PASSENGER_CALLS, (list: PassengerCallVo[]) => {
      console.log('[CC-Socket] ⬇ passenger_calls,:', list)
      store.passengerCalls = list
      store.socketStatus.lastPushAt = Date.now()
    })

    socket.on(SOCKET_ON_EVENT.WEATHER, (data: WeatherVo) => {
      console.log('[CC-Socket] ⬇ weather:', data)
      store.weather = data
    })
  }

  /** 断开连接并清理监听 */
  const disconnect = () => {
    socket.removeAllListeners()
    destroyCommandCenterSocket()
    store.socketStatus.connected = false
  }

  /**
   * 订阅指定城市的数据推送
   * @param cityCode - 城市编码
   */
  const subscribeCity = (cityCode: string) => {
    console.log('[CC-Socket] ⬆ emit subscribe, cityCode:', cityCode)
    socket.emit(SOCKET_EMIT_EVENT.SUBSCRIBE, { cityCode })
  }

  /**
   * 取消订阅指定城市的数据推送
   * @param cityCode - 城市编码
   */
  const unsubscribeCity = (cityCode: string) => {
    console.log('[CC-Socket] ⬆ emit unsubscribe, cityCode:', cityCode)
    socket.emit(SOCKET_EMIT_EVENT.UNSUBSCRIBE, { cityCode })
  }

  const subscribeVehicleDetail = (vehicleId: number) => {
    console.log('[CC-Socket] ⬆ emit subscribe_vehicle_detail, vehicleId:', vehicleId)
    socket.emit(SOCKET_EMIT_EVENT.SUBSCRIBE_VEHICLE_DETAIL, { vehicleId })
  }

  const unsubscribeVehicleDetail = (vehicleId?: number) => {
    const payload = vehicleId ? { vehicleId } : {}
    console.log('[CC-Socket] ⬆ emit unsubscribe_vehicle_detail', payload)
    socket.emit(SOCKET_EMIT_EVENT.UNSUBSCRIBE_VEHICLE_DETAIL, payload)
  }

  return {
    isOnline,
    connect,
    disconnect,
    subscribeCity,
    unsubscribeCity,
    subscribeVehicleDetail,
    unsubscribeVehicleDetail,
  }
}
