import { useState, useEffect } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPhone, faUserDoctor, faHeadset, faShieldCheck, faMagnifyingGlass } from '@fortawesome/pro-duotone-svg-icons';
import { faIcon } from '@/lib/icon-wrapper';
import { Input } from '@/components/base/input/input';
import { Button } from '@/components/base/buttons/button';
import { apiClient } from '@/lib/api-client';
import { notify } from '@/lib/toast';
import { cx } from '@/utils/cx';

const SearchIcon = faIcon(faMagnifyingGlass);

type TransferTarget = {
    id: string;
    name: string;
    type: 'agent' | 'supervisor' | 'doctor';
    department?: string;
    phoneNumber: string;
    status?: 'ready' | 'busy' | 'offline' | 'on-call' | 'break';
};

type TransferDialogProps = {
    ucid: string;
    currentAgentId?: string;
    onClose: () => void;
    onTransferred: () => void;
};

const statusConfig: Record<string, { label: string; dotClass: string }> = {
    ready: { label: 'Ready', dotClass: 'bg-success-solid' },
    'on-call': { label: 'On Call', dotClass: 'bg-error-solid' },
    'in-call': { label: 'On Call', dotClass: 'bg-error-solid' },
    busy: { label: 'Busy', dotClass: 'bg-warning-solid' },
    acw: { label: 'Wrapping', dotClass: 'bg-warning-solid' },
    break: { label: 'Break', dotClass: 'bg-tertiary' },
    training: { label: 'Training', dotClass: 'bg-tertiary' },
    offline: { label: 'Offline', dotClass: 'bg-quaternary' },
};

const typeIcons = {
    agent: faHeadset,
    supervisor: faShieldCheck,
    doctor: faUserDoctor,
};

