import { useEffect, useRef } from 'react'
import { WebSocketService } from '../services/websocket'
import { logger } from '../utils/logger'
import { isNotificationLikeMessage } from '../utils/messageTypes'
import { formatApiMessageToMessage } from '../utils/formatMessage'
import { Message, Contact } from '../types'
import { getSessionAvatar } from '../utils/avatarUtils'
import type { FetchContactsOptions } from './useContacts'

interface UseWebSocketProps {
  isLoggedIn: boolean
  token: string
  currentUserId: number | null
  activeContactIdRef: React.MutableRefObject<number | null>
  contactsRef: React.MutableRefObject<Contact[]>
  setMessages: React.Dispatch<React.SetStateAction<Record<number, Message[]>>>
  setContacts: React.Dispatch<React.SetStateAction<Contact[]>>
  /** 收到消息后与会话列表一并刷新（防抖内先拉 conversations 再拉总未读） */
  refreshUnreadCount: () => void
  fetchContacts: (options?: FetchContactsOptions) => Promise<void>
}

export function useWebSocket({
  isLoggedIn,
  token,
  currentUserId,
  activeContactIdRef,
  contactsRef,
  setMessages,
  setContacts,
  refreshUnreadCount,
  fetchContacts
}: UseWebSocketProps) {
  const fetchContactsRef = useRef(fetchContacts)
  const refreshUnreadCountRef = useRef(refreshUnreadCount)
  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  /** 主窗口是否在前台且可见（用于：停在当前会话但窗口在后台时仍推托盘提醒） */
  const mainWindowFocusedRef = useRef(
    typeof document !== 'undefined' &&
      document.visibilityState === 'visible' &&
      document.hasFocus()
  )

  useEffect(() => {
    const syncMainWindowFocus = () => {
      mainWindowFocusedRef.current =
        document.visibilityState === 'visible' && document.hasFocus()
    }
    syncMainWindowFocus()
    window.addEventListener('focus', syncMainWindowFocus)
    window.addEventListener('blur', syncMainWindowFocus)
    document.addEventListener('visibilitychange', syncMainWindowFocus)
    return () => {
      window.removeEventListener('focus', syncMainWindowFocus)
      window.removeEventListener('blur', syncMainWindowFocus)
      document.removeEventListener('visibilitychange', syncMainWindowFocus)
    }
  }, [])

  useEffect(() => {
    fetchContactsRef.current = fetchContacts
  }, [fetchContacts])

  useEffect(() => {
    refreshUnreadCountRef.current = refreshUnreadCount
  }, [refreshUnreadCount])

  useEffect(() => {
    let wsService: WebSocketService | null = null

    if (isLoggedIn && token && currentUserId !== null) {
      wsService = new WebSocketService(token, async (incomingMsg) => {
        if (!incomingMsg) {
          logger.warn('App: Received null or undefined message')
          return
        }
        
        logger.info('App: Received new message', { 
          id: incomingMsg.id, 
          type: incomingMsg.type,
          sender_id: incomingMsg.sender_id,
          receiver_id: incomingMsg.receiver_id,
          app_id: (incomingMsg as any).app_id,
          currentUserId: currentUserId
        })
        
        let targetContactId: number | null = null
        const isNotification = incomingMsg.type === 'NOTIFICATION'
        const notificationLike = isNotificationLikeMessage(
          incomingMsg.type,
          incomingMsg.content_type
        )
        const appId = (incomingMsg as any).app_id as number | undefined
        const isBroadcast = Boolean((incomingMsg as any).is_broadcast)
        
        if (isNotification && appId) {
          // 系统通知 / 广播：按照 Web 端约定，使用负的 app_id 作为会话 ID
          targetContactId = -appId
        } else if (isNotification) {
          // 没有 app_id 的通知，回退到按 receiver_id 归入普通会话
          targetContactId = incomingMsg.receiver_id || 0
        } else {
          if (incomingMsg.receiver_id === currentUserId) {
            targetContactId = incomingMsg.sender_id || null
          } else if (incomingMsg.sender_id === currentUserId) {
            targetContactId = incomingMsg.receiver_id || null
          } else if (incomingMsg.sender_id && incomingMsg.sender_id !== currentUserId) {
            targetContactId = incomingMsg.sender_id
            logger.info('App: receiver_id missing, assuming message from sender', {
              sender_id: incomingMsg.sender_id,
              currentUserId
            })
          }
        }
        
        if (targetContactId === null) {
          logger.warn('App: Could not determine targetContactId', {
            incomingMsg,
            currentUserId,
            hasReceiverId: incomingMsg.receiver_id !== undefined,
            hasSenderId: incomingMsg.sender_id !== undefined
          })
          return
        }
        
        const newMessage = formatApiMessageToMessage(incomingMsg, currentUserId)
        const isSelf = newMessage.isSelf

        const currentChatId = activeContactIdRef.current
        const isCurrentChat = currentChatId === targetContactId
        
        const mainFocused = mainWindowFocusedRef.current
        const suppressTrayForForegroundChat = isCurrentChat && mainFocused

        logger.info('App: Processing new message', {
          targetContactId,
          currentChatId,
          isCurrentChat,
          mainWindowFocused: mainFocused,
          isSelf
        })
        
        setMessages(prev => {
          const currentMessages = prev[targetContactId!] || []
          const exists = currentMessages.some(msg => msg.id === newMessage.id)
          if (exists) {
            logger.warn('App: Message already exists, skipping', { messageId: newMessage.id })
            return prev
          }
          return {
            ...prev,
            [targetContactId!]: [...currentMessages, newMessage]
          }
        })
        
        const currentContacts = contactsRef.current
        let contact = currentContacts.find(c => c.id === targetContactId)
        
        // 对于系统通知会话，如果当前联系人列表中不存在，则在本地创建一个虚拟联系人
        if (!contact && isNotification && appId) {
          const systemName = (incomingMsg as any).app_name || '系统通知'
          const systemContact: Contact = {
            id: targetContactId,
            name: systemName,
            avatar: getSessionAvatar(targetContactId, systemName, 40),
            lastMessage: undefined,
            lastMessageTime: undefined,
            unreadCount: 0,
            remarks: undefined
          }
          
          contact = systemContact
          
          setContacts(prev => {
            const exists = prev.some(c => c.id === targetContactId)
            if (exists) {
              return prev
            }
            return [systemContact, ...prev]
          })
        }
        
        if (contact) {
          const lastMessageText = notificationLike
            ? (incomingMsg.title || incomingMsg.content)
            : (newMessage.type === 'image' ? '[图片]' : newMessage.content)

          // 未读数以服务端 /messages/unread-count 为准；此处只更新预览与时间，不修改 unreadCount
          setContacts(prev => {
            const updated = prev.map(c => {
              if (c.id === targetContactId) {
                return {
                  ...c,
                  lastMessage: lastMessageText,
                  lastMessageTime: '刚刚'
                }
              }
              return c
            })
            
            const contactIndex = updated.findIndex(c => c.id === targetContactId)
            if (contactIndex > 0) {
              const [contact] = updated.splice(contactIndex, 1)
              return [contact, ...updated]
            }
            
            return updated
          })
        } else {
          logger.info('App: Contact not in list, refreshing contacts', { targetContactId })
          void fetchContactsRef.current({ silent: true }).catch(error => {
            logger.warn('App: fetchContacts after WS (missing contact) failed', error)
          })
        }

        if (debounceTimerRef.current) {
          clearTimeout(debounceTimerRef.current)
        }
        debounceTimerRef.current = setTimeout(() => {
          debounceTimerRef.current = null
          void fetchContactsRef
            .current({ silent: true })
            .then(() => {
              refreshUnreadCountRef.current()
            })
            .catch((error: unknown) => {
              logger.warn('App: fetchContacts after WS message failed', error)
              refreshUnreadCountRef.current()
            })
        }, 400)

        // 仅当「当前会话且主窗口在前台」时抑制托盘；否则（含同会话但窗口在后台）推 unreadMap
        if (!suppressTrayForForegroundChat && window.electron && window.electron.ipcRenderer) {
          const notificationContent = notificationLike
            ? `${incomingMsg.title || ''}\n${incomingMsg.content || ''}`
            : newMessage.content
          window.electron.ipcRenderer.send('start-notification', {
            id: targetContactId,
            name:
              contact?.name ||
              (isNotification ? ((incomingMsg as any).app_name || '系统通知') : '新消息'),
            content: notificationContent
          })
        }
      })

      wsService.connect()
    } else if (isLoggedIn && token && currentUserId === null) {
      logger.warn('App: WebSocket not initialized because currentUserId is null')
    }

    return () => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current)
        debounceTimerRef.current = null
      }
      wsService?.disconnect()
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isLoggedIn, token, currentUserId])
}
