/**
 * useNewInboxBridge — adapta chatStore + instanceStore para o formato
 * que os componentes de display legados já consomem.
 * Nenhum componente visual precisa ser alterado.
 */
import { useMemo, useCallback, useEffect, useRef } from 'react'
import { useChatStore } from '../../store/chatStore'
import { useInstanceStore } from '../../store/instanceStore'
import { chatApi, messageApi, reconcileApi } from '../../services/chatApiService'
import { socketService } from '../../services/socketService'
import { formatPhone, getAvatarProxyUrl } from '../../utils/inboxUtils'
import type { NewWhatsChat } from '../../types/inboxTypes'

// ─── Mapeamentos legado ───────────────────────────────────────────────────────

function chatToLegacy(c: ReturnType<typeof useChatStore.getState>['chats'][0]): NewWhatsChat {
  const isGroup = c.jid.endsWith('@g.us')
  const jidUser = c.jid.split('@')[0]

  // Telefone formatado — sempre passa por formatPhone para normalizar E.164 → exibição
  // c.contactPhone é o número cru do DB (ex: "5511999887766"); formatPhone aplica máscara
  const formattedPhone = isGroup ? jidUser : formatPhone(c.contactPhone ?? jidUser, c.jid)

  // 1. Nome de Exibição
  // Regra estrita: grupos usam SEMPRE o subject (c.name) — nunca o
  // pushName/contactName do último participante que enviou mensagem.
  let displayName = isGroup
    ? (c.name || 'Grupo')
    : (c.contactName || c.name || formattedPhone || jidUser)

  // Limpeza final: se por algum motivo ainda vier o JID completo, removemos o sufixo
  if (displayName.includes('@')) {
    displayName = displayName.split('@')[0]
  }

  // 2. Avatar — só aponta pro proxy quando o banco (contactAvatarUrl) já
  // confirmou que existe foto. Quando é null, Avatar.tsx mostra iniciais
  // direto, sem disparar requisição — elimina os 60+ GETs/lista que o
  // proxy respondia 204. A URL do proxy é estável (o backend lida com a
  // expiração do CDN do WhatsApp internamente).
  const avatar_url: string | null = c.contactAvatarUrl
    ? getAvatarProxyUrl({ instance_name: c.instanceId, remote_jid: c.jid }, 'contact')
    : null

  return {
    id: c.id as any,
    instance_name: c.instanceId,
    remote_jid: c.jid,
    phone: formattedPhone,
    lead_name: c.contactName,
    avatar_url,
    bio: isGroup ? 'Detalhes do Grupo' : (formattedPhone || 'Clique para informações'),
    displayName,
    subject: c.protocolNumber ? `#${c.protocolNumber}` : (isGroup ? null : formattedPhone),
    last_message_text: c.lastMessageBody || null,
    last_message_time: c.lastMessageAt || c.createdAt,
    last_message_from_me: c.lastMessageFromMe ? 1 : 0,
    last_message_status: c.lastMessageStatus?.toLowerCase() ?? null,
    last_message_type: c.lastMessageType?.toLowerCase() ?? null,
    last_message_sender: c.lastMessageSender ?? null,
    unread_count: c.unreadCount,
    is_pinned: c.isPinned,
    is_archived: c.isArchived,
    labels: [],
  }
}

function messagesToLegacy(msgs: ReturnType<typeof useChatStore.getState>['messages'][string]) {
  return (msgs ?? []).map((m) => ({
    id: m.id as any,
    chat_id: m.chatId as any,
    message_id: m.messageId,
    text: m.body ?? '',
    direction: (m.fromMe ? 'out' : 'in') as 'in' | 'out',
    timestamp: new Date(m.timestamp).getTime(),
    status: m.status.toLowerCase(),
    type: m.type.toLowerCase(),
    media_url: m.mediaUrl,
    mime_type: m.mimeType,
    reply_to_id: m.replyToId,
    // Quoted message — mapeia replyTo do Prisma para o formato do MessageBubble
    quoted_id: m.replyTo?.id ?? null,
    quoted_message_id: m.replyTo?.messageId ?? null,
    quoted_message_text: m.replyTo?.body ?? null,
    quoted_participant: m.replyTo ? (m.replyTo.fromMe ? 'me' : null) : null,
    participant: m.pushName ?? null,
    senderJid: m.senderJid ?? null,
    sender_jid: m.senderJid ?? null,
    remote_jid: m.chatId,
    from_me: m.fromMe ? 1 : 0,
    rich_payload: (m as any).richPayload ?? null,
  }))
}

