import { useEffect, useRef } from 'react'
import { WebSocketService } from '../services/websocket'
import { logger } from '../utils/logger'
import { isNotificationLikeMessage, isMessageFromSelf } from '../utils/messageTypes'
import { Message, Contact } from '../types'

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[]>>
  unreadCountsRef: React.MutableRefObject<Record<number, number>>
  fetchContacts: () => Promise<void>
}

export function useWebSocket({
  isLoggedIn,
  token,
  currentUserId,
  activeContactIdRef,
  contactsRef,
  setMessages,
  setContacts,
  unreadCountsRef,
  fetchContacts
}: UseWebSocketProps) {
  const fetchContactsRef = useRef(fetchContacts)
  useEffect(() => {
    fetchContactsRef.current = fetchContacts
  }, [fetchContacts])

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

    if (isLoggedIn && token && currentUserId !== null) {
      unreadCountsRef.current = {}
      
      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 isSelf = isMessageFromSelf(incomingMsg, currentUserId)
        
        let messageType: 'text' | 'image' | 'file' | 'video' | 'notification' = 'text'
        if (notificationLike) {
          messageType = 'notification'
        } else {
          const contentType = incomingMsg.content_type
          if (contentType === 'IMAGE') {
            messageType = 'image'
          } else if (contentType === 'VIDEO') {
            messageType = 'video'
          } else if (contentType === 'FILE') {
            messageType = 'file'
          }
        }
        
        const newMessage: Message = {
          id: incomingMsg.id || Date.now(),
          content: incomingMsg.content || incomingMsg.title || '收到一条新消息',
          isSelf: isSelf,
          type: messageType,
          timestamp: incomingMsg.created_at ? new Date(incomingMsg.created_at).getTime() : Date.now(),
          title: incomingMsg.title,
          actionUrl: incomingMsg.action_url,
          actionText: incomingMsg.action_text || '立即处理',
          messageType: incomingMsg.type,
          content_type: incomingMsg.content_type,
          size: (incomingMsg as any).size
        }

        const currentChatId = activeContactIdRef.current
        const isCurrentChat = currentChatId === targetContactId
        
        logger.info('App: Processing new message', {
          targetContactId,
          currentChatId,
          isCurrentChat,
          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 systemContact: Contact = {
            id: targetContactId,
            name: (incomingMsg as any).app_name || '系统通知',
            avatar: '📢',
            lastMessage: undefined,
            lastMessageTime: undefined,
            unreadCount: 0
          }
          
          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)
          
          if (!isCurrentChat && !isSelf) {
            unreadCountsRef.current[targetContactId] = (unreadCountsRef.current[targetContactId] || 0) + 1
          } else if (isCurrentChat) {
            unreadCountsRef.current[targetContactId] = 0
          }
          
          setContacts(prev => {
            const updated = prev.map(c => {
              if (c.id === targetContactId) {
                return {
                  ...c,
                  lastMessage: lastMessageText,
                  lastMessageTime: '刚刚',
                  unreadCount: unreadCountsRef.current[targetContactId] || 0
                }
              }
              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 })
          fetchContactsRef.current().catch(error => {
            logger.error('App: Failed to refresh contacts after receiving message', error)
          })
        }
        
        if (window.electron && window.electron.ipcRenderer) {
          const notificationContent = notificationLike
            ? `${incomingMsg.title || ''}\n${incomingMsg.content || ''}`
            : newMessage.content
          window.electron.ipcRenderer.send('start-notification', { 
            id: targetContactId, 
            name: isNotification ? '系统通知' : (contact?.name || '新消息'), 
            content: notificationContent 
          })
        }
      })

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

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