import { useEffect, useRef, useState, useCallback } from 'react';
import { getShoppingListSyncSocketUrl } from '@/services/shopping-lists';

export interface SyncUpdateMessage {
  type: 'ITEM_ADDED' | 'ITEM_UPDATED' | 'ITEM_REMOVED';
  itemId?: string;
  item?: any;
  updates?: any;
}

export function useShoppingListSync(
  householdId: string,
  listId: string,
  onRemoteChange: (msg: SyncUpdateMessage) => void
) {
  const socketRef = useRef<WebSocket | null>(null);
  const [isConnected, setIsConnected] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const reconnectAttemptsRef = useRef(0);

  const connect = useCallback(() => {
    if (!householdId || !listId) return;

    // Close previous socket if active
    if (socketRef.current) {
      socketRef.current.close();
    }

    try {
      const url = getShoppingListSyncSocketUrl(householdId, listId);
      const ws = new WebSocket(url);
      socketRef.current = ws;

      ws.onopen = () => {
        setIsConnected(true);
        setError(null);
        reconnectAttemptsRef.current = 0;
        console.log(`🛒 Connected to shopping list real-time sync: ${listId}`);
      };

      ws.onmessage = (event) => {
        try {
          const payload: SyncUpdateMessage = JSON.parse(event.data);
          onRemoteChange(payload);
        } catch (err) {
          console.error('Failed parsing real-time grocery payload', err);
        }
      };

      ws.onerror = () => {
        setError('Connection interrupt');
      };

      ws.onclose = (event) => {
        setIsConnected(false);
        console.log(`🔌 Sync severed: ${event.reason || 'Disconnected'}`);
        
        // Simple linear backoff reconnect
        if (reconnectAttemptsRef.current < 5) {
          reconnectAttemptsRef.current += 1;
          const delay = Math.min(1000 * reconnectAttemptsRef.current, 5000);
          setTimeout(() => {
            console.log(`🔄 Attempting sync handshake reconnect (${reconnectAttemptsRef.current}/5)...`);
            connect();
          }, delay);
        }
      };
    } catch (err) {
      console.error('Fatal WebSocket initialization', err);
      setError('Sync failed to initialize');
    }
  }, [householdId, listId, onRemoteChange]);

  useEffect(() => {
    connect();
    return () => {
      if (socketRef.current) {
        // Clear hook handlers to prevent state leakage during dismount
        socketRef.current.onclose = null; 
        socketRef.current.close();
      }
    };
  }, [connect]);

  const toggleItemCheck = useCallback((itemId: string, checked: boolean) => {
    if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) {
      socketRef.current.send(
        JSON.stringify({
          type: 'TOGGLE_ITEM',
          itemId,
          checked,
        })
      );
    }
  }, []);

  return {
    isConnected,
    error,
    toggleItemCheck,
  };
}
