import { useMemo } from 'react';
import { Link, useParams } from 'react-router';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
    faArrowLeft,
    faPhone,
    faPhoneArrowDownLeft,
    faPhoneArrowUpRight,
    faPhoneMissed,
    faClock,
    faPercent,
    faPhoneArrowDown,
    faPhoneArrowUp,
    faPhoneXmark,
    faUserHeadset,
} from '@fortawesome/pro-duotone-svg-icons';
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { Avatar } from '@/components/base/avatar/avatar';
import { Badge } from '@/components/base/badges/badges';
import { Button } from '@/components/base/buttons/button';
import { Table, TableCard } from '@/components/application/table/table';
import { TopBar } from '@/components/layout/top-bar';
import { formatShortDate, formatPhone, getInitials } from '@/lib/format';
import { useData } from '@/providers/data-provider';
import type { Call, CallDirection, CallDisposition } from '@/types/entities';

type KpiCardProps = {
    label: string;
    value: number | string;
    icon: IconDefinition;
    iconColor: string;
    iconBg: string;
};

const KpiCard = ({ label, value, icon, iconColor, iconBg }: KpiCardProps) => (
    <div className="flex flex-1 items-center gap-4 rounded-xl border border-secondary bg-primary p-4 shadow-xs">
        <div className={`flex size-10 shrink-0 items-center justify-center rounded-full ${iconBg}`}>
            <FontAwesomeIcon icon={icon} className={`size-4 ${iconColor}`} />
        </div>
        <div className="flex flex-col">
            <span className="text-xs font-medium text-tertiary">{label}</span>
            <span className="text-lg font-bold text-primary">{value}</span>
        </div>
    </div>
);

