import { useCallback, useEffect, useRef, useState } from 'react';
import { SIPClient } from '@/lib/sip-client';
import type { SIPConfig, ConnectionStatus, CallState } from '@/types/sip';

const DEFAULT_CONFIG: SIPConfig = {
    displayName: import.meta.env.VITE_SIP_DISPLAY_NAME ?? 'Helix Agent',
    uri: import.meta.env.VITE_SIP_URI ?? '',
    password: import.meta.env.VITE_SIP_PASSWORD ?? '',
    wsServer: import.meta.env.VITE_SIP_WS_SERVER ?? '',
    stunServers: 'stun:stun.l.google.com:19302',
};

export const useSipPhone = (config?: Partial<SIPConfig>) => {
    const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>('disconnected');
    const [callState, setCallState] = useState<CallState>('idle');
    const [callerNumber, setCallerNumber] = useState<string | null>(null);
    const [isMuted, setIsMuted] = useState(false);
    const [isOnHold, setIsOnHold] = useState(false);
    const [callDuration, setCallDuration] = useState(0);
    const [callStartTime, setCallStartTime] = useState<Date | null>(null);

    const sipClientRef = useRef<SIPClient | null>(null);
    const durationIntervalRef = useRef<number | null>(null);

    // Call duration timer
    useEffect(() => {
        if (callState === 'active' && !callStartTime) {
            setCallStartTime(new Date());
        }

        if (callState === 'active') {
            durationIntervalRef.current = window.setInterval(() => {
                if (callStartTime) {
                    setCallDuration(Math.floor((Date.now() - callStartTime.getTime()) / 1000));
                }
            }, 1000);
        } else if (callState === 'idle' || callState === 'ended' || callState === 'failed') {
            if (durationIntervalRef.current) {
                clearInterval(durationIntervalRef.current);
                durationIntervalRef.current = null;
            }
            setCallDuration(0);
            setCallStartTime(null);
        }

        return () => {
            if (durationIntervalRef.current) {
                clearInterval(durationIntervalRef.current);
            }
        };
    }, [callState, callStartTime]);

    // Auto-reset to idle after ended/failed
    useEffect(() => {
        if (callState === 'ended' || callState === 'failed') {
            const timer = setTimeout(() => {
                setCallState('idle');
                setCallerNumber(null);
                setIsMuted(false);
                setIsOnHold(false);
            }, 2000);
            return () => clearTimeout(timer);
        }
    }, [callState]);

    const connect = useCallback(() => {
        const mergedConfig = { ...DEFAULT_CONFIG, ...config };

        if (!mergedConfig.wsServer || !mergedConfig.uri) {
            console.warn('SIP config incomplete — wsServer and uri required');
            return;
        }

        // Don't reconnect if already connected or connecting
        if (sipClientRef.current?.isConnected() || sipClientRef.current?.isRegistered()) {
            return;
        }

        if (sipClientRef.current) {
            sipClientRef.current.disconnect();
        }

        setConnectionStatus('connecting');

        const client = new SIPClient(
            mergedConfig,
            (status) => setConnectionStatus(status),
            (state, number) => {
                setCallState(state);
                if (number) setCallerNumber(number);
            },
        );

        sipClientRef.current = client;
        client.connect();
    }, [config]);

    const disconnect = useCallback(() => {
        sipClientRef.current?.disconnect();
        sipClientRef.current = null;
        setConnectionStatus('disconnected');
    }, []);

    const makeCall = useCallback((phoneNumber: string) => {
        sipClientRef.current?.call(phoneNumber);
        setCallerNumber(phoneNumber);
    }, []);

    const answer = useCallback(() => {
        sipClientRef.current?.answer();
    }, []);

    const reject = useCallback(() => {
        sipClientRef.current?.reject();
    }, []);

    const hangup = useCallback(() => {
        sipClientRef.current?.hangup();
    }, []);

    const toggleMute = useCallback(() => {
        if (isMuted) {
            sipClientRef.current?.unmute();
        } else {
            sipClientRef.current?.mute();
        }
        setIsMuted(!isMuted);
    }, [isMuted]);

    const toggleHold = useCallback(() => {
        if (isOnHold) {
            sipClientRef.current?.unhold();
        } else {
            sipClientRef.current?.hold();
        }
        setIsOnHold(!isOnHold);
    }, [isOnHold]);

    // Cleanup only on actual page unload, not StrictMode remount
    useEffect(() => {
        const handleUnload = () => {
            sipClientRef.current?.disconnect();
        };
        window.addEventListener('beforeunload', handleUnload);
        return () => {
            window.removeEventListener('beforeunload', handleUnload);
        };
    }, []);

    return {
        // State
        connectionStatus,
        callState,
        callerNumber,
        isMuted,
        isOnHold,
        callDuration,
        isRegistered: connectionStatus === 'registered',
        isInCall: ['ringing-in', 'ringing-out', 'active'].includes(callState),

        // Actions
        connect,
        disconnect,
        makeCall,
        answer,
        reject,
        hangup,
        toggleMute,
        toggleHold,
    };
};
