import { useEffect, useMemo, useRef, useState } from 'react';
import type { FC } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
    faPhoneArrowDown,
    faPhoneArrowUp,
    faPhoneXmark,
    faPlay,
    faPause,
    faMagnifyingGlass,
} from '@fortawesome/pro-duotone-svg-icons';

const SearchLg: FC<{ className?: string }> = ({ className }) => <FontAwesomeIcon icon={faMagnifyingGlass} className={className} />;
import { Table } from '@/components/application/table/table';
import { Badge } from '@/components/base/badges/badges';
import { Button } from '@/components/base/buttons/button';
import { Input } from '@/components/base/input/input';
import { Select } from '@/components/base/select/select';
import { PageHeader } from '@/components/layout/page-header';
import { PhoneActionCell } from '@/components/call-desk/phone-action-cell';
import { formatShortDate, formatPhone } from '@/lib/format';
// cx removed — no longer used after SLA column removal
import { useData } from '@/providers/data-provider';
import { useAuth } from '@/providers/auth-provider';
import { PaginationCardDefault } from '@/components/application/pagination/pagination';
import type { Call, CallDirection, CallDisposition } from '@/types/entities';

type FilterKey = 'all' | 'inbound' | 'outbound' | 'missed';

const allFilterItems = [
    { id: 'all' as const, label: 'All Calls' },
    { id: 'inbound' as const, label: 'Inbound' },
    { id: 'outbound' as const, label: 'Outbound' },
    { id: 'missed' as const, label: 'Missed' },
];

const agentFilterItems = [
    { id: 'all' as const, label: 'All Calls' },
    { id: 'inbound' as const, label: 'Inbound' },
    { id: 'outbound' as const, label: 'Outbound' },
];

const dispositionConfig: Record<CallDisposition, { label: string; color: 'success' | 'brand' | 'blue-light' | 'warning' | 'gray' | 'error' }> = {
    APPOINTMENT_BOOKED: { label: 'Appt Booked', color: 'success' },
    APPOINTMENT_RESCHEDULED: { label: 'Appt Rescheduled', color: 'warning' },
    APPOINTMENT_CANCELLED: { label: 'Appt Cancelled', color: 'error' },
    FOLLOW_UP_SCHEDULED: { label: 'Follow-up', color: 'brand' },
    INFO_PROVIDED: { label: 'Info Provided', color: 'blue-light' },
    NO_ANSWER: { label: 'No Answer', color: 'warning' },
    WRONG_NUMBER: { label: 'Wrong Number', color: 'gray' },
    NOT_INTERESTED: { label: 'Not Interested', color: 'error' },
    CALLBACK_REQUESTED: { label: 'Callback', color: 'brand' },
    CALL_DROPPED: { label: 'Call Dropped', color: 'gray' },
};

