import { useState, useEffect, useRef } from 'react';
import {
    faPhone,
    faPhoneArrowDown,
    faPhoneArrowUp,
    faPhoneHangup,
    faPhoneXmark,
    faMicrophoneSlash,
    faMicrophone,
    faPause,
    faCircleCheck,
    faFloppyDisk,
    faCalendarPlus,
} from '@fortawesome/pro-duotone-svg-icons';
import { faIcon } from '@/lib/icon-wrapper';

const Phone01 = faIcon(faPhone);
const PhoneIncoming01 = faIcon(faPhoneArrowDown);
const PhoneOutgoing01 = faIcon(faPhoneArrowUp);
const PhoneHangUp = faIcon(faPhoneHangup);
const PhoneX = faIcon(faPhoneXmark);
const MicrophoneOff01 = faIcon(faMicrophoneSlash);
const Microphone01 = faIcon(faMicrophone);
const PauseCircle = faIcon(faPause);
const CheckCircle = faIcon(faCircleCheck);
const Save01 = faIcon(faFloppyDisk);
const CalendarPlus02 = faIcon(faCalendarPlus);
import { Button } from '@/components/base/buttons/button';
import { TextArea } from '@/components/base/textarea/textarea';
import { AppointmentForm } from '@/components/call-desk/appointment-form';
import { useSip } from '@/providers/sip-provider';
import { useAuth } from '@/providers/auth-provider';
import { cx } from '@/utils/cx';
import type { CallDisposition } from '@/types/entities';

const formatDuration = (seconds: number): string => {
    const m = Math.floor(seconds / 60)
        .toString()
        .padStart(2, '0');
    const s = (seconds % 60).toString().padStart(2, '0');
    return `${m}:${s}`;
};

const statusDotColor: Record<string, string> = {
    registered: 'bg-success-500',
    connecting: 'bg-warning-500',
    disconnected: 'bg-quaternary',
    error: 'bg-error-500',
};

const statusLabel: Record<string, string> = {
    registered: 'Ready',
    connecting: 'Connecting...',
    disconnected: 'Offline',
    error: 'Error',
};

const dispositionOptions: Array<{
    value: CallDisposition;
    label: string;
    activeClass: string;
    defaultClass: string;
}> = [
    {
        value: 'APPOINTMENT_BOOKED',
        label: 'Appt Booked',
        activeClass: 'bg-success-solid text-white ring-transparent',
        defaultClass: 'bg-success-primary text-success-primary border-success',
    },
    {
        value: 'FOLLOW_UP_SCHEDULED',
        label: 'Follow-up',
        activeClass: 'bg-brand-solid text-white ring-transparent',
        defaultClass: 'bg-brand-primary text-brand-secondary border-brand',
    },
    {
        value: 'INFO_PROVIDED',
        label: 'Info Given',
        activeClass: 'bg-utility-blue-light-600 text-white ring-transparent',
        defaultClass: 'bg-utility-blue-light-50 text-utility-blue-light-700 border-utility-blue-light-200',
    },
    {
        value: 'NO_ANSWER',
        label: 'No Answer',
        activeClass: 'bg-warning-solid text-white ring-transparent',
        defaultClass: 'bg-warning-primary text-warning-primary border-warning',
    },
    {
        value: 'WRONG_NUMBER',
        label: 'Wrong #',
        activeClass: 'bg-secondary-solid text-white ring-transparent',
        defaultClass: 'bg-secondary text-secondary border-secondary',
    },
    {
        value: 'CALLBACK_REQUESTED',
        label: 'Not Interested',
        activeClass: 'bg-error-solid text-white ring-transparent',
        defaultClass: 'bg-error-primary text-error-primary border-error',
    },
];

