import { useEffect, useRef, useState } from 'react';
import { io, Socket } from 'socket.io-client';
import { AdminNotification } from '@/types/admin.types';
import { SOCKET_URL } from '@/config/backend';
import { getAccessToken } from '@/components/apis/authApiClients';

interface NotificationCounts {
  total: number;
  unread: number;
  read: number;
}

interface UseNotificationSocketReturn {
  socket: Socket | null;
  isConnected: boolean;
  notificationCounts: NotificationCounts;
  onNewNotification: (callback: (notification: AdminNotification) => void) => void;
  onNotificationRead: (callback: (data: { id: string }) => void) => void;
  onAllNotificationsRead: (callback: () => void) => void;
}

export function useNotificationSocket(): UseNotificationSocketReturn {
  const [socket, setSocket] = useState<Socket | null>(null);
  const [isConnected, setIsConnected] = useState(false);
  const [notificationCounts, setNotificationCounts] = useState<NotificationCounts>({
    total: 0,
    unread: 0,
    read: 0
  });

  const newNotificationCallbackRef = useRef<((notification: AdminNotification) => void) | null>(null);
  const notificationReadCallbackRef = useRef<((data: { id: string }) => void) | null>(null);
  const allNotificationsReadCallbackRef = useRef<(() => void) | null>(null);

  useEffect(() => {
    // Initialize socket connection
    const templateManagerUrl = SOCKET_URL; // connect directly to template-manager socket server
    const token = getAccessToken();
    console.log('[useNotificationSocket] Initializing socket', {
      url: templateManagerUrl,
      hasToken: !!token,
      tokenPreview: token ? token.substring(0, 12) + '...' : null
    });
    const newSocket = io(templateManagerUrl, {
      transports: ['websocket', 'polling'],
      timeout: 20000,
      path: '/socket.io/',
      auth: token ? { token } : undefined,
    });

    newSocket.on('connect', () => {
      console.log('🔌 Connected to notification socket');
      setIsConnected(true);
    });

    newSocket.on('disconnect', () => {
      console.log('🔌 Disconnected from notification socket');
      setIsConnected(false);
    });

    newSocket.on('notification-count', (counts: NotificationCounts) => {
      console.log('📊 Notification counts updated:', counts);
      setNotificationCounts(counts);
    });

    newSocket.on('new-notification', (notification: AdminNotification) => {
      console.log('🔔 New notification received:', notification);
      if (newNotificationCallbackRef.current) {
        newNotificationCallbackRef.current(notification);
      }
    });

    newSocket.on('notification-read', (data: { id: string }) => {
      console.log('✅ Notification marked as read:', data.id);
      if (notificationReadCallbackRef.current) {
        notificationReadCallbackRef.current(data);
      }
    });

    newSocket.on('all-notifications-read', () => {
      console.log('✅ All notifications marked as read');
      if (allNotificationsReadCallbackRef.current) {
        allNotificationsReadCallbackRef.current();
      }
    });

    newSocket.on('connect_error', (error: any) => {
      console.error('🔌 Socket connection error:', {
        message: error?.message,
        name: error?.name,
        data: error?.data
      });
      setIsConnected(false);
    });

    setSocket(newSocket);

    return () => {
      newSocket.close();
    };
  }, []);

  const onNewNotification = (callback: (notification: AdminNotification) => void) => {
    newNotificationCallbackRef.current = callback;
  };

  const onNotificationRead = (callback: (data: { id: string }) => void) => {
    notificationReadCallbackRef.current = callback;
  };

  const onAllNotificationsRead = (callback: () => void) => {
    allNotificationsReadCallbackRef.current = callback;
  };

  return {
    socket,
    isConnected,
    notificationCounts,
    onNewNotification,
    onNotificationRead,
    onAllNotificationsRead,
  };
}