const formatDuration = (seconds: number): string => {
    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 formatPercent = (value: number): string => {
    if (isNaN(value) || !isFinite(value)) return '0%';
    return `${Math.round(value)}%`;
};

const formatPhoneDisplay = (call: Call): string => {
    if (call.callerNumber && call.callerNumber.length > 0) {
        return formatPhone(call.callerNumber[0]);
    }
    return '\u2014';
};

const dispositionConfig: Record<CallDisposition, { label: string; color: 'success' | 'brand' | 'blue-light' | 'warning' | 'gray' | 'error' }> = {
    APPOINTMENT_BOOKED: { label: 'Appt Booked', color: 'success' },
    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' },
    CALLBACK_REQUESTED: { label: 'Callback', color: 'brand' },
};

const DirectionIcon = ({ direction, status }: { direction: CallDirection | null; status: Call['callStatus'] }) => {
    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" />;
};

export const AgentDetailPage = () => {
    const { id } = useParams<{ id: string }>();
    const { calls, leads, loading } = useData();

    const agentName = id ? decodeURIComponent(id) : '';

    const agentCalls = useMemo(
        () =>
            calls
                .filter((c) => c.agentName === agentName)
                .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;
                }),
        [calls, agentName],
    );

    // Build lead name map for enrichment
    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]);

    // KPI calculations
    const totalCalls = agentCalls.length;
    const inboundCalls = agentCalls.filter((c) => c.callDirection === 'INBOUND').length;
    const outboundCalls = agentCalls.filter((c) => c.callDirection === 'OUTBOUND').length;
    const missedCalls = agentCalls.filter((c) => c.callStatus === 'MISSED').length;

    const completedCalls = agentCalls.filter((c) => (c.durationSeconds ?? 0) > 0);
    const totalDuration = completedCalls.reduce((sum, c) => sum + (c.durationSeconds ?? 0), 0);
    const avgHandle = completedCalls.length > 0 ? Math.round(totalDuration / completedCalls.length) : 0;

    const booked = agentCalls.filter((c) => c.disposition === 'APPOINTMENT_BOOKED').length;
    const conversion = totalCalls > 0 ? (booked / totalCalls) * 100 : 0;

    const nameParts = agentName.split(' ');
    const initials = getInitials(nameParts[0] ?? '', nameParts[1] ?? '');

    if (loading) {
        return (
            <div className="flex flex-1 flex-col overflow-hidden">
                <TopBar title="Agent Detail" />
                <div className="flex flex-1 items-center justify-center">
                    <p className="text-sm text-tertiary">Loading...</p>
                </div>
            </div>
        );
    }

    if (totalCalls === 0 && !loading) {
        return (
            <div className="flex flex-1 flex-col overflow-hidden">
                <TopBar title="Agent Detail" />
                <div className="flex flex-1 flex-col items-center justify-center gap-3 p-8">
                    <FontAwesomeIcon icon={faUserHeadset} className="size-10 text-fg-quaternary" />
                    <p className="text-md font-semibold text-primary">No data found for "{agentName}"</p>
                    <p className="text-sm text-tertiary">This agent has no call records.</p>
                    <Link to="/team-dashboard">
                        <Button size="sm" color="secondary" iconLeading={({ className }: { className?: string }) => (
                            <FontAwesomeIcon icon={faArrowLeft} className={className} />
                        )}>
                            Back to Team Dashboard
                        </Button>
                    </Link>
                </div>
            </div>
        );
    }

    return (
        <div className="flex flex-1 flex-col overflow-hidden">
            <TopBar title="Agent Detail" subtitle={`${totalCalls} total calls`} />

            <div className="flex-1 overflow-y-auto p-6 space-y-6">
                {/* Agent header + back button */}
                <div className="flex items-center justify-between">
                    <div className="flex items-center gap-4">
                        <Link to="/team-dashboard">
                            <Button size="sm" color="tertiary" iconLeading={({ className }: { className?: string }) => (
                                <FontAwesomeIcon icon={faArrowLeft} className={className} />
                            )}>
                                Back
                            </Button>
                        </Link>
                        <div className="h-8 w-px bg-secondary" />
                        <Avatar size="lg" initials={initials} />
                        <div className="flex flex-col">
                            <h2 className="text-lg font-bold text-primary">{agentName}</h2>
                            <p className="text-sm text-tertiary">Agent</p>
                        </div>
                    </div>
                </div>

                {/* KPI row */}
                <div className="grid grid-cols-2 gap-3 xl:grid-cols-6">
                    <KpiCard label="Total Calls" value={totalCalls} icon={faPhone} iconColor="text-fg-brand-primary" iconBg="bg-brand-secondary" />
                    <KpiCard label="Inbound" value={inboundCalls} icon={faPhoneArrowDownLeft} iconColor="text-fg-success-primary" iconBg="bg-success-secondary" />
                    <KpiCard label="Outbound" value={outboundCalls} icon={faPhoneArrowUpRight} iconColor="text-fg-brand-primary" iconBg="bg-brand-secondary" />
                    <KpiCard label="Missed" value={missedCalls} icon={faPhoneMissed} iconColor="text-fg-error-primary" iconBg="bg-error-secondary" />
                    <KpiCard label="Avg Handle" value={formatDuration(avgHandle)} icon={faClock} iconColor="text-fg-warning-primary" iconBg="bg-warning-secondary" />
                    <KpiCard label="Conversion" value={formatPercent(conversion)} icon={faPercent} iconColor="text-fg-success-primary" iconBg="bg-success-secondary" />
                </div>

                {/* Call log table */}
                <TableCard.Root size="sm">
                    <TableCard.Header
                        title="Call Log"
                        badge={agentCalls.length}
                        description={`Calls handled by ${agentName}`}
                    />

                    {agentCalls.length === 0 ? (
                        <div className="flex flex-col items-center justify-center py-16">
                            <p className="text-sm text-tertiary">No calls found.</p>
                        </div>
                    ) : (
                        <Table>
                            <Table.Header>
                                <Table.Head label="TYPE" className="w-14" isRowHeader />
                                <Table.Head label="PATIENT" />
                                <Table.Head label="PHONE" />
                                <Table.Head label="DURATION" className="w-24" />
                                <Table.Head label="OUTCOME" />
                                <Table.Head label="TIME" />
                            </Table.Header>
                            <Table.Body items={agentCalls}>
                                {(call) => {
                                    const patientName = call.leadName ?? leadNameMap.get(call.leadId ?? '') ?? 'Unknown';
                                    const phoneDisplay = formatPhoneDisplay(call);
                                    const durationStr = call.durationSeconds !== null && call.durationSeconds > 0
                                        ? formatDuration(call.durationSeconds)
                                        : '\u2014';
                                    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>
                                                <span className="text-sm text-tertiary whitespace-nowrap">
                                                    {phoneDisplay}
                                                </span>
                                            </Table.Cell>
                                            <Table.Cell>
                                                <span className="text-sm text-secondary whitespace-nowrap">
                                                    {durationStr}
                                                </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>
                                            <Table.Cell>
                                                <span className="text-sm text-tertiary whitespace-nowrap">
                                                    {call.startedAt ? formatShortDate(call.startedAt) : '\u2014'}
                                                </span>
                                            </Table.Cell>
                                        </Table.Row>
                                    );
                                }}
                            </Table.Body>
                        </Table>
                    )}
                </TableCard.Root>
            </div>
        </div>
    );
};
