'use client'

import { useEffect, useMemo, useRef, useState } from 'react'
import { ChatProvider, useChatContext } from '@/app/contexts/ChatContext'
import { SupabaseUserProvider } from '@/app/contexts/SupabaseUserContext'
import { PushNotificationsProvider, usePushNotificationsContext } from '@/app/contexts/PushNotificationsContext'
import { useConversations } from './hooks'
import { Avatar } from './components'
import { ChatOnboarding } from './components/ChatOnboarding'
import { ConversationListSkeleton } from './components/ConversationListSkeleton'
import { Search, UserPlus, User, LogOut, RotateCw, MessageCircle, MoreVertical, Bell, BellOff } from 'lucide-react'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  DropdownMenuSeparator,
} from '@/components/ui/dropdown-menu'
 
import { AuthenticatedLayout } from '@/app/components/AthenticatedLayout'
import { useTranslations } from 'next-intl'
import { InviteUserModal } from './components/InviteUserModal'
import { PushNotificationPrompt } from './components/PushNotificationPrompt'
import { SubscriptionStatusPopup } from './components/SubscriptionStatusPopup'
import { useSupabaseUser } from '@/app/contexts/SupabaseUserContext'
import { SignOutModal } from '@/app/components/SignOutModal'
import { useSearchParams, useRouter } from 'next/navigation'
import { socket } from '@/lib/socket'

type Props = {
  children: React.ReactNode
}

