import { useEffect, useMemo, useState, useRef } from 'react';
import { faMagnifyingGlass, faPlay, faPause, faSparkles } from '@fortawesome/pro-duotone-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faIcon } from '@/lib/icon-wrapper';

const SearchLg = faIcon(faMagnifyingGlass);
import { Badge } from '@/components/base/badges/badges';
import { Input } from '@/components/base/input/input';
import { Table } from '@/components/application/table/table';
import { TopBar } from '@/components/layout/top-bar';
import { PhoneActionCell } from '@/components/call-desk/phone-action-cell';
import { RecordingAnalysisSlideout } from '@/components/call-desk/recording-analysis';
import { apiClient } from '@/lib/api-client';
import { formatPhone, formatDateOnly } from '@/lib/format';

type RecordingRecord = {
    id: string;
    direction: string | null;
    callStatus: string | null;
    callerNumber: { primaryPhoneNumber: string } | null;
    agentName: string | null;
    startedAt: string | null;
    durationSec: number | null;
    disposition: string | null;
    recording: { primaryLinkUrl: string; primaryLinkLabel: string } | null;
};

const QUERY = `{ calls(first: 200, orderBy: [{ startedAt: DescNullsLast }]) { edges { node {
    id direction callStatus callerNumber { primaryPhoneNumber }
    agentName startedAt durationSec disposition
    recording { primaryLinkUrl primaryLinkLabel }
} } } }`;

const formatDate = (iso: string): string => formatDateOnly(iso);

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

const RecordingPlayer = ({ url }: { url: string }) => {
    const audioRef = useRef<HTMLAudioElement>(null);
    const [playing, setPlaying] = useState(false);

    const toggle = () => {
        if (!audioRef.current) return;
        if (playing) { audioRef.current.pause(); } else { audioRef.current.play(); }
        setPlaying(!playing);
    };

    return (
        <div className="flex items-center gap-2">
            <button onClick={toggle} className="flex size-7 items-center justify-center rounded-full bg-brand-solid text-white hover:opacity-90 transition duration-100 ease-linear">
                <FontAwesomeIcon icon={playing ? faPause : faPlay} className="size-3" />
            </button>
            <audio ref={audioRef} src={url} onEnded={() => setPlaying(false)} />
        </div>
    );
};

