import { useEffect, useState } from 'react';
import { getSocket, joinRequestRoom, leaveRequestRoom } from '@/utils/socket';
import { getWorkNotes } from '@/services/workflowApi';
import workflowApi from '@/services/workflowApi';

/**
 * Custom Hook: useRequestSocket
 * 
 * Purpose: Manages real-time WebSocket connection for request updates
 * 
 * Responsibilities:
 * - Establishes socket connection for the request
 * - Joins/leaves request-specific room
 * - Listens for new work notes in real-time
 * - Listens for TAT alerts and updates
 * - Merges work notes with activity timeline
 * - Manages unread work notes badge
 * - Handles socket cleanup on unmount
 * 
 * @param requestIdentifier - Request number or UUID
 * @param apiRequest - Current request data object
 * @param activeTab - Currently active tab
 * @param user - Current authenticated user
 * @returns Object with merged messages, unread count, and work note attachments
 */
export function useRequestSocket(
  requestIdentifier: string,
  apiRequest: any,
  activeTab: string,
  user: any
) {
  // State: Merged array of work notes and activities, sorted chronologically
  const [mergedMessages, setMergedMessages] = useState<any[]>([]);
  
  // State: Count of unread work notes (shows badge on Work Notes tab)
  const [unreadWorkNotes, setUnreadWorkNotes] = useState(0);
  
  // State: Attachments extracted from work notes for Documents tab
  const [workNoteAttachments, setWorkNoteAttachments] = useState<any[]>([]);

  /**
   * Effect: Establish socket connection and join request room
   * 
   * Process:
   * 1. Resolve UUID from request number if needed
   * 2. Initialize socket connection
   * 3. Join request-specific room (makes user "online" for this request)
   * 4. Cleanup on unmount (leave room, remove listeners)
   */
  useEffect(() => {
    if (!requestIdentifier) {
      console.warn('[useRequestSocket] No requestIdentifier, cannot join socket room');
      return;
    }
    
    // Socket connection initialized - logging removed
    
    let mounted = true;
    let actualRequestId = requestIdentifier;
    
    (async () => {
      try {
        // API Call: Fetch UUID if we have request number (socket rooms use UUID)
        const details = await workflowApi.getWorkflowDetails(requestIdentifier);
        if (details?.workflow?.requestId && mounted) {
          actualRequestId = details.workflow.requestId;
          // UUID resolved - logging removed
        }
      } catch (error) {
        console.error('[useRequestSocket] Failed to resolve UUID:', error);
      }
      
      if (!mounted) return;
      
      // Initialize: Get socket instance with base URL
      const socket = getSocket(); // Uses getSocketBaseUrl() helper internally
      
      if (!socket) {
        console.error('[useRequestSocket] Socket not available');
        return;
      }
      
      const userId = (user as any)?.userId;
      
      /**
       * Handler: Join request room when socket connects
       * This makes the user "online" for this specific request
       */
      const handleConnect = () => {
        // Socket connected - joining room
        joinRequestRoom(socket, actualRequestId, userId);
      };
      
      // Join immediately if already connected, otherwise wait for connect event
      if (socket.connected) {
        handleConnect();
      } else {
        socket.on('connect', handleConnect);
      }
      
      /**
       * Cleanup: Leave room and remove listeners when component unmounts
       * This marks user as "offline" for this request
       */
      return () => {
        if (mounted) {
          socket.off('connect', handleConnect);
          leaveRequestRoom(socket, actualRequestId);
          // Left room - logging removed
        }
      };
    })();
    
    return () => { mounted = false; };
  }, [requestIdentifier, user]);
  
  /**
   * Effect: Fetch and merge work notes with activities for timeline display
   * 
   * Purpose: Combine work notes (real-time chat) with audit trail (system events)
   * to create a unified timeline view
   */
  useEffect(() => {
    if (!requestIdentifier || !apiRequest) return;
    
    (async () => {
      try {
        // Fetch: Get all work notes for this request
        const workNotes = await getWorkNotes(requestIdentifier);
        const activities = apiRequest.auditTrail || [];
        
        // Merge: Combine work notes and activities
        const merged = [...workNotes, ...activities];
        
        // Sort: Order by timestamp (oldest to newest)
        merged.sort((a, b) => {
          const timeA = new Date(a.createdAt || a.created_at || a.timestamp || 0).getTime();
          const timeB = new Date(b.createdAt || b.created_at || b.timestamp || 0).getTime();
          return timeA - timeB;
        });
        
        setMergedMessages(merged);
        // Messages merged - logging removed
      } catch (error) {
        console.error('[useRequestSocket] Failed to fetch and merge messages:', error);
      }
    })();
  }, [requestIdentifier, apiRequest]);
  
  /**
   * Effect: Listen for real-time work notes and TAT alerts via WebSocket
   * 
   * Listens for:
   * 1. 'noteHandler' / 'worknote:new' - New work note added
   * 2. 'tat:alert' - TAT threshold reached or deadline breached
   */
  useEffect(() => {
    if (!requestIdentifier) return;
    
    // Get socket using helper function (handles VITE_BASE_URL or VITE_API_BASE_URL)
    const socket = getSocket(); // Uses getSocketBaseUrl() helper internally
    
    if (!socket) return;
    
    /**
     * Handler: New work note received via WebSocket
     * 
     * Actions:
     * 1. Increment unread badge if user is not on Work Notes tab
     * 2. Refresh merged messages to show new note
     */
    const handleNewWorkNote = (_data: any) => {
      // New work note received - logging removed
      
      // Update unread badge (only if not viewing work notes)
      if (activeTab !== 'worknotes') {
        setUnreadWorkNotes(prev => prev + 1);
      }
      
      // Refresh: Re-fetch and merge messages to include new work note
      (async () => {
        try {
          const workNotes = await getWorkNotes(requestIdentifier);
          const activities = apiRequest?.auditTrail || [];
          const merged = [...workNotes, ...activities].sort((a, b) => {
            const timeA = new Date(a.createdAt || a.created_at || a.timestamp || 0).getTime();
            const timeB = new Date(b.createdAt || b.created_at || b.timestamp || 0).getTime();
            return timeA - timeB;
          });
          setMergedMessages(merged);
        } catch (error) {
          console.error('[useRequestSocket] Failed to refresh messages:', error);
        }
      })();
    };
    
    /**
     * Handler: TAT alert received via WebSocket
     * 
     * Triggered when:
     * - 50% TAT threshold reached
     * - 75% TAT threshold reached
     * - 100% TAT deadline breached
     * 
     * Actions:
     * 1. Show console notification with emoji indicator
     * 2. Refresh request data to get updated TAT alerts
     * 3. Show browser notification if permission granted
     */
    const handleTatAlert = (data: any) => {
      const alertEmoji = data.type === 'breach' ? '⏰' : data.type === 'threshold2' ? '⚠️' : '⏳';
      
      // Refresh: Get updated TAT alerts from backend
      (async () => {
        try {
          const details = await workflowApi.getWorkflowDetails(requestIdentifier);
          
          if (details) {
            // Extract TAT alerts for potential future use
            void (Array.isArray(details.tatAlerts) ? details.tatAlerts : []);
            
            // Browser notification (if user granted permission)
            if ('Notification' in window && Notification.permission === 'granted') {
              new Notification(`${alertEmoji} TAT Alert`, {
                body: data.message,
                icon: '/favicon.ico',
                tag: `tat-${data.requestId}-${data.type}`,
                requireInteraction: false
              });
            }
          }
        } catch (error) {
          console.error('[useRequestSocket] Failed to refresh after TAT alert:', error);
        }
      })();
    };
    
    // Register: Add event listeners for real-time updates
    socket.on('noteHandler', handleNewWorkNote);
    socket.on('worknote:new', handleNewWorkNote);
    socket.on('tat:alert', handleTatAlert);
    
    /**
     * Cleanup: Remove event listeners when component unmounts or dependencies change
     * Prevents memory leaks and duplicate listeners
     */
    return () => {
      socket.off('noteHandler', handleNewWorkNote);
      socket.off('worknote:new', handleNewWorkNote);
      socket.off('tat:alert', handleTatAlert);
    };
  }, [requestIdentifier, activeTab, apiRequest]);
  
  /**
   * Effect: Reset unread count when user switches to Work Notes tab
   * User has seen the messages, so clear the badge
   */
  useEffect(() => {
    if (activeTab === 'worknotes') {
      setUnreadWorkNotes(0);
    }
  }, [activeTab]);

  return {
    mergedMessages,
    unreadWorkNotes,
    workNoteAttachments,
    setWorkNoteAttachments
  };
}