function ChatLayoutContent({ children }: Props) {
  const router = useRouter()
  const { selectedChat, setSelectedChat, showMobileChat, setShowMobileChat } =
    useChatContext()
  const { conversations, loading, error, search, reload, clearUnread } = useConversations()
  const [searchQuery, setSearchQuery] = useState('')
  const [showOnboarding, setShowOnboarding] = useState(false)
  const [showInviteModal, setShowInviteModal] = useState(false)
  const [showSignOutModal, setShowSignOutModal] = useState(false)
  const t = useTranslations('chat.layout')
  const ti = useTranslations('chat.invite')
  const tn = useTranslations('chat.notifications')
  const { supabaseUser } = useSupabaseUser()
  const searchParams = useSearchParams()
  const [processingInvite, setProcessingInvite] = useState(false)
  const [localConversations, setLocalConversations] = useState(conversations)
  const { status: pushStatus, subscribe: subscribePush, unsubscribe: unsubscribePush } = usePushNotificationsContext()
  const totalUnread = useMemo(
    () =>
      localConversations.reduce(
        (acc, conv) => acc + (typeof conv.unreadCount === 'number' ? conv.unreadCount : 0),
        0
      ),
    [localConversations]
  )

  // Synchroniser localConversations avec conversations
  useEffect(() => {
    setLocalConversations(conversations)
  }, [conversations])

  const handleSearch = async (query: string) => {
    setSearchQuery(query)
    if (query.trim()) {
      await search(query)
    } else {
      await reload()
    }
  }

  const handleStartChatting = () => {
    setShowOnboarding(false)
    setShowInviteModal(true)
  }

  const handleSignOutClick = () => {
    setShowSignOutModal(true)
  }

  const handleSignOut = async () => {
    try {
      const response = await fetch('/api/signout', {
        method: 'POST',
        credentials: 'include',
      })

      if (response.ok) {
        // Rediriger vers la page d'authentification avec router
        router.push('/auth')
      } else {
        console.error('Error during sign out')
        setShowSignOutModal(false)
      }
    } catch (error) {
      console.error('Error during sign out:', error)
      setShowSignOutModal(false)
    }
  }

  const handleTogglePushNotifications = async () => {
    if (pushStatus === 'subscribed') {
      // Désabonner
      await unsubscribePush()
    } else {
      // S'abonner
      await subscribePush()
    }
  }

  // Connexion Socket.IO et rejoindre toutes les conversations
  useEffect(() => {
    if (!supabaseUser?.id || localConversations.length === 0) return

    const joinAllConversations = () => {
      // Rejoindre toutes les conversations de l'utilisateur
      localConversations.forEach(conv => {
        socket.emit('join-conversation', conv.id)
      })
    }

    // Connexion au socket
    if (!socket.connected) {
      socket.connect()
      // Attendre la connexion avant de rejoindre les rooms
      socket.once('connect', joinAllConversations)
    } else {
      // Déjà connecté, rejoindre immédiatement
      joinAllConversations()
    }

    return () => {
      // Quitter toutes les conversations lors du démontage
      if (socket.connected) {
        localConversations.forEach(conv => {
          socket.emit('leave-conversation', conv.id)
        })
      }
    }
  }, [supabaseUser?.id, localConversations.length])

  // Réagir aux notifications push reçues (incrémente le badge même si l'onglet est visible)
  useEffect(() => {
    if (typeof window === 'undefined' || !('serviceWorker' in navigator)) return

    const handleServiceWorkerMessage = (event: MessageEvent) => {
      const messageData = (event.data as any) || {}
      
      // Répondre aux demandes d'URL actuelle du service worker
      if (messageData?.type === 'GET_CURRENT_URL') {
        const port = event.ports[0]
        if (port) {
          port.postMessage({
            currentUrl: window.location.pathname,
            isVisible: document.visibilityState === 'visible',
          })
        }
        return
      }
      
      if (messageData?.type !== 'PUSH_NOTIFICATION') return

      const payload = messageData.payload || {}
      const { conversationId, senderMainId, messagePreview, timestamp } = payload
      const notificationType = (payload?.type as string | undefined) ?? 'message'

      // Ne gérer que les notifications de type message
      if (notificationType !== 'message') return

      if (!conversationId) return
      if (conversationId === selectedChat) return
      if (typeof senderMainId === 'number' && senderMainId === supabaseUser?.main_id) return

      setLocalConversations((prev) => {
        const index = prev.findIndex((conv) => conv.id === conversationId)
        if (index === -1) return prev

        const target = prev[index]
        const updatedConversation = {
          ...target,
          unreadCount: (target.unreadCount || 0) + 1,
          lastMessage: messagePreview ?? target.lastMessage,
          lastMessageTime: timestamp ? new Date(timestamp).toLocaleTimeString() : target.lastMessageTime,
          lastMessageTimestamp: timestamp ? new Date(timestamp).getTime() : target.lastMessageTimestamp,
        }

        const others = prev.filter((_, idx) => idx !== index)
        return [updatedConversation, ...others]
      })
    }

    navigator.serviceWorker.addEventListener('message', handleServiceWorkerMessage)

    return () => {
      navigator.serviceWorker.removeEventListener('message', handleServiceWorkerMessage)
    }
  }, [selectedChat, supabaseUser?.main_id])

  const processedConversationRef = useRef<string | null>(null)

  // Ouvrir automatiquement une conversation depuis l'URL ?conversation=<id>
  useEffect(() => {
    const conversationParam = searchParams?.get('conversation')
    if (!conversationParam) return

    // Éviter de retraiter plusieurs fois la même valeur
    if (processedConversationRef.current === conversationParam) return

    // Vérifier si la conversation existe dans la liste
    const conversationExists = localConversations.some(conv => conv.id === conversationParam)
    if (!conversationExists) return

    processedConversationRef.current = conversationParam

    setSelectedChat(conversationParam)
    setShowMobileChat(true)
    
    // Réinitialiser uniquement le badge de cette conversation
    setLocalConversations(prev =>
      prev.map(c =>
        c.id === conversationParam ? { ...c, unreadCount: 0 } : c
      )
    )

    // Nettoyer le paramètre de l'URL (pour l'utilisateur)
    if (typeof window !== 'undefined') {
      const url = new URL(window.location.href)
      url.searchParams.delete('conversation')
      window.history.replaceState({}, '', url.toString())
    }
  }, [searchParams, localConversations, setSelectedChat, setShowMobileChat])

  // Traiter un lien d'invitation directe ?invitation_code=<code>
  useEffect(() => {
    const invitationCode = searchParams?.get('invitation_code')
    if (!invitationCode || processingInvite) return
    // Attendre que l'utilisateur Supabase soit prêt pour éviter les erreurs en aval
    if (!supabaseUser?.id) return
    setProcessingInvite(true)

    const acceptInvite = async () => {
      try {
        // Récupérer l'ID à partir du code d'invitation
        const codeRes = await fetch('/api/chat/get-inviter-id', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ invitationCode }),
        })
        
        if (!codeRes.ok) {
          const errorData = await codeRes.json().catch(() => ({}))
          console.error('Error retrieving inviter ID:', errorData)
          
          // Nettoyer l'URL même en cas d'erreur pour éviter de réessayer indéfiniment
          if (typeof window !== 'undefined') {
            const url = new URL(window.location.href)
            url.searchParams.delete('invitation_code')
            window.history.replaceState({}, '', url.toString())
          }
          return
        }

        const codeData = await codeRes.json()
        
        if (!codeData?.inviterMainId) {
          console.error('Invalid response format:', codeData)
          // Nettoyer l'URL même en cas d'erreur
          if (typeof window !== 'undefined') {
            const url = new URL(window.location.href)
            url.searchParams.delete('invitation_code')
            window.history.replaceState({}, '', url.toString())
          }
          return
        }

        // Accepter l'invitation avec l'ID récupéré
        const res = await fetch('/api/chat/accept-direct-invite', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({ inviterMainId: Number(codeData.inviterMainId) }),
        })
        
        if (!res.ok) {
          const errorData = await res.json().catch(() => ({}))
          console.error('Error accepting invitation:', errorData)
          // Nettoyer l'URL même en cas d'erreur
          if (typeof window !== 'undefined') {
            const url = new URL(window.location.href)
            url.searchParams.delete('invitation_code')
            window.history.replaceState({}, '', url.toString())
          }
          return
        }

        const data = await res.json()
        if (data?.conversationId) {
          setSelectedChat(data.conversationId)
          setShowMobileChat(true)
          await reload()
          // Nettoyer l'URL pour éviter de retraiter l'invitation
          if (typeof window !== 'undefined') {
            const url = new URL(window.location.href)
            url.searchParams.delete('invitation_code')
            window.history.replaceState({}, '', url.toString())
          }
        }
      } catch (e) {
        console.error('Error in accept-direct-invite:', e)
        // Nettoyer l'URL même en cas d'erreur
        if (typeof window !== 'undefined') {
          const url = new URL(window.location.href)
          url.searchParams.delete('invitation_code')
          window.history.replaceState({}, '', url.toString())
        }
      } finally {
        setProcessingInvite(false)
      }
    }

    acceptInvite()
  }, [searchParams, supabaseUser?.id])

  // Afficher l'onboarding si pas de conversations et pas en cours de chargement
  const shouldShowOnboarding =
    !loading && !error && localConversations.length === 0 && !showOnboarding

  return (
    <div className="h-screen bg-gray-50 dark:bg-gray-900 flex">
      {/* Sidebar des conversations - Style Bento */}
      <div
        className={`${
          showMobileChat ? 'hidden' : 'flex'
        } lg:flex w-full lg:w-1/3 xl:w-1/4 bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 flex-col`}
      >
        {/* Header Bento */}
        <div className="sticky top-0 z-10 bg-white dark:bg-gray-800 p-4 lg:p-6 lg:relative lg:z-auto border-b border-gray-200 dark:border-gray-700">
          <div className="mb-4">
            <div className="flex items-center justify-between">
              <div>
                <h1 className="text-lg lg:text-xl font-bold text-gray-900 dark:text-white">
                  {t('title')}
                </h1>
                <p className="text-xs lg:text-sm text-gray-500 dark:text-gray-400">
                  {t('subtitle')}
                </p>
              </div>
              <div className="flex items-center gap-2">
                <button
                  onClick={() => reload(false)}
                  disabled={loading}
                  className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-xl transition-colors disabled:opacity-50"
                  title={t('retryButton')}
                  aria-label={t('retryButton')}
                >
                  <RotateCw className={`w-5 h-5 text-gray-500 dark:text-gray-400 ${loading ? 'animate-spin' : ''}`} />
                </button>
                
                <button
                  onClick={() => setShowInviteModal(true)}
                  className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-xl transition-colors"
                  title={ti('inviteButton')}
                  aria-label={ti('inviteButton')}
                >
                  <UserPlus className="w-5 h-5 text-gray-500 dark:text-gray-400" />
                </button>
                <button
                  className="relative p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-xl transition-colors"
                  title="Messages"
                  aria-label="Messages"
                  type="button"
                >
                  <MessageCircle className="w-5 h-5 text-gray-500 dark:text-gray-400" />
                  {totalUnread > 0 && (
                    <span className="absolute -top-1 -right-1 bg-orange-500 text-white text-[10px] font-semibold px-1.5 py-[1px] rounded-full min-w-[16px] text-center">
                      {totalUnread > 9 ? '9+' : totalUnread}
                    </span>
                  )}
                </button>
                
                {/* Dropdown menu - 3 points verticaux */}
                <DropdownMenu>
                  <DropdownMenuTrigger asChild>
                    <button
                      className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-xl transition-colors"
                      title="Options"
                      aria-label="Options"
                    >
                      <MoreVertical className="w-5 h-5 text-gray-500 dark:text-gray-400" />
                    </button>
                  </DropdownMenuTrigger>
                  <DropdownMenuContent align="end" className="w-56">
                    <DropdownMenuItem 
                      onClick={handleTogglePushNotifications}
                      className="cursor-pointer"
                      disabled={pushStatus === 'unsupported' || pushStatus === 'registering'}
                    >
                      {pushStatus === 'subscribed' ? (
                        <>
                          <BellOff className="w-4 h-4 mr-2" />
                          <span>{tn('disableNotifications')}</span>
                        </>
                      ) : (
                        <>
                          <Bell className="w-4 h-4 mr-2" />
                          <span>{tn('enableNotifications')}</span>
                        </>
                      )}
                    </DropdownMenuItem>
                  </DropdownMenuContent>
                </DropdownMenu>
              </div>
            </div>
          </div>

          {/* Barre de recherche Bento */}
          <div className="relative">
            <input
              type="text"
              placeholder={t('searchPlaceholder')}
              value={searchQuery}
              onChange={(e) => handleSearch(e.target.value)}
              className="w-full pl-8 lg:pl-10 pr-3 lg:pr-4 py-2 border-0 rounded-xl bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-teal-500 text-sm lg:text-base"
            />
            <Search className="absolute left-2 lg:left-3 top-2.5 w-3 h-3 lg:w-4 lg:h-4 text-gray-400" />
          </div>
        </div>

        {/* Liste des conversations - Style Bento */}
        <div className="flex-1 overflow-y-auto p-3 lg:p-4 space-y-2 lg:space-y-3 pb-20 lg:pb-3">
          {/* État de chargement */}
          {loading && (
            <ConversationListSkeleton />
          )}

          {/* État d'erreur */}
          {error && (
            <div className="p-4 bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 rounded-xl text-center">
              <p className="text-sm">{error}</p>
              <button
                onClick={() => reload(false)}
                className="mt-2 text-xs underline hover:no-underline"
              >
                {t('retryButton')}
              </button>
            </div>
          )}

          {/* État vide */}
          {!loading && !error && localConversations.length === 0 && (
            <div className="p-10 text-center">
              <div className="inline-flex items-center justify-center w-12 h-12 rounded-2xl bg-teal-50 dark:bg-teal-900/20 text-teal-600 dark:text-teal-300 mb-3">
                <UserPlus className="w-6 h-6" />
              </div>
              <h3 className="text-base font-semibold text-gray-900 dark:text-white mb-1">{t('emptyTitle')}</h3>
              <p className="text-sm text-gray-500 dark:text-gray-400 mb-4">{t('emptySubtitle')}</p>
              <button
                onClick={() => setShowInviteModal(true)}
                className="inline-flex items-center gap-2 px-3 py-2 rounded-xl bg-teal-500 text-white hover:bg-teal-600 transition-colors"
                title={ti('inviteButton')}
                aria-label={ti('inviteButton')}
              >
                <UserPlus className="w-4 h-4" /> {ti('inviteButton')}
              </button>
            </div>
          )}

          {/* Liste des conversations */}
          {!loading && !error && localConversations.map((conversation) => (
            <div
              key={conversation.id}
              onClick={() => {
                setSelectedChat(conversation.id)
                setShowMobileChat(true)
                // Réinitialiser uniquement le badge de cette conversation
                setLocalConversations(prev =>
                  prev.map(c =>
                    c.id === conversation.id ? { ...c, unreadCount: 0 } : c
                  )
                )
              }}
              className={`bg-white dark:bg-gray-800 rounded-2xl shadow-sm border border-gray-200 dark:border-gray-700 p-3 lg:p-4 cursor-pointer hover:shadow-md transition-all duration-200 ${
                selectedChat === conversation.id
                  ? 'lg:ring-2 lg:ring-teal-500 lg:bg-teal-50 dark:lg:bg-teal-900/20'
                  : ''
              }`}
            >
              <div className="flex items-center space-x-3">
                <Avatar
                  avatar={conversation.avatar || null}
                  name={conversation.name || t('conversationFallback')}
                  size="md"
                />
                <div className="flex-1 min-w-0">
                  <div className="flex items-center justify-between mb-1">
                    <h3 className="text-sm lg:text-sm font-semibold text-gray-900 dark:text-white truncate">
                      {conversation.name}
                    </h3>
                    <span className="text-xs text-gray-500 dark:text-gray-400 flex-shrink-0 ml-2">
                      {conversation.lastMessageTime}
                    </span>
                  </div>
                  <p className="text-xs text-gray-600 dark:text-gray-300 mb-2 line-clamp-1">
                    {conversation.lastMessage}
                  </p>
                  <div className="flex items-center justify-between">
                    <span
                      className={`text-xs px-2 py-1 rounded-full ${
                        conversation.isGroup
                          ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300'
                          : 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300'
                      }`}
                    >
                      {conversation.isGroup ? t('groupLabel') : t('contactLabel')}
                    </span>
                    {conversation.unreadCount > 0 && (
                      <span className="bg-orange-500 text-white text-xs rounded-full px-2 py-1 min-w-[18px] lg:min-w-[20px] text-center font-medium">
                        {conversation.unreadCount}
                      </span>
                    )}
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>

        {/* Section utilisateur connecté - Style Bento */}
        {supabaseUser && (
          <div className="sticky bottom-0 z-10 bg-white dark:bg-gray-800 p-4 lg:p-6 lg:relative lg:z-auto border-t border-gray-200 dark:border-gray-700">
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <button className="flex items-center space-x-2 w-full bg-white dark:bg-gray-800 rounded-xl p-3 shadow-sm border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
                  <User className="w-5 h-5 text-gray-500 dark:text-gray-400 flex-shrink-0" />
                  <span className="text-sm font-medium text-gray-900 dark:text-white truncate text-left">
                    {supabaseUser.name.length > 25 
                      ? `${supabaseUser.name.substring(0, 25)}...` 
                      : supabaseUser.name}
                  </span>
                </button>
              </DropdownMenuTrigger>
              <DropdownMenuContent 
                align="end" 
                className="w-[var(--radix-dropdown-menu-trigger-width)]"
                sideOffset={4}
              >
                <DropdownMenuItem className="cursor-default">
                  <span className="text-sm text-gray-900 dark:text-white break-words">
                    {supabaseUser.name}
                  </span>
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem 
                  onClick={handleSignOutClick}
                  className="cursor-pointer text-red-600 dark:text-red-400 focus:text-red-600 dark:focus:text-red-400"
                >
                  <LogOut className="w-4 h-4 mr-2" />
                  <span>{t('signOut')}</span>
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        )}
      </div>

      {/* Zone de détails de conversation - Style Bento */}
      <div
        className={`${
          showMobileChat ? 'flex' : 'hidden'
        } lg:flex flex-1 flex-col`}
      >
        {shouldShowOnboarding ? (
          <ChatOnboarding onStartChatting={handleStartChatting} />
        ) : (
          children
        )}
      </div>

      {/* Invite Modal */}
      <InviteUserModal
        isOpen={showInviteModal}
        onClose={() => setShowInviteModal(false)}
        isAffiliate={!!supabaseUser?.is_affiliate}
        onConversationCreated={({ conversationId }) => {
          setSelectedChat(conversationId)
          setShowMobileChat(true)
          reload()
          setShowInviteModal(false)
        }}
      />

      {/* Sign Out Modal */}
      <SignOutModal
        isOpen={showSignOutModal}
        onClose={() => setShowSignOutModal(false)}
        onSignOut={handleSignOut}
      />

      {/* Push Notification Prompt */}
      <PushNotificationPrompt />
      
      {/* Subscription Status Popup */}
      <SubscriptionStatusPopup />
    </div>
  )
}

export default function ChatLayout({ children }: Props) {
  return (
    <AuthenticatedLayout>
      <SupabaseUserProvider>
        <PushNotificationsProvider>
        <ChatProvider>
          <ChatLayoutContent>{children}</ChatLayoutContent>
        </ChatProvider>
        </PushNotificationsProvider>
      </SupabaseUserProvider>
    </AuthenticatedLayout>
  )
}
