import { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCircle, faChevronDown, faSpinnerThird } from '@fortawesome/pro-duotone-svg-icons';
import { useAgentState } from '@/hooks/use-agent-state';
import type { OzonetelState } from '@/hooks/use-agent-state';
import { apiClient } from '@/lib/api-client';
import { notify } from '@/lib/toast';
import { cx } from '@/utils/cx';

type ToggleableStatus = 'ready' | 'break' | 'training';

const displayConfig: Record<OzonetelState, { label: string; color: string; dotColor: string }> = {
    ready: { label: 'Ready', color: 'text-success-primary', dotColor: 'text-fg-success-primary' },
    break: { label: 'Break', color: 'text-warning-primary', dotColor: 'text-fg-warning-primary' },
    training: { label: 'Training', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' },
    calling: { label: 'Calling', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' },
    'in-call': { label: 'In Call', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' },
    acw: { label: 'Wrapping up', color: 'text-warning-primary', dotColor: 'text-fg-warning-primary' },
    offline: { label: 'Offline', color: 'text-tertiary', dotColor: 'text-fg-quaternary' },
};

const toggleOptions: Array<{ key: ToggleableStatus; label: string; color: string; dotColor: string }> = [
    { key: 'ready', label: 'Ready', color: 'text-success-primary', dotColor: 'text-fg-success-primary' },
    { key: 'break', label: 'Break', color: 'text-warning-primary', dotColor: 'text-fg-warning-primary' },
    { key: 'training', label: 'Training', color: 'text-brand-secondary', dotColor: 'text-fg-brand-primary' },
];

type AgentStatusToggleProps = {
    isRegistered: boolean;
    connectionStatus: string;
};

export const AgentStatusToggle = ({ isRegistered, connectionStatus }: AgentStatusToggleProps) => {
    const agentConfig = localStorage.getItem('helix_agent_config');
    const agentId = agentConfig ? JSON.parse(agentConfig).ozonetelAgentId : null;
    const { state: ozonetelState } = useAgentState(agentId);

    const [menuOpen, setMenuOpen] = useState(false);
    const [changing, setChanging] = useState(false);

    const handleChange = async (newStatus: ToggleableStatus) => {
        setMenuOpen(false);
        if (newStatus === ozonetelState) return;
        setChanging(true);

        try {
            if (newStatus === 'ready') {
                console.log('[AGENT-STATE] Changing to Ready');
                const res = await apiClient.post('/api/ozonetel/agent-state', { agentId, state: 'Ready' });
                console.log('[AGENT-STATE] Ready response:', JSON.stringify(res));
            } else {
                const pauseReason = newStatus === 'break' ? 'Break' : 'Training';
                // Ozonetel rejects Pause→Pause (Break↔Training) — the agent must
                // transit through Ready. Insert a Ready hop whenever we're
                // moving between two paused sub-states.
                const isPauseToPause = ozonetelState === 'break' || ozonetelState === 'training';
                if (isPauseToPause) {
                    console.log(`[AGENT-STATE] ${ozonetelState}→${newStatus}: sending Ready first, then Pause(${pauseReason})`);
                    await apiClient.post('/api/ozonetel/agent-state', { agentId, state: 'Ready' });
                    await new Promise(resolve => setTimeout(resolve, 400));
                }
                console.log(`[AGENT-STATE] Changing to Pause: ${pauseReason}`);
                const res = await apiClient.post('/api/ozonetel/agent-state', { agentId, state: 'Pause', pauseReason });
                console.log('[AGENT-STATE] Pause response:', JSON.stringify(res));
            }
            // Don't setStatus — SSE will push the real state
        } catch (err) {
            console.error('[AGENT-STATE] Status change failed:', err);
            notify.error('Status Change Failed', 'Could not update agent status');
        } finally {
            setChanging(false);
        }
    };

    // If SIP isn't connected, show connection status with user-friendly message
    if (!isRegistered) {
        const statusMessages: Record<string, string> = {
            disconnected: 'Telephony unavailable',
            connecting: 'Connecting to telephony...',
            connected: 'Registering...',
            error: 'Telephony error — check VPN',
        };
        return (
            <div className="flex items-center gap-1.5 rounded-full bg-secondary px-3 py-1">
                <FontAwesomeIcon icon={faCircle} className="size-2 text-fg-warning-primary animate-pulse" />
                <span className="text-xs font-medium text-tertiary">{statusMessages[connectionStatus] ?? connectionStatus}</span>
            </div>
        );
    }

    const current = displayConfig[ozonetelState] ?? displayConfig.offline;
    const canToggle = ozonetelState === 'ready' || ozonetelState === 'break' || ozonetelState === 'training' || ozonetelState === 'offline';

    return (
        <div className="relative">
            <button
                onClick={() => canToggle && setMenuOpen(!menuOpen)}
                disabled={changing || !canToggle}
                className={cx(
                    'flex items-center gap-1.5 rounded-full bg-secondary px-3 py-1 transition duration-100 ease-linear',
                    canToggle && !changing ? 'hover:bg-secondary_hover cursor-pointer' : 'cursor-default',
                )}
            >
                {changing ? (
                    <FontAwesomeIcon icon={faSpinnerThird} spin className="size-2.5 text-fg-brand-primary" />
                ) : (
                    <FontAwesomeIcon icon={faCircle} className={cx('size-2', current.dotColor)} />
                )}
                <span className={cx('text-xs font-medium', changing ? 'text-brand-secondary' : current.color)}>
                    {changing ? 'Changing…' : current.label}
                </span>
                {canToggle && !changing && <FontAwesomeIcon icon={faChevronDown} className="size-2.5 text-fg-quaternary" />}
            </button>

            {menuOpen && (
                <>
                    <div className="fixed inset-0 z-40" onClick={() => setMenuOpen(false)} />
                    <div className="absolute right-0 top-full z-50 mt-1 w-36 rounded-lg bg-primary shadow-lg ring-1 ring-secondary py-1">
                        {toggleOptions.map((opt) => (
                            <button
                                key={opt.key}
                                onClick={() => handleChange(opt.key)}
                                className={cx(
                                    'flex w-full items-center gap-2 px-3 py-2 text-xs font-medium transition duration-100 ease-linear',
                                    opt.key === ozonetelState ? 'bg-active' : 'hover:bg-primary_hover',
                                )}
                            >
                                <FontAwesomeIcon icon={faCircle} className={cx('size-2', opt.dotColor)} />
                                <span className={opt.color}>{opt.label}</span>
                            </button>
                        ))}
                    </div>
                </>
            )}
        </div>
    );
};
