/**
 * WebSocket 连接状态管理 Store
 * 
 * 管理 WebSocket 连接的生命周期
 * 订阅后端推送的消息并转发到其他 Store
 */

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import ws, {
  connect as wsConnect,
  disconnect as wsDisconnect,
  subscribePlayPlan,
  subscribeBroadcast,
  subscribeConnect,
  unsubscribe,
  isConnected as wsIsConnected,
  ConnectionState
} from '@/utils/websocket'

export const useWebSocketStore = defineStore('websocket', () => {
  // 连接状态
  const connectionState = ref(ConnectionState.DISCONNECTED)

  // 是否已连接
  const isConnected = computed(() => connectionState.value === ConnectionState.CONNECTED)

  // 是否正在重连
  const isReconnecting = computed(() => connectionState.value === ConnectionState.RECONNECTING)

  // 订阅ID
  const playPlanSubscription = ref(null)
  const broadcastSubscription = ref(null)
  const connectSubscription = ref(null)

  // 消息回调
  let onPlayPlanChangeCallback = null
  let onBroadcastStartCallback = null
  let onBroadcastEndCallback = null

  // 屏幕 Store 引用（避免循环引用）
  let screenStore = null

  function setScreenStore(store) {
    screenStore = store
  }

  // 状态同步定时器（用于检测 WebSocket 底层连接与 store 状态不一致的情况）
  let stateSyncTimer = null

  function init() {
    if (wsIsConnected()) {
      console.log('[WS Store] WebSocket already connected')
      connectionState.value = ConnectionState.CONNECTED
      return
    }

    console.log('[WS Store] Initializing WebSocket connection...')
    connectionState.value = ConnectionState.CONNECTING

    wsConnect(() => {
      console.log('[WS Store] WebSocket connected successfully')
      connectionState.value = ConnectionState.CONNECTED
      subscribeChannels()
    })
  }

  function subscribeChannels() {
    unsubscribeChannels()

    playPlanSubscription.value = subscribePlayPlan((message) => {
      handlePlayPlanMessage(message)
    })

    broadcastSubscription.value = subscribeBroadcast((message) => {
      handleBroadcastMessage(message)
    })

    connectSubscription.value = subscribeConnect((message) => {
      console.log('[WS Store] Received connect confirmation:', message)
    })
  }

  function unsubscribeChannels() {
    if (playPlanSubscription.value) {
      unsubscribe(playPlanSubscription.value)
      playPlanSubscription.value = null
    }
    if (broadcastSubscription.value) {
      unsubscribe(broadcastSubscription.value)
      broadcastSubscription.value = null
    }
    if (connectSubscription.value) {
      unsubscribe(connectSubscription.value)
      connectSubscription.value = null
    }
  }

  function handlePlayPlanMessage(message) {
    if (!message) return

    const type = message.type
    const data = message.data || {}

    console.log('[WS Store] Received play plan message:', type, data)

    if (type === 'play_plan_changed') {
      if (onPlayPlanChangeCallback) {
        onPlayPlanChangeCallback(data)
      } else if (screenStore) {
        screenStore.handlePlayPlanChanged(data)
      }
    } else if (type === 'play_plan_disabled') {
      if (onPlayPlanChangeCallback) {
        onPlayPlanChangeCallback({ enabled: false, items: [] })
      } else if (screenStore) {
        screenStore.handlePlayPlanDisabled()
      }
    }
  }

  function handleBroadcastMessage(message) {
    if (!message) return

    const type = message.type
    const data = message.data || {}

    console.log('[WS Store] Received broadcast message:', type, data)

    if (type === 'broadcast_started') {
      if (onBroadcastStartCallback) {
        onBroadcastStartCallback(data)
      } else if (screenStore) {
        screenStore.handleBroadcastStarted(data)
      }
    } else if (type === 'broadcast_ended') {
      if (onBroadcastEndCallback) {
        onBroadcastEndCallback()
      } else if (screenStore) {
        screenStore.handleBroadcastEnded()
      }
    }
  }

  function disconnect() {
    console.log('[WS Store] Disconnecting WebSocket')
    unsubscribeChannels()
    if (stateSyncTimer) {
      clearInterval(stateSyncTimer)
      stateSyncTimer = null
    }
    wsDisconnect()
    connectionState.value = ConnectionState.DISCONNECTED
  }

  function setOnPlayPlanChange(callback) {
    onPlayPlanChangeCallback = callback
  }

  function setOnBroadcastStart(callback) {
    onBroadcastStartCallback = callback
  }

  function setOnBroadcastEnd(callback) {
    onBroadcastEndCallback = callback
  }

  return {
    connectionState,
    isConnected,
    isReconnecting,
    init,
    disconnect,
    setScreenStore,
    setOnPlayPlanChange,
    setOnBroadcastStart,
    setOnBroadcastEnd
  }
})