const formatDuration = (seconds: number | null): string => {
    if (seconds === null || seconds === 0) return '\u2014';
    if (seconds < 60) return `${seconds}s`;
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`;
};

const DirectionIcon: FC<{ direction: CallDirection | null; status: Call['callStatus'] }> = ({ direction, status }) => {
    if (status === 'MISSED') {
        return <FontAwesomeIcon icon={faPhoneXmark} className="size-4 text-fg-error-secondary" />;
    }
    if (direction === 'OUTBOUND') {
        return <FontAwesomeIcon icon={faPhoneArrowUp} className="size-4 text-fg-brand-secondary" />;
    }
    return <FontAwesomeIcon icon={faPhoneArrowDown} className="size-4 text-fg-success-secondary" />;
};

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

    const togglePlay = () => {
        const audio = audioRef.current;
        if (!audio) return;
        if (isPlaying) {
            audio.pause();
            setIsPlaying(false);
        } else {
            audio.play().then(() => setIsPlaying(true)).catch(() => {});
        }
    };

    const handleEnded = () => setIsPlaying(false);

    return (
        <>
            <audio ref={audioRef} src={url} preload="none" onEnded={handleEnded} />
            <Button
                size="sm"
                color="tertiary"
                iconLeading={
                    <FontAwesomeIcon
                        icon={isPlaying ? faPause : faPlay}
                        data-icon
                        className="size-3.5"
                    />
                }
                onClick={togglePlay}
                aria-label={isPlaying ? 'Pause recording' : 'Play recording'}
            />
        </>
    );
};

const PAGE_SIZE = 20;

export const CallHistoryPage = () => {
    const { calls, leads } = useData();
    const { user, isAdmin } = useAuth();
    const [search, setSearch] = useState('');
    const [filter, setFilter] = useState<FilterKey>('all');
    const [page, setPage] = useState(1);

    const leadNameMap = useMemo(() => {
        const map = new Map<string, string>();
        for (const lead of leads) {
            if (lead.id && lead.contactName) {
                const name = `${lead.contactName.firstName ?? ''} ${lead.contactName.lastName ?? ''}`.trim();
                if (name) map.set(lead.id, name);
            }
        }
        return map;
    }, [leads]);

    // Agent sees only their own calls; supervisor sees all
    const agentConfig = localStorage.getItem('helix_agent_config');
    const myAgentId = agentConfig ? (() => { try { return JSON.parse(agentConfig).ozonetelAgentId; } catch { return null; } })() : null;

    const filteredCalls = useMemo(() => {
        let result = [...calls].sort((a, b) => {
            const dateA = a.startedAt ? new Date(a.startedAt).getTime() : 0;
            const dateB = b.startedAt ? new Date(b.startedAt).getTime() : 0;
            return dateB - dateA;
        });

        // CC agent: filter to own calls only.
        // Match on the authoritative agent relation (set by CDR enrichment)
        // or the raw agentName for unenriched rows. Chain names like
        // "RamaiahAdmin -> GlobalHealthX" are split — last segment is
        // the final handler. Missed calls have no handler and are excluded
        // from the agent's personal history (they belong on the Missed
        // Calls queue).
        if (!isAdmin && myAgentId) {
            const myId = myAgentId.toLowerCase();
            result = result.filter((c) => {
                // Missed calls have no handler — exclude from agent history
                if (c.callStatus === 'MISSED') return false;
                // Authoritative: agent relation from CDR enrichment
                if (c.agent?.ozonetelAgentId?.toLowerCase() === myId) return true;
                // Fallback: parse chain in agentName, match last segment
                if (c.agentName) {
                    const segments = c.agentName.split('->').map(s => s.trim().toLowerCase());
                    const finalHandler = segments[segments.length - 1];
                    if (finalHandler === myId) return true;
                }
                return false;
            });
        }

        if (filter === 'inbound') result = result.filter((c) => c.callDirection === 'INBOUND' && c.callStatus !== 'MISSED');
        else if (filter === 'outbound') result = result.filter((c) => c.callDirection === 'OUTBOUND');
        else if (filter === 'missed') result = result.filter((c) => c.callStatus === 'MISSED');

        if (search.trim()) {
            const q = search.toLowerCase();
            result = result.filter((c) => {
                const name = c.leadName ?? leadNameMap.get(c.leadId ?? '') ?? '';
                const phone = c.callerNumber?.[0]?.number ?? '';
                const agent = c.agentName ?? '';
                return name.toLowerCase().includes(q) || phone.includes(q) || agent.toLowerCase().includes(q);
            });
        }

        return result;
    }, [calls, filter, search, leadNameMap, isAdmin, myAgentId, user.id]);

    const completedCount = filteredCalls.filter((c) => c.callStatus === 'COMPLETED').length;
    const missedCount = filteredCalls.filter((c) => c.callStatus === 'MISSED').length;

    const totalPages = Math.max(1, Math.ceil(filteredCalls.length / PAGE_SIZE));
    const pagedCalls = filteredCalls.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);

    useEffect(() => { setPage(1); }, [filter, search]); // eslint-disable-line react-hooks/exhaustive-deps

    return (
        <div className="flex flex-1 flex-col overflow-hidden">
                <PageHeader
                    title={isAdmin ? 'Call History' : 'My Call History'}
                    badge={filteredCalls.length}
                    subtitle={isAdmin ? `${completedCount} completed \u00B7 ${missedCount} missed` : `${completedCount} completed`}
                    infoText={isAdmin ? 'All calls across all agents with recordings and dispositions.' : 'Your answered inbound and outbound calls.'}
                    controls={
                        <>
                            <div className="w-44">
                                <Select
                                    size="sm"
                                    placeholder="All Calls"
                                    selectedKey={filter}
                                    onSelectionChange={(key) => setFilter(key as FilterKey)}
                                    items={isAdmin ? allFilterItems : agentFilterItems}
                                    aria-label="Filter calls"
                                >
                                    {(item) => (
                                        <Select.Item id={item.id} label={item.label}>
                                            {item.label}
                                        </Select.Item>
                                    )}
                                </Select>
                            </div>
                            <div className="w-56">
                                <Input
                                    placeholder="Search calls..."
                                    icon={SearchLg}
                                    size="sm"
                                    value={search}
                                    onChange={(value) => setSearch(value)}
                                    aria-label="Search calls"
                                />
                            </div>
                        </>
                    }
                />

            <div className="flex flex-1 flex-col min-h-0 overflow-hidden px-4 pt-3">
                    {filteredCalls.length === 0 ? (
                        <div className="flex flex-col items-center justify-center py-16">
                            <h3 className="text-sm font-semibold text-primary">No calls found</h3>
                            <p className="text-sm text-tertiary mt-1">
                                {search ? 'Try a different search term' : 'No call history available yet.'}
                            </p>
                        </div>
                    ) : (
                        <Table>
                            <Table.Header>
                                <Table.Head label="TYPE" className="w-14" isRowHeader />
                                <Table.Head label="CALLER" />
                                <Table.Head label="PHONE" />
                                <Table.Head label="DURATION" className="w-24" />
                                <Table.Head label="OUTCOME" />
                                {/* Agent columns — only visible for supervisor */}
                                {isAdmin && <Table.Head label="AGENT" />}
                                {isAdmin && <Table.Head label="RECORDING" className="w-24" />}
                                <Table.Head label="TIME" />
                            </Table.Header>
                            <Table.Body items={pagedCalls}>
                                {(call) => {
                                    const phoneRaw = call.callerNumber?.[0]?.number ?? '';
                                    const patientName = call.leadName ?? leadNameMap.get(call.leadId ?? '') ?? (phoneRaw ? formatPhone({ number: phoneRaw, callingCode: '+91' }) : 'Unknown');
                                    const dispositionCfg = call.disposition !== null ? dispositionConfig[call.disposition] : null;

                                    return (
                                        <Table.Row id={call.id}>
                                            <Table.Cell>
                                                <DirectionIcon direction={call.callDirection} status={call.callStatus} />
                                            </Table.Cell>
                                            <Table.Cell>
                                                <span className="text-sm font-medium text-primary truncate max-w-[160px] block">
                                                    {patientName}
                                                </span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                {phoneRaw ? (
                                                    <PhoneActionCell
                                                        phoneNumber={phoneRaw}
                                                        displayNumber={formatPhone({ number: phoneRaw, callingCode: '+91' })}
                                                    />
                                                ) : (
                                                    <span className="text-sm text-quaternary">{'\u2014'}</span>
                                                )}
                                            </Table.Cell>
                                            <Table.Cell>
                                                <span className="text-sm text-secondary whitespace-nowrap">
                                                    {formatDuration(call.durationSeconds)}
                                                </span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                {dispositionCfg ? (
                                                    <Badge size="sm" color={dispositionCfg.color} type="pill-color">
                                                        {dispositionCfg.label}
                                                    </Badge>
                                                ) : (
                                                    <span className="text-sm text-quaternary">{'\u2014'}</span>
                                                )}
                                            </Table.Cell>
                                            {isAdmin && (
                                                <Table.Cell>
                                                    <span className="text-sm text-secondary">
                                                        {call.agent?.name ?? call.agentName ?? '\u2014'}
                                                    </span>
                                                </Table.Cell>
                                            )}
                                            {isAdmin && (
                                                <Table.Cell>
                                                    {call.recordingUrl ? (
                                                        <RecordingPlayer url={call.recordingUrl} />
                                                    ) : (
                                                        <span className="text-xs text-quaternary">{'\u2014'}</span>
                                                    )}
                                                </Table.Cell>
                                            )}
                                            <Table.Cell>
                                                <span className="text-sm text-tertiary whitespace-nowrap">
                                                    {call.startedAt ? formatShortDate(call.startedAt) : '\u2014'}
                                                </span>
                                            </Table.Cell>
                                        </Table.Row>
                                    );
                                }}
                            </Table.Body>
                        </Table>
                    )}
            </div>
            {totalPages > 1 && (
                <div className="shrink-0 border-t border-secondary px-6 py-3">
                    <PaginationCardDefault
                        page={page}
                        total={totalPages}
                        onPageChange={setPage}
                    />
                </div>
            )}
        </div>
    );
};
