import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
    faPhone,
    faPhoneArrowDownLeft,
    faPhoneArrowUpRight,
    faPhoneMissed,
} from '@fortawesome/pro-duotone-svg-icons';
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { faCircleInfo } from '@fortawesome/pro-duotone-svg-icons';
import type { Call, Lead } from '@/types/entities';

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

const KpiCard = ({ label, value, icon, iconColor, iconBg, subtitle, tooltip }: 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 flex-1">
            <div className="flex items-center gap-1">
                <span className="text-xs font-medium text-tertiary">{label}</span>
                {tooltip && <FontAwesomeIcon icon={faCircleInfo} className="size-3 text-fg-quaternary" title={tooltip} />}
            </div>
            <span className="text-lg font-bold text-primary">{value}</span>
            {subtitle && <span className="text-[10px] text-tertiary">{subtitle}</span>}
        </div>
    </div>
);

type MetricCardProps = {
    label: string;
    value: string;
    description: string;
    tooltip?: string;
};

const MetricCard = ({ label, value, description, tooltip }: MetricCardProps) => (
    <div className="flex flex-1 flex-col gap-0.5 rounded-xl border border-secondary bg-primary p-4 shadow-xs">
        <div className="flex items-center gap-1">
            <span className="text-xs font-medium text-tertiary">{label}</span>
            {tooltip && <FontAwesomeIcon icon={faCircleInfo} className="size-3 text-fg-quaternary" title={tooltip} />}
        </div>
        <span className="text-md font-bold text-primary">{value}</span>
        <span className="text-[10px] text-tertiary">{description}</span>
    </div>
);

const formatPercent = (value: number): string => {
    if (isNaN(value) || !isFinite(value)) return '0%';
    return `${Math.round(value)}%`;
};

const formatMinutes = (minutes: number | null): string => {
    if (minutes === null) return '—';
    if (minutes < 60) return `${minutes}m`;
    const hours = Math.floor(minutes / 60);
    const mins = minutes % 60;
    return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
};

interface DashboardKpiProps {
    calls: Call[];
    leads: Lead[];
}

export const DashboardKpi = ({ calls, leads }: DashboardKpiProps) => {
    const totalCalls = calls.length;
    const inboundCalls = calls.filter((c) => c.callDirection === 'INBOUND').length;
    const outboundCalls = calls.filter((c) => c.callDirection === 'OUTBOUND').length;
    const missedCalls = calls.filter((c) => c.callStatus === 'MISSED').length;

    const leadsWithResponse = leads.filter((l) => l.createdAt && l.firstContactedAt);
    const avgResponseTime = leadsWithResponse.length > 0
        ? Math.round(leadsWithResponse.reduce((sum, l) => {
            const diff = Math.abs(new Date(l.firstContactedAt!).getTime() - new Date(l.createdAt!).getTime()) / 60000;
            return sum + diff;
        }, 0) / leadsWithResponse.length)
        : null;

    const missedCallsList = calls.filter((c) => c.callStatus === 'MISSED' && c.startedAt);
    const missedCallbackTime = missedCallsList.length > 0
        ? Math.round(missedCallsList.reduce((sum, c) => sum + (Date.now() - new Date(c.startedAt!).getTime()) / 60000, 0) / missedCallsList.length)
        : null;

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

    const leadToAppt = leads.length > 0
        ? (leads.filter((l) => l.leadStatus === 'APPOINTMENT_SET' || l.leadStatus === 'CONVERTED').length / leads.length) * 100
        : 0;

    return (
        <div className="space-y-4">
            <div className="grid grid-cols-2 gap-3 xl:grid-cols-4">
                <KpiCard label="Total Calls" value={totalCalls} icon={faPhone} iconColor="text-fg-brand-primary" iconBg="bg-brand-secondary" tooltip="Total inbound + outbound calls in the selected period" />
                <KpiCard label="Inbound" value={inboundCalls} icon={faPhoneArrowDownLeft} iconColor="text-fg-success-primary" iconBg="bg-success-secondary" tooltip="Calls received from patients/leads" />
                <KpiCard label="Outbound" value={outboundCalls} icon={faPhoneArrowUpRight} iconColor="text-fg-brand-primary" iconBg="bg-brand-secondary" tooltip="Calls made by agents to patients/leads" />
                <KpiCard label="Missed" value={missedCalls} icon={faPhoneMissed} iconColor="text-fg-error-primary" iconBg="bg-error-secondary"
                    subtitle={totalCalls > 0 ? `${formatPercent((missedCalls / totalCalls) * 100)} of total` : undefined}
                    tooltip="Inbound calls that were not answered by any agent" />
            </div>
            <div className="grid grid-cols-2 gap-3 xl:grid-cols-4">
                <MetricCard label="Avg Response" value={formatMinutes(avgResponseTime)} description="Lead creation to first contact" tooltip="Average time between a lead being created and an agent making first contact" />
                <MetricCard label="Missed Callback" value={formatMinutes(missedCallbackTime)} description="Avg wait for missed callbacks" tooltip="Average time missed calls have been waiting for a callback" />
                <MetricCard label="Call → Appt" value={formatPercent(callToAppt)} description="Calls resulting in bookings" tooltip="Percentage of calls where the outcome was an appointment booking" />
                <MetricCard label="Lead → Appt" value={formatPercent(leadToAppt)} description="Leads converted to appointments" tooltip="Percentage of leads that reached APPOINTMENT_SET or CONVERTED status" />
            </div>
        </div>
    );
};