export const TransferDialog = ({ ucid, currentAgentId, onClose, onTransferred }: TransferDialogProps) => {
    const [targets, setTargets] = useState<TransferTarget[]>([]);
    const [search, setSearch] = useState('');
    const [loading, setLoading] = useState(true);
    const [transferring, setTransferring] = useState(false);
    const [selectedTarget, setSelectedTarget] = useState<TransferTarget | null>(null);
    const [connectedTarget, setConnectedTarget] = useState<TransferTarget | null>(null);

    // Fetch transfer targets
    useEffect(() => {
        const fetchTargets = async () => {
            try {
                const [agentsRes, doctorsRes] = await Promise.all([
                    apiClient.graphql<any>(`{ agents(first: 20) { edges { node { id name ozonetelAgentId sipExtension } } } }`),
                    apiClient.graphql<any>(`{ doctors(first: 20) { edges { node { id name department phone { primaryPhoneNumber } } } } }`),
                ]);

                const agents: TransferTarget[] = (agentsRes.agents?.edges ?? [])
                    .map((e: any) => e.node)
                    .filter((a: any) => a.ozonetelAgentId !== currentAgentId)
                    .map((a: any) => ({
                        id: a.id,
                        name: a.name,
                        type: 'agent' as const,
                        phoneNumber: `0${a.sipExtension}`,
                        status: 'offline' as const,
                    }));

                const doctors: TransferTarget[] = (doctorsRes.doctors?.edges ?? [])
                    .map((e: any) => e.node)
                    .filter((d: any) => d.phone?.primaryPhoneNumber)
                    .map((d: any) => ({
                        id: d.id,
                        name: d.name,
                        type: 'doctor' as const,
                        department: d.department?.replace(/_/g, ' '),
                        phoneNumber: `0${d.phone.primaryPhoneNumber}`,
                    }));

                setTargets([...agents, ...doctors]);
            } catch (err) {
                console.warn('Failed to fetch transfer targets:', err);
            } finally {
                setLoading(false);
            }
        };
        fetchTargets();
    }, [currentAgentId]);

    // Subscribe to agent state via SSE for live status
    useEffect(() => {
        const agentTargets = targets.filter(t => t.type === 'agent');
        if (agentTargets.length === 0) return;

        // Poll agent states from the supervisor endpoint
        const fetchStates = async () => {
            for (const agent of agentTargets) {
                try {
                    const res = await apiClient.get<any>(`/api/supervisor/agent-state/${agent.phoneNumber.replace(/^0/, '')}`, { silent: true });
                    if (res?.state) {
                        setTargets(prev => prev.map(t =>
                            t.id === agent.id ? { ...t, status: res.state } : t,
                        ));
                    }
                } catch { /* best effort */ }
            }
        };
        fetchStates();
        const interval = setInterval(fetchStates, 10000);
        return () => clearInterval(interval);
    }, [targets.length]);

    const filtered = search.trim()
        ? targets.filter(t => t.name.toLowerCase().includes(search.toLowerCase()) || (t.department ?? '').toLowerCase().includes(search.toLowerCase()))
        : targets;

    const agents = filtered.filter(t => t.type === 'agent');
    const doctors = filtered.filter(t => t.type === 'doctor');

    const handleConnect = async () => {
        const target = selectedTarget;
        if (!target) return;
        setTransferring(true);
        try {
            await apiClient.post('/api/ozonetel/call-control', {
                action: 'CONFERENCE',
                ucid,
                conferenceNumber: target.phoneNumber,
            });
            setConnectedTarget(target);
            notify.success('Connected', `Speaking with ${target.name}. Click Complete to transfer.`);
        } catch {
            notify.error('Transfer Failed', `Could not connect to ${target.name}`);
        } finally {
            setTransferring(false);
        }
    };


    const handleComplete = async () => {
        if (!connectedTarget) return;
        setTransferring(true);
        try {
            await apiClient.post('/api/ozonetel/call-control', {
                action: 'KICK_CALL',
                ucid,
                conferenceNumber: connectedTarget.phoneNumber,
            });
            notify.success('Transferred', `Call transferred to ${connectedTarget.name}`);
            onTransferred();
        } catch {
            notify.error('Transfer Failed', 'Could not complete transfer');
        } finally {
            setTransferring(false);
        }
    };

    const handleCancel = async () => {
        if (!connectedTarget) { onClose(); return; }
        // Disconnect the third party, keep the caller
        setTransferring(true);
        try {
            await apiClient.post('/api/ozonetel/call-control', {
                action: 'KICK_CALL',
                ucid,
                conferenceNumber: connectedTarget.phoneNumber,
            });
            setConnectedTarget(null);
            notify.info('Cancelled', 'Transfer cancelled, caller reconnected');
        } catch {
            notify.error('Error', 'Could not disconnect third party');
        } finally {
            setTransferring(false);
        }
    };

    // Connected state — show target + complete/cancel buttons
    if (connectedTarget) {
        return (
            <div className="flex flex-col flex-1 min-h-0">
                <div className="flex items-center justify-center gap-3 py-8">
                    <div className="flex size-10 items-center justify-center rounded-full bg-success-secondary">
                        <FontAwesomeIcon icon={typeIcons[connectedTarget.type] ?? faPhone} className="size-4 text-fg-success-primary" />
                    </div>
                    <div>
                        <p className="text-sm font-semibold text-primary">Connected to {connectedTarget.name}</p>
                        <p className="text-xs text-tertiary">Speak privately, then complete the transfer</p>
                    </div>
                </div>
                <div className="shrink-0 flex items-center justify-center gap-3 pt-4 border-t border-secondary">
                    <Button size="sm" color="secondary" onClick={handleCancel} isLoading={transferring}>Cancel</Button>
                    <Button size="sm" color="primary" onClick={handleComplete} isLoading={transferring}>Complete Transfer</Button>
                </div>
            </div>
        );
    }

    // Target selection
    return (
        <div className="flex flex-col flex-1 min-h-0">
            {/* Search + actions — pinned */}
            <div className="shrink-0 flex items-center gap-2 mb-3">
                <div className="flex-1">
                    <Input size="sm" placeholder="Search agent, doctor..." icon={SearchIcon} value={search} onChange={setSearch} />
                </div>
                <Button size="sm" color="secondary" onClick={onClose}>Cancel</Button>
                <Button size="sm" color="primary" isLoading={transferring} isDisabled={!selectedTarget} onClick={handleConnect}>
                    Connect
                </Button>
            </div>

            {/* Scrollable target list */}
            <div className="flex-1 overflow-y-auto space-y-4">
                {loading ? (
                    <p className="text-xs text-tertiary text-center py-4">Loading...</p>
                ) : (
                    <>
                        {/* Agents */}
                        {agents.length > 0 && (
                            <div>
                                <p className="text-xs font-bold uppercase tracking-wider text-tertiary mb-2">Agents</p>
                                <div className="space-y-1">
                                    {agents.map(agent => {
                                        const st = statusConfig[agent.status ?? 'offline'] ?? statusConfig.offline;
                                        const isSelected = selectedTarget?.id === agent.id;
                                        return (
                                            <button
                                                key={agent.id}
                                                onClick={() => setSelectedTarget(agent)}
                                                disabled={transferring}
                                                className={cx(
                                                    'flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-left transition duration-100 ease-linear',
                                                    isSelected ? 'bg-brand-secondary ring-2 ring-brand' : 'hover:bg-secondary cursor-pointer',
                                                )}
                                            >
                                                <div className="flex items-center gap-2.5">
                                                    <FontAwesomeIcon icon={faHeadset} className="size-3.5 text-fg-quaternary" />
                                                    <span className="text-sm font-medium text-primary">{agent.name}</span>
                                                </div>
                                                <div className="flex items-center gap-1.5">
                                                    <span className={cx('size-2 rounded-full', st.dotClass)} />
                                                    <span className="text-xs text-tertiary">{st.label}</span>
                                                </div>
                                            </button>
                                        );
                                    })}
                                </div>
                            </div>
                        )}

                        {/* Doctors */}
                        {doctors.length > 0 && (
                            <div>
                                <p className="text-xs font-bold uppercase tracking-wider text-tertiary mb-2">Doctors</p>
                                <div className="space-y-1">
                                    {doctors.map(doc => {
                                        const isSelected = selectedTarget?.id === doc.id;
                                        return (
                                        <button
                                            key={doc.id}
                                            onClick={() => setSelectedTarget(doc)}
                                            disabled={transferring}
                                            className={cx(
                                                'flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-left transition duration-100 ease-linear',
                                                isSelected ? 'bg-brand-secondary ring-2 ring-brand' : 'hover:bg-secondary cursor-pointer',
                                            )}
                                        >
                                            <div className="flex items-center gap-2.5">
                                                <FontAwesomeIcon icon={faUserDoctor} className="size-3.5 text-fg-quaternary" />
                                                <div>
                                                    <span className="text-sm font-medium text-primary">{doc.name}</span>
                                                    {doc.department && <span className="ml-2 text-xs text-tertiary">{doc.department}</span>}
                                                </div>
                                            </div>
                                        </button>
                                        );
                                    })}
                                </div>
                            </div>
                        )}


                        {filtered.length === 0 && !loading && (
                            <p className="text-xs text-quaternary text-center py-4">No matching targets</p>
                        )}
                    </>
                )}
            </div>

        </div>
    );
};