export const CallWidget = () => {
    const {
        connectionStatus,
        callState,
        callerNumber,
        isMuted,
        isOnHold,
        callDuration,
        answer,
        reject,
        hangup,
        toggleMute,
        toggleHold,
    } = useSip();
    const { user } = useAuth();

    const [disposition, setDisposition] = useState<CallDisposition | null>(null);
    const [notes, setNotes] = useState('');
    const [lastDuration, setLastDuration] = useState(0);
    const [matchedLead, setMatchedLead] = useState<any>(null);
    const [leadActivities, setLeadActivities] = useState<any[]>([]);
    const [isSaving, setIsSaving] = useState(false);
    const [isAppointmentOpen, setIsAppointmentOpen] = useState(false);
    const callStartTimeRef = useRef<string | null>(null);

    // Capture duration right before call ends
    useEffect(() => {
        if (callState === 'active' && callDuration > 0) {
            setLastDuration(callDuration);
        }
    }, [callState, callDuration]);

    // Track call start time
    useEffect(() => {
        if (callState === 'active' && !callStartTimeRef.current) {
            callStartTimeRef.current = new Date().toISOString();
        }
        if (callState === 'idle') {
            callStartTimeRef.current = null;
        }
    }, [callState]);

    // Look up caller when call becomes active
    useEffect(() => {
        if (callState === 'ringing-in' && callerNumber && callerNumber !== 'Unknown') {
            const lookup = async () => {
                try {
                    const { apiClient } = await import('@/lib/api-client');
                    const token = apiClient.getStoredToken();
                    if (!token) return;

                    const API_URL = import.meta.env.VITE_API_URL ?? 'http://localhost:4100';
                    const res = await fetch(`${API_URL}/api/call/lookup`, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'Authorization': `Bearer ${token}`,
                        },
                        body: JSON.stringify({ phoneNumber: callerNumber }),
                    });
                    const data = await res.json();
                    if (data.matched && data.lead) {
                        setMatchedLead(data.lead);
                        setLeadActivities(data.activities ?? []);
                    }
                } catch (err) {
                    console.warn('Lead lookup failed:', err);
                }
            };
            lookup();
        }
    }, [callState, callerNumber]);

    // Reset state when returning to idle
    useEffect(() => {
        if (callState === 'idle') {
            setDisposition(null);
            setNotes('');
            setMatchedLead(null);
            setLeadActivities([]);
        }
    }, [callState]);

    const handleSaveAndClose = async () => {
        if (!disposition) return;
        setIsSaving(true);

        try {
            const { apiClient } = await import('@/lib/api-client');

            // 1. Create Call record on platform
            await apiClient.graphql(
                `mutation CreateCall($data: CallCreateInput!) {
                    createCall(data: $data) { id }
                }`,
                {
                    data: {
                        callDirection: 'INBOUND',
                        callStatus: 'COMPLETED',
                        agentName: user.name,
                        startedAt: callStartTimeRef.current,
                        endedAt: new Date().toISOString(),
                        durationSeconds: callDuration,
                        disposition,
                        callNotes: notes || null,
                        leadId: matchedLead?.id ?? null,
                    },
                },
            ).catch(err => console.warn('Failed to create call record:', err));

            // 2. Update lead status if matched
            if (matchedLead?.id) {
                const statusMap: Partial<Record<string, string>> = {
                    APPOINTMENT_BOOKED: 'APPOINTMENT_SET',
                    FOLLOW_UP_SCHEDULED: 'CONTACTED',
                    INFO_PROVIDED: 'CONTACTED',
                    NO_ANSWER: 'CONTACTED',
                    WRONG_NUMBER: 'LOST',
                    CALLBACK_REQUESTED: 'CONTACTED',
                    NOT_INTERESTED: 'LOST',
                };
                const newStatus = statusMap[disposition];
                if (newStatus) {
                    await apiClient.graphql(
                        `mutation UpdateLead($id: ID!, $data: LeadUpdateInput!) {
                            updateLead(id: $id, data: $data) { id }
                        }`,
                        {
                            id: matchedLead.id,
                            data: {
                                leadStatus: newStatus,
                                lastContactedAt: new Date().toISOString(),
                            },
                        },
                    ).catch(err => console.warn('Failed to update lead:', err));
                }

                // 3. Create lead activity
                await apiClient.graphql(
                    `mutation CreateLeadActivity($data: LeadActivityCreateInput!) {
                        createLeadActivity(data: $data) { id }
                    }`,
                    {
                        data: {
                            activityType: 'CALL_RECEIVED',
                            summary: `Inbound call — ${disposition.replace(/_/g, ' ')}`,
                            occurredAt: new Date().toISOString(),
                            performedBy: user.name,
                            channel: 'PHONE',
                            durationSeconds: callDuration,
                            leadId: matchedLead.id,
                        },
                    },
                ).catch(err => console.warn('Failed to create activity:', err));
            }
        } catch (err) {
            console.error('Save failed:', err);
        }

        setIsSaving(false);
        hangup();
        setDisposition(null);
        setNotes('');
    };

    const dotColor = statusDotColor[connectionStatus] ?? 'bg-quaternary';
    const label = statusLabel[connectionStatus] ?? connectionStatus;

    // Idle: collapsed pill
    if (callState === 'idle') {
        return (
            <div
                className={cx(
                    'fixed bottom-6 right-6 z-50',
                    'inline-flex items-center gap-2 rounded-full border border-secondary bg-primary px-4 py-2.5 shadow-lg',
                    'transition-all duration-300',
                )}
            >
                <span className={cx('size-2.5 shrink-0 rounded-full', dotColor)} />
                <span className="text-sm font-semibold text-secondary">{label}</span>
                <span className="text-sm text-tertiary">Helix Phone</span>
            </div>
        );
    }

    // Ringing inbound
    if (callState === 'ringing-in') {
        return (
            <div
                className={cx(
                    'fixed bottom-6 right-6 z-50 w-80',
                    'flex flex-col items-center gap-5 rounded-2xl border border-secondary bg-primary p-6 shadow-2xl',
                    'transition-all duration-300',
                )}
            >
                <div className="relative">
                    <div className="absolute inset-0 animate-ping rounded-full bg-brand-solid opacity-20" />
                    <div className="relative animate-bounce">
                        <PhoneIncoming01 className="size-10 text-fg-brand-primary" />
                    </div>
                </div>

                <div className="flex flex-col items-center gap-1">
                    <span className="text-xs font-bold uppercase tracking-wider text-brand-secondary">
                        Incoming Call
                    </span>
                    <span className="text-lg font-bold text-primary">{callerNumber ?? 'Unknown'}</span>
                </div>

                <div className="flex items-center gap-3">
                    <Button size="md" color="primary" iconLeading={Phone01} onClick={answer}>
                        Answer
                    </Button>
                    <Button size="md" color="primary-destructive" iconLeading={PhoneX} onClick={reject}>
                        Decline
                    </Button>
                </div>
            </div>
        );
    }

    // Ringing outbound
    if (callState === 'ringing-out') {
        return (
            <div
                className={cx(
                    'fixed bottom-6 right-6 z-50 w-80',
                    'flex flex-col items-center gap-5 rounded-2xl border border-secondary bg-primary p-6 shadow-2xl',
                    'transition-all duration-300',
                )}
            >
                <PhoneOutgoing01 className="size-10 animate-pulse text-fg-brand-primary" />

                <div className="flex flex-col items-center gap-1">
                    <span className="text-xs font-bold uppercase tracking-wider text-brand-secondary">
                        Calling...
                    </span>
                    <span className="text-lg font-bold text-primary">{callerNumber ?? 'Unknown'}</span>
                </div>

                <Button size="md" color="primary-destructive" iconLeading={PhoneHangUp} onClick={hangup}>
                    Cancel
                </Button>
            </div>
        );
    }

    // Active call (full widget)
    if (callState === 'active') {
        return (
            <div
                className={cx(
                    'fixed bottom-6 right-6 z-50 w-80',
                    'flex flex-col gap-4 rounded-2xl border border-secondary bg-primary p-5 shadow-2xl',
                    'transition-all duration-300',
                )}
            >
                {/* Header */}
                <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                        <Phone01 className="size-4 text-fg-success-primary" />
                        <span className="text-sm font-semibold text-primary">Active Call</span>
                    </div>
                    <span className="font-mono text-sm font-bold tabular-nums text-brand-secondary">
                        {formatDuration(callDuration)}
                    </span>
                </div>

                {/* Caller info */}
                <div>
                    <span className="text-lg font-bold text-primary">
                        {matchedLead?.contactName
                            ? `${matchedLead.contactName.firstName ?? ''} ${matchedLead.contactName.lastName ?? ''}`.trim()
                            : callerNumber ?? 'Unknown'}
                    </span>
                    {matchedLead && (
                        <span className="ml-2 text-sm text-tertiary">{callerNumber}</span>
                    )}
                </div>

                {/* AI Summary */}
                {matchedLead?.aiSummary && (
                    <div className="rounded-xl bg-brand-primary p-3">
                        <div className="mb-1 text-xs font-bold uppercase tracking-wider text-brand-secondary">AI Insight</div>
                        <p className="text-sm text-primary">{matchedLead.aiSummary}</p>
                        {matchedLead.aiSuggestedAction && (
                            <span className="mt-2 inline-block rounded-lg bg-brand-solid px-3 py-1 text-xs font-semibold text-white">
                                {matchedLead.aiSuggestedAction}
                            </span>
                        )}
                    </div>
                )}

                {/* Recent activity */}
                {leadActivities.length > 0 && (
                    <div className="space-y-1">
                        <div className="text-xs font-semibold text-tertiary">Recent Activity</div>
                        {leadActivities.slice(0, 3).map((a: any, i: number) => (
                            <div key={i} className="text-xs text-quaternary">
                                {a.activityType?.replace(/_/g, ' ')}: {a.summary}
                            </div>
                        ))}
                    </div>
                )}

                {/* Call controls */}
                <div className="flex items-center gap-2">
                    <Button
                        size="sm"
                        color={isMuted ? 'primary' : 'secondary'}
                        iconLeading={isMuted ? MicrophoneOff01 : Microphone01}
                        onClick={toggleMute}
                    >
                        {isMuted ? 'Unmute' : 'Mute'}
                    </Button>
                    <Button
                        size="sm"
                        color={isOnHold ? 'primary' : 'secondary'}
                        iconLeading={PauseCircle}
                        onClick={toggleHold}
                    >
                        {isOnHold ? 'Resume' : 'Hold'}
                    </Button>
                    <Button size="sm" color="primary-destructive" iconLeading={PhoneHangUp} onClick={hangup}>
                        End
                    </Button>
                </div>

                {/* Book Appointment */}
                <Button
                    size="sm"
                    color="primary"
                    iconLeading={CalendarPlus02}
                    onClick={() => setIsAppointmentOpen(true)}
                    className="w-full"
                >
                    Book Appointment
                </Button>

                <AppointmentForm
                    isOpen={isAppointmentOpen}
                    onOpenChange={setIsAppointmentOpen}
                    callerNumber={callerNumber}
                    leadName={matchedLead ? `${matchedLead.contactName?.firstName ?? ''} ${matchedLead.contactName?.lastName ?? ''}`.trim() : null}
                    leadId={matchedLead?.id}
                    onSaved={() => {
                        setIsAppointmentOpen(false);
                        setDisposition('APPOINTMENT_BOOKED');
                    }}
                />

                {/* Divider */}
                <div className="border-t border-secondary" />

                {/* Disposition */}
                <div className="flex flex-col gap-2.5">
                    <span className="text-xs font-bold uppercase tracking-wider text-secondary">Disposition</span>
                    <div className="grid grid-cols-2 gap-1.5">
                        {dispositionOptions.map((opt) => {
                            const isSelected = disposition === opt.value;
                            return (
                                <button
                                    key={opt.value}
                                    type="button"
                                    onClick={() => setDisposition(opt.value)}
                                    className={cx(
                                        'cursor-pointer rounded-lg border px-2.5 py-1.5 text-xs font-semibold transition duration-100 ease-linear',
                                        isSelected ? cx(opt.activeClass, 'ring-2 ring-brand') : opt.defaultClass,
                                    )}
                                >
                                    {opt.label}
                                </button>
                            );
                        })}
                    </div>

                    <TextArea
                        placeholder="Add notes..."
                        value={notes}
                        onChange={(value) => setNotes(value)}
                        rows={2}
                        textAreaClassName="text-xs"
                    />

                    <Button
                        size="sm"
                        color="primary"
                        iconLeading={Save01}
                        isDisabled={disposition === null || isSaving}
                        isLoading={isSaving}
                        onClick={handleSaveAndClose}
                        className="w-full"
                    >
                        {isSaving ? 'Saving...' : 'Save & Close'}
                    </Button>
                </div>
            </div>
        );
    }

    // Ended / Failed
    if (callState === 'ended' || callState === 'failed') {
        const isEnded = callState === 'ended';
        return (
            <div
                className={cx(
                    'fixed bottom-6 right-6 z-50 w-80',
                    'flex flex-col items-center gap-2 rounded-2xl border border-secondary bg-primary p-5 shadow-2xl',
                    'transition-all duration-300',
                )}
            >
                <CheckCircle
                    className={cx('size-8', isEnded ? 'text-fg-success-primary' : 'text-fg-error-primary')}
                />
                <span className="text-sm font-semibold text-primary">
                    {isEnded ? 'Call Ended' : 'Call Failed'}
                    {lastDuration > 0 && ` \u00B7 ${formatDuration(lastDuration)}`}
                </span>
                <span className="text-xs text-tertiary">auto-closing...</span>
            </div>
        );
    }

    return null;
};
