import { useState, useCallback, useRef } from 'react';
import { TopBar } from '@/components/layout/top-bar';
import { CallSimulator } from '@/components/call-desk/call-simulator';
import { IncomingCallCard } from '@/components/call-desk/incoming-call-card';
import { CallLog } from '@/components/call-desk/call-log';
import { DailyStats } from '@/components/call-desk/daily-stats';
import { useAuth } from '@/providers/auth-provider';
import { useData } from '@/providers/data-provider';
import { useLeads } from '@/hooks/use-leads';
import type { Call, CallDisposition, LeadStatus } from '@/types/entities';

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

const isToday = (dateStr: string): boolean => {
    const d = new Date(dateStr);
    const now = new Date();
    return (
        d.getFullYear() === now.getFullYear() &&
        d.getMonth() === now.getMonth() &&
        d.getDate() === now.getDate()
    );
};

const dispositionToStatus: Partial<Record<CallDisposition, LeadStatus>> = {
    APPOINTMENT_BOOKED: 'APPOINTMENT_SET',
    FOLLOW_UP_SCHEDULED: 'CONTACTED',
    INFO_PROVIDED: 'CONTACTED',
    NO_ANSWER: 'NEW',
    WRONG_NUMBER: 'LOST',
    CALLBACK_REQUESTED: 'LOST',
};

export const CallDeskPage = () => {
    const { user } = useAuth();
    const { calls, leadActivities, campaigns, addCall } = useData();
    const { leads, updateLead } = useLeads();

    const [callState, setCallState] = useState<CallState>('idle');
    const [activeLead, setActiveLead] = useState<ReturnType<typeof useLeads>['leads'][number] | null>(null);
    const [completedDisposition, setCompletedDisposition] = useState<CallDisposition | null>(null);
    const callStartRef = useRef<Date | null>(null);
    const ringingTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
    const completedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

    const todaysCalls = calls.filter(
        (c) => c.agentName === user.name && c.startedAt !== null && isToday(c.startedAt),
    );

    const handleSimulateCall = useCallback(() => {
        if (callState !== 'idle') return;

        // Prefer leads with aiSummary, fall back to any lead
        const leadsWithAi = leads.filter((l) => l.aiSummary !== null);
        const pool = leadsWithAi.length > 0 ? leadsWithAi : leads;
        if (pool.length === 0) return;

        const randomLead = pool[Math.floor(Math.random() * pool.length)];
        setActiveLead(randomLead);
        setCallState('ringing');
        setCompletedDisposition(null);

        ringingTimerRef.current = setTimeout(() => {
            setCallState('active');
            callStartRef.current = new Date();
        }, 1500);
    }, [callState, leads]);

    const handleDisposition = useCallback(
        (disposition: CallDisposition, notes: string) => {
            if (activeLead === null) return;

            const now = new Date();
            const startedAt = callStartRef.current ?? now;
            const durationSeconds = Math.floor((now.getTime() - startedAt.getTime()) / 1000);

            const newCall: Call = {
                id: `call-sim-${Date.now()}`,
                createdAt: startedAt.toISOString(),
                callDirection: 'INBOUND',
                callStatus: 'COMPLETED',
                callerNumber: activeLead.contactPhone,
                agentName: user.name,
                startedAt: startedAt.toISOString(),
                endedAt: now.toISOString(),
                durationSeconds: Math.max(durationSeconds, 60),
                recordingUrl: null,
                disposition,
                callNotes: notes || null,
                patientId: null,
                appointmentId: null,
                leadId: activeLead.id,
                leadName:
                    `${activeLead.contactName?.firstName ?? ''} ${activeLead.contactName?.lastName ?? ''}`.trim() ||
                    'Unknown',
                leadPhone: activeLead.contactPhone?.[0]?.number ?? undefined,
                leadService: activeLead.interestedService ?? undefined,
            };

            addCall(newCall);

            const newStatus = dispositionToStatus[disposition];
            if (newStatus !== undefined) {
                updateLead(activeLead.id, {
                    leadStatus: newStatus,
                    lastContactedAt: now.toISOString(),
                    contactAttempts: (activeLead.contactAttempts ?? 0) + 1,
                });
            }

            setCompletedDisposition(disposition);
            setCallState('completed');

            completedTimerRef.current = setTimeout(() => {
                setCallState('idle');
                setActiveLead(null);
                setCompletedDisposition(null);
            }, 3000);
        },
        [activeLead, user.name, addCall, updateLead],
    );

    return (
        <div className="flex flex-1 flex-col">
            <TopBar title="Call Desk" subtitle={`${user.name} \u00B7 Ramaiah Memorial Hospital`} />

            <div className="flex flex-1 overflow-hidden">
                <div className="flex-1 space-y-5 overflow-y-auto p-7">
                    <CallSimulator
                        onSimulate={handleSimulateCall}
                        isCallActive={callState !== 'idle'}
                    />
                    <IncomingCallCard
                        callState={callState}
                        lead={activeLead}
                        activities={leadActivities}
                        campaigns={campaigns}
                        onDisposition={handleDisposition}
                        completedDisposition={completedDisposition}
                    />
                    <CallLog calls={todaysCalls} />
                </div>

                <aside className="hidden w-72 space-y-5 overflow-y-auto border-l border-secondary bg-primary p-5 xl:block">
                    <DailyStats calls={todaysCalls} />
                </aside>
            </div>
        </div>
    );
};
