'use client';

import { useEffect, useCallback, useState } from 'react';
import { useSupabaseUser } from '@/app/contexts/SupabaseUserContext';
import { supabase } from '@/lib/supabase';
import { socket } from '@/lib/socket';

export const useUserPresence = () => {
  const { supabaseUser, supabaseUserId } = useSupabaseUser();
  const [presenceByUserId, setPresenceByUserId] = useState<Record<string, 'online' | 'offline' | 'away'>>({});

  // Mettre à jour le statut utilisateur
  const updateUserStatus = useCallback(async (status: 'online' | 'offline' | 'away', userId: string) => {
    try {
      await supabase
        .from('users')
        .update({
          status,
          last_seen: new Date().toISOString(),
          updated_at: new Date().toISOString()
        })
        .eq('id', userId);

      // Diffuser le changement de statut via Socket.IO
      if (socket.connected) {
        socket.emit('user-status-change', {
          userId,
          status,
          lastSeen: new Date().toISOString()
        });
      }
    } catch (error) {
      console.error('Error updating user status:', error);
    }
  }, []);

  // Mise à jour périodique de last_seen (toutes les 30 secondes)
  useEffect(() => {
    if (!supabaseUserId) return;

    const interval = setInterval(async () => {
      try {
        await supabase
          .from('users')
          .update({ last_seen: new Date().toISOString() })
          .eq('id', supabaseUserId);
      } catch (err) {
        console.error('Error updating last_seen:', err);
      }
    }, 30000); // 30 secondes

    return () => clearInterval(interval);
  }, [supabaseUserId]);

  // Marquer en ligne à la connexion
  useEffect(() => {
    if (!supabaseUserId) return;

    updateUserStatus('online', supabaseUserId);

    return () => {
      if (supabaseUserId) {
        updateUserStatus('offline', supabaseUserId);
      }
    };
  }, [supabaseUserId, updateUserStatus]);

  // Marquer offline à la déconnexion (beforeunload)
  useEffect(() => {
    const handleBeforeUnload = () => {
      if (supabaseUserId) {
        // Utiliser sendBeacon pour garantir l'envoi même à la fermeture
        navigator.sendBeacon('/api/chat/user-status', JSON.stringify({
          userId: supabaseUserId,
          status: 'offline'
        }));
      }
    };

    window.addEventListener('beforeunload', handleBeforeUnload);

    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
      if (supabaseUserId) {
        updateUserStatus('offline', supabaseUserId);
      }
    };
  }, [supabaseUserId, updateUserStatus]);

  // Écouter les changements de statut d'autres utilisateurs via Socket.IO
  useEffect(() => {
    if (!socket.connected) {
      socket.connect();
    }

    const handleStatusUpdate = (data: { userId: string; status: 'online' | 'offline' | 'away'; lastSeen: string }) => {
      setPresenceByUserId(prev => ({ ...prev, [data.userId]: data.status }));
    };

    // Compatibilité avec différents noms d'événements
    socket.on('user-status-updated', handleStatusUpdate);
    socket.on('user-status-change', handleStatusUpdate);

    return () => {
      socket.off('user-status-updated', handleStatusUpdate);
      socket.off('user-status-change', handleStatusUpdate);
    };
  }, []);

  // Abonnement Supabase Realtime aux changements sur la table users
  useEffect(() => {
    const channel = supabase
      .channel('users-presence')
      .on(
        'postgres_changes',
        { event: 'UPDATE', schema: 'public', table: 'users' },
        (payload: any) => {
          const newRow = payload.new as { id: string; status?: 'online' | 'offline' | 'away' };
          if (newRow && typeof newRow.id === 'string' && newRow.status) {
            const status = newRow.status as 'online' | 'offline' | 'away';
            setPresenceByUserId(prev => ({ ...prev, [newRow.id]: status }));
          }
        }
      )
      .subscribe();

    return () => {
      supabase.removeChannel(channel);
    };
  }, []);

  return {
    supabaseUserId,
    updateUserStatus,
    presenceByUserId
  };
};