// ─── Hook principal ───────────────────────────────────────────────────────────

export function useNewInboxBridge() {
  const initialized = useRef(false)
  const chatStore = useChatStore()
  const instanceStore = useInstanceStore()

  // ── Boot: socket + instâncias ─────────────────────────────────────────────
  useEffect(() => {
    if (initialized.current) return
    initialized.current = true

    const token = localStorage.getItem('token')
    if (!token) return

    socketService.connect(token)
    chatStore.initSocketListeners()
    instanceStore.initSocketListeners()
    instanceStore.loadInstances()
  }, [])

  // ── Carregar chats quando instância ativa muda ─────────────────────────────
  useEffect(() => {
    const { activeInstanceId } = instanceStore
    if (!activeInstanceId) return
    chatStore.loadChats(activeInstanceId)
    socketService.joinInstance(activeInstanceId)
    // Reconcilia nomes em background (cache 30min — leve em escala)
    reconcileApi.reconcileNames(activeInstanceId).catch(() => {})
  }, [instanceStore.activeInstanceId])

  // ── Adaptação: instâncias → legado ────────────────────────────────────────
  const instancesLegacy = useMemo(
    () =>
      instanceStore.instances.map((i) => ({
        instance: i.id,
        nome: i.name,
        status: i.status === 'CONNECTED' ? 'connected' : i.status.toLowerCase(),
        phone: i.phone,
        avatar: null,
        profilePictureUrl: null,
      })),
    [instanceStore.instances]
  )

  const activeInstanceLegacy = useMemo(
    () => instancesLegacy.find((i) => i.instance === instanceStore.activeInstanceId) ?? null,
    [instancesLegacy, instanceStore.activeInstanceId]
  )

  // ── Adaptação: chats → legado ─────────────────────────────────────────────
  const chatsLegacy = useMemo(() => chatStore.chats.map(chatToLegacy), [chatStore.chats])

  const selectedChatLegacy = useMemo(() => {
    if (!chatStore.activeChatId) return null
    const c = chatStore.chats.find((c) => c.id === chatStore.activeChatId)
    return c ? chatToLegacy(c) : null
  }, [chatStore.activeChatId, chatStore.chats])

  const messagesLegacy = useMemo(() => {
    if (!chatStore.activeChatId) return []
    const raw = chatStore.messages[chatStore.activeChatId] ?? []
    const mapped = messagesToLegacy(raw)
    console.log('[bridge] messagesLegacy recomputed:', { activeChatId: chatStore.activeChatId, rawCount: raw.length, mappedCount: mapped.length })
    return mapped
  }, [chatStore.activeChatId, chatStore.messages])

  // ── Handlers ──────────────────────────────────────────────────────────────

  const handleSelectChat = useCallback(async (chat: NewWhatsChat | null) => {
    if (!chat) { useChatStore.getState().setActiveChat(null); return }
    await chatStore.selectChat(String(chat.id))
  }, [chatStore])

  const handleSendText = useCallback(async (text: string, mentions?: string[], replyToMessageId?: string) => {
    if (!chatStore.activeChatId || !instanceStore.activeInstanceId) return
    const chat = chatStore.chats.find((c) => c.id === chatStore.activeChatId)
    if (!chat) return
    await chatStore.sendMessage(instanceStore.activeInstanceId, chat.jid, text, replyToMessageId, mentions)
  }, [chatStore, instanceStore.activeInstanceId])

  const handleLoadMoreHistory = useCallback(async () => {
    if (!chatStore.activeChatId) return { hasMore: false }
    const oldest = chatStore.messages[chatStore.activeChatId]?.[0]
    if (!oldest) return { hasMore: false }
    return chatStore.loadMessages(chatStore.activeChatId, { before: oldest.timestamp })
  }, [chatStore])

  const handleSetActiveInstance = useCallback((legacyInstance: any) => {
    instanceStore.setActiveInstance(legacyInstance?.instance ?? null)
  }, [instanceStore])

  const handleRefreshInstances = useCallback(async () => {
    await instanceStore.loadInstances()
  }, [instanceStore])

  const handleConnectInstance = useCallback(async (instanceId: string) => {
    await instanceStore.connectInstance(instanceId)
  }, [instanceStore])

  const handleArchiveChat = useCallback(async (chatId: string, archived: boolean) => {
    await chatApi.archive(chatId, archived)
    useChatStore.getState().patchChat(chatId, { isArchived: archived })
  }, [])

  const handlePinChat = useCallback(async (chatId: string, pinned: boolean) => {
    await chatApi.pin(chatId, pinned)
    useChatStore.getState().patchChat(chatId, { isPinned: pinned })
  }, [])

  const handleDeleteChat = useCallback(async (chatId: string) => {
    await chatApi.delete(chatId)
    useChatStore.getState().setChats(
      useChatStore.getState().chats.filter((c) => c.id !== chatId)
    )
    if (useChatStore.getState().activeChatId === chatId) {
      useChatStore.getState().setActiveChat(null)
    }
  }, [])

  const handleMarkRead = useCallback(async (chatId: string) => {
    await chatApi.markRead(chatId)
    useChatStore.getState().patchChat(chatId, { unreadCount: 0 })
  }, [])

  const handleSearchMessages = useCallback(async (q: string) => {
    if (!instanceStore.activeInstanceId || q.length < 2) return []
    return messageApi.search(instanceStore.activeInstanceId, q)
  }, [instanceStore.activeInstanceId])

  // action é a string-key emitida por ChatListItem (ex: 'archive', 'pin', ...)
  // onFavoriteToggle é injetado pelo componente pai (inbox page) pois favoritos são estado local
  const handleMenuAction = useCallback((
    action: string,
    chat: NewWhatsChat,
    onFavoriteToggle?: (jid: string) => void
  ) => {
    const chatId = String(chat.id)
    switch (action) {
      case 'archive':   handleArchiveChat(chatId, !chat.is_archived);  break
      case 'pin':       handlePinChat(chatId, !chat.is_pinned);        break
      case 'mark_read': handleMarkRead(chatId);                        break
      case 'delete':    handleDeleteChat(chatId);                      break
      case 'favorite':  onFavoriteToggle?.(chat.remote_jid);           break
    }
  }, [handleArchiveChat, handlePinChat, handleMarkRead, handleDeleteChat])

  return {
    instances: instancesLegacy,
    activeInstance: activeInstanceLegacy,
    chats: chatsLegacy,
    selectedChat: selectedChatLegacy,
    messages: messagesLegacy,
    loadingChats: chatStore.chatsLoading,
    loadingMessages: chatStore.messagesLoading,
    activeInstanceId: instanceStore.activeInstanceId,
    qrByInstance: instanceStore.qrByInstance,

    setActiveInstance: handleSetActiveInstance,
    refreshInstances: handleRefreshInstances,
    handleSelectChat,
    handleSendText,
    handleLoadMoreHistory,
    handleConnectInstance,
    handleArchiveChat,
    handlePinChat,
    handleDeleteChat,
    handleMarkRead,
    handleSearchMessages,
    handleMenuAction,

    presenceByJid: {} as Record<string, any>,
    isFavoriteChat: (_: NewWhatsChat) => false,
  }
}
