import { useCallback, useEffect, useRef, useState } from 'react';
import { disconnectSocket, getSocket } from '@/lib/socket';
import type { CallDisposition } from '@/types/entities';

type CallState = 'idle' | 'ringing' | 'active' | 'completed';

type EnrichedLead = {
    id: string;
    firstName: string;
    lastName: string;
    phone: string;
    email?: string;
    source?: string;
    status?: string;
    campaign?: string;
    interestedService?: string;
    age: number;
    aiSummary?: string;
    aiSuggestedAction?: string;
    recentActivities: { activityType: string; summary: string; occurredAt: string; performedBy: string }[];
};

type IncomingCallEvent = {
    callSid: string;
    eventType: 'ringing' | 'answered' | 'ended';
    lead: EnrichedLead | null;
    callerPhone: string;
    agentName: string;
    timestamp: string;
};

export const useCallEvents = (agentName: string) => {
    const [callState, setCallState] = useState<CallState>('idle');
    const [activeLead, setActiveLead] = useState<EnrichedLead | null>(null);
    const [activeCallSid, setActiveCallSid] = useState<string | null>(null);
    const [callStartTime, setCallStartTime] = useState<string | null>(null);
    const [isConnected, setIsConnected] = useState(false);
    const completedTimerRef = useRef<number | null>(null);

    // Connect to WebSocket and register agent
    useEffect(() => {
        const socket = getSocket();

        socket.on('connect', () => {
            setIsConnected(true);
            socket.emit('agent:register', agentName);
        });

        socket.on('disconnect', () => {
            setIsConnected(false);
        });

        socket.on('agent:registered', (data: { agentName: string }) => {
            console.log(`Registered as agent: ${data.agentName}`);
        });

        socket.on('call:incoming', (event: IncomingCallEvent) => {
            if (event.eventType === 'ringing' || event.eventType === 'answered') {
                setActiveCallSid(event.callSid);
                setActiveLead(event.lead);
                setCallStartTime(event.timestamp);

                if (event.eventType === 'ringing') {
                    setCallState('ringing');
                    // Auto-transition to active after 1.5s (call is answered)
                    setTimeout(() => setCallState('active'), 1500);
                } else {
                    setCallState('active');
                }
            } else if (event.eventType === 'ended') {
                // Call ended from Exotel side (e.g. customer hung up)
                setCallState('completed');
                completedTimerRef.current = window.setTimeout(() => {
                    setCallState('idle');
                    setActiveLead(null);
                    setActiveCallSid(null);
                    setCallStartTime(null);
                }, 3000);
            }
        });

        socket.on('call:disposition:ack', () => {
            // Disposition saved on server
        });

        socket.connect();

        return () => {
            if (completedTimerRef.current) {
                clearTimeout(completedTimerRef.current);
            }
            disconnectSocket();
        };
    }, [agentName]);

    // Send disposition to server
    const sendDisposition = useCallback(
        (disposition: CallDisposition, notes: string) => {
            const socket = getSocket();
            const duration = callStartTime
                ? Math.floor((Date.now() - new Date(callStartTime).getTime()) / 1000)
                : 0;

            socket.emit('call:disposition', {
                callSid: activeCallSid,
                leadId: activeLead?.id ?? null,
                disposition,
                notes,
                agentName,
                callerPhone: activeLead?.phone ?? '',
                startedAt: callStartTime,
                duration,
            });

            setCallState('completed');
            completedTimerRef.current = window.setTimeout(() => {
                setCallState('idle');
                setActiveLead(null);
                setActiveCallSid(null);
                setCallStartTime(null);
            }, 3000);
        },
        [activeCallSid, activeLead, agentName, callStartTime],
    );

    return {
        callState,
        activeLead,
        activeCallSid,
        isConnected,
        sendDisposition,
    };
};