export const CallRecordingsPage = () => {
    const [calls, setCalls] = useState<RecordingRecord[]>([]);
    const [loading, setLoading] = useState(true);
    const [search, setSearch] = useState('');
    const [slideoutCallId, setSlideoutCallId] = useState<string | null>(null);

    useEffect(() => {
        apiClient.graphql<{ calls: { edges: Array<{ node: RecordingRecord }> } }>(QUERY, undefined, { silent: true })
            .then(data => {
                const withRecordings = data.calls.edges
                    .map(e => e.node)
                    .filter(c => c.recording?.primaryLinkUrl);
                setCalls(withRecordings);
            })
            .catch(() => {})
            .finally(() => setLoading(false));
    }, []);

    const filtered = useMemo(() => {
        if (!search.trim()) return calls;
        const q = search.toLowerCase();
        return calls.filter(c =>
            (c.agentName ?? '').toLowerCase().includes(q) ||
            (c.callerNumber?.primaryPhoneNumber ?? '').includes(q),
        );
    }, [calls, search]);

    return (
        <>
            <TopBar title="Call Recordings" />
            <div className="flex flex-1 flex-col overflow-hidden">
                <div className="flex shrink-0 items-center justify-between border-b border-secondary px-6 py-3">
                    <span className="text-sm text-tertiary">{filtered.length} recordings</span>
                    <div className="w-56">
                        <Input placeholder="Search agent or phone..." icon={SearchLg} size="sm" value={search} onChange={setSearch} />
                    </div>
                </div>

                <div className="flex flex-1 flex-col overflow-hidden px-4 pt-3">
                    {loading ? (
                        <div className="flex items-center justify-center py-12">
                            <p className="text-sm text-tertiary">Loading recordings...</p>
                        </div>
                    ) : filtered.length === 0 ? (
                        <div className="flex items-center justify-center py-12">
                            <p className="text-sm text-quaternary">{search ? 'No matching recordings' : 'No call recordings found'}</p>
                        </div>
                    ) : (
                        <Table size="sm">
                            <Table.Header>
                                <Table.Head label="Agent" isRowHeader />
                                <Table.Head label="Caller" />
                                <Table.Head label="AI" className="w-14" />
                                <Table.Head label="Type" className="w-20" />
                                <Table.Head label="Date" className="w-28" />
                                <Table.Head label="Duration" className="w-20" />
                                <Table.Head label="Disposition" className="w-32" />
                                <Table.Head label="Recording" className="w-24" />
                            </Table.Header>
                            <Table.Body items={filtered}>
                                {(call) => {
                                    const phone = call.callerNumber?.primaryPhoneNumber ?? '';
                                    const dirLabel = call.direction === 'INBOUND' ? 'In' : 'Out';
                                    const dirColor = call.direction === 'INBOUND' ? 'blue' : 'brand';

                                    return (
                                        <Table.Row id={call.id}>
                                            <Table.Cell>
                                                <span className="text-sm text-primary">{call.agentName || '—'}</span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                {phone ? (
                                                    <PhoneActionCell phoneNumber={phone} displayNumber={formatPhone({ number: phone, callingCode: '+91' })} />
                                                ) : <span className="text-xs text-quaternary">—</span>}
                                            </Table.Cell>
                                            <Table.Cell>
                                                <span
                                                    role="button"
                                                    tabIndex={0}
                                                    onPointerDown={(e) => {
                                                        e.stopPropagation();
                                                        setSlideoutCallId(call.id);
                                                    }}
                                                    className="inline-flex items-center gap-1 rounded-full bg-brand-primary px-2.5 py-1 text-xs font-semibold text-brand-secondary hover:bg-brand-secondary hover:text-white cursor-pointer transition duration-100 ease-linear"
                                                    title="AI Analysis"
                                                >
                                                    <FontAwesomeIcon icon={faSparkles} className="size-3" />
                                                    AI
                                                </span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                <Badge size="sm" color={dirColor} type="pill-color">{dirLabel}</Badge>
                                            </Table.Cell>
                                            <Table.Cell>
                                                <span className="text-sm text-primary">{call.startedAt ? formatDate(call.startedAt) : '—'}</span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                <span className="text-sm text-primary">{formatDuration(call.durationSec)}</span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                {call.disposition ? (
                                                    <Badge size="sm" color="gray" type="pill-color">
                                                        {call.disposition.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, c => c.toUpperCase())}
                                                    </Badge>
                                                ) : <span className="text-xs text-quaternary">—</span>}
                                            </Table.Cell>
                                            <Table.Cell>
                                                {call.recording?.primaryLinkUrl && (
                                                    <RecordingPlayer url={call.recording.primaryLinkUrl} />
                                                )}
                                            </Table.Cell>
                                        </Table.Row>
                                    );
                                }}
                            </Table.Body>
                        </Table>
                    )}

                </div>

                {/* Analysis slideout */}
                {(() => {
                    const call = slideoutCallId ? filtered.find(c => c.id === slideoutCallId) : null;
                    if (!call?.recording?.primaryLinkUrl) return null;
                    return (
                        <RecordingAnalysisSlideout
                            isOpen={true}
                            onOpenChange={(open) => { if (!open) setSlideoutCallId(null); }}
                            recordingUrl={call.recording.primaryLinkUrl}
                            callId={call.id}
                            agentName={call.agentName}
                            callerNumber={call.callerNumber?.primaryPhoneNumber ?? null}
                            direction={call.direction}
                            startedAt={call.startedAt}
                            durationSec={call.durationSec}
                            disposition={call.disposition}
                        />
                    );
                })()}
            </div>
        </>
    );
};
