import { ChevronDown, ChevronUp, Download, Loader2 } from 'lucide-react';
import { forwardRef, useRef, useState } from 'react';

import { cn } from '@/lib/utils';

import { exportElementToPdf } from './pdf';
import type { ReservationRow, ReservationsBlock } from './types';

const PREVIEW_ROWS = 6;
const priceFmt = new Intl.NumberFormat('fr-FR', { maximumFractionDigits: 2 });

function fmtDay(s: string, withYear = false): string {
    if (!s) return '—';
    const d = new Date(`${s}T00:00:00`);
    if (Number.isNaN(d.getTime())) return s;
    return d.toLocaleDateString('fr-FR', {
        day: 'numeric',
        month: 'short',
        ...(withYear ? { year: 'numeric' } : {}),
    });
}

function Badge({ className, children }: { className?: string; children: React.ReactNode }) {
    return (
        <span className={cn('inline-flex w-fit items-center rounded-full px-2 py-0.5 text-xs font-medium', className)}>
            {children}
        </span>
    );
}

function StatusBadge({ status }: { status: string }) {
    const s = status.toLowerCase();
    const cls = s.includes('confirm')
        ? 'bg-emerald-50 text-emerald-700 ring-1 ring-emerald-600/20'
        : s.includes('annul')
          ? 'bg-red-50 text-red-700 ring-1 ring-red-600/20'
          : 'bg-amber-50 text-amber-700 ring-1 ring-amber-600/20';
    return <Badge className={cls}>{status}</Badge>;
}

function PaidBadge({ row }: { row: ReservationRow }) {
    const cls =
        row.paid_state === 'paid'
            ? 'bg-emerald-50 text-emerald-700 ring-1 ring-emerald-600/20'
            : row.paid_state === 'unpaid'
              ? 'bg-red-50 text-red-700 ring-1 ring-red-600/20'
              : row.paid_state === 'pending'
                ? 'bg-amber-50 text-amber-700 ring-1 ring-amber-600/20'
                : 'bg-muted text-muted-foreground';
    return <Badge className={cls}>{row.paid}</Badge>;
}

export function ReservationsTable({ block, onDrill }: { block: ReservationsBlock; onDrill?: (question: string) => void }) {
    const [expanded, setExpanded] = useState(false);
    const [exporting, setExporting] = useState(false);
    const pdfRef = useRef<HTMLDivElement>(null);

    const rows = expanded ? block.rows : block.rows.slice(0, PREVIEW_ROWS);
    const remaining = block.rows.length - PREVIEW_ROWS;

    const handlePdf = async () => {
        if (!pdfRef.current || exporting) return;
        setExporting(true);
        try {
            await exportElementToPdf(pdfRef.current, 'reservations.pdf');
        } finally {
            setExporting(false);
        }
    };

    return (
        <div className="overflow-hidden rounded-xl border border-border bg-card">
            <div className="flex items-center justify-between gap-2 border-b border-border bg-muted/50 px-3 py-2">
                <div className="text-sm font-medium">
                    {block.title ?? 'Réservations'}
                    <span className="ml-1.5 text-xs font-normal text-muted-foreground">
                        {block.total} au total
                        {block.shown < block.total ? ` · ${block.shown} chargées` : ''}
                    </span>
                </div>
                <button
                    type="button"
                    onClick={handlePdf}
                    disabled={exporting}
                    className="inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border bg-background px-2.5 py-1 text-xs font-medium transition hover:border-secondary hover:text-secondary disabled:opacity-50"
                >
                    {exporting ? <Loader2 className="size-3.5 animate-spin" /> : <Download className="size-3.5" />}
                    PDF
                </button>
            </div>

            <table className="w-full border-collapse text-sm">
                <thead>
                    <tr className="text-xs text-muted-foreground">
                        <th className="px-3 py-2 text-left font-medium">Client</th>
                        <th className="px-3 py-2 text-left font-medium">Logement</th>
                        <th className="px-3 py-2 text-left font-medium">Séjour</th>
                        <th className="px-3 py-2 text-right font-medium">Prix</th>
                        <th className="px-3 py-2 text-left font-medium">Canal</th>
                        <th className="px-3 py-2 text-left font-medium">État</th>
                    </tr>
                </thead>
                <tbody>
                    {rows.map((r, i) => {
                        const clickable = !!(r.drill && onDrill);
                        return (
                        <tr
                            key={i}
                            onClick={clickable ? () => onDrill?.(r.drill!) : undefined}
                            className={cn('border-t border-border/60 align-top transition hover:bg-accent/40', clickable && 'cursor-pointer')}
                        >
                            <td className="px-3 py-2 font-medium">{r.client}</td>
                            <td className="px-3 py-2">{r.logement}</td>
                            <td className="px-3 py-2 text-muted-foreground">
                                <div className="whitespace-nowrap">
                                    {fmtDay(r.check_in)} → {fmtDay(r.check_out, true)}
                                </div>
                                <div className="text-xs opacity-80">
                                    {r.nights} nuit{r.nights > 1 ? 's' : ''}
                                </div>
                            </td>
                            <td className="px-3 py-2 text-right font-medium whitespace-nowrap">
                                {priceFmt.format(r.price)} {r.currency}
                            </td>
                            <td className="px-3 py-2">
                                <Badge className="bg-primary/10 text-primary ring-1 ring-primary/15">{r.channel}</Badge>
                            </td>
                            <td className="px-3 py-2">
                                <div className="flex flex-col gap-1">
                                    <StatusBadge status={r.status} />
                                    <PaidBadge row={r} />
                                </div>
                            </td>
                        </tr>
                        );
                    })}
                </tbody>
            </table>

            {block.rows.length > PREVIEW_ROWS && (
                <button
                    type="button"
                    onClick={() => setExpanded((v) => !v)}
                    className="flex w-full items-center justify-center gap-1 border-t border-border px-3 py-2 text-xs font-medium text-secondary transition hover:bg-accent/50"
                >
                    {expanded ? (
                        <>
                            <ChevronUp className="size-3.5" /> Voir moins
                        </>
                    ) : (
                        <>
                            <ChevronDown className="size-3.5" /> Voir plus ({remaining})
                        </>
                    )}
                </button>
            )}

            {/* Off-screen printable document (all loaded rows) captured for the PDF export. */}
            <div className="pointer-events-none fixed top-0 -left-[10000px]" aria-hidden>
                <PrintableReservations ref={pdfRef} title={block.title} total={block.total} rows={block.rows} />
            </div>
        </div>
    );
}

const cellStyle: React.CSSProperties = { padding: '6px 8px', color: '#0f172a', verticalAlign: 'top' };

const PrintableReservations = forwardRef<
    HTMLDivElement,
    { title?: string; total: number; rows: ReservationRow[] }
>(function PrintableReservations({ title, total, rows }, ref) {
    return (
        <div
            ref={ref}
            style={{ width: 800, padding: 24, background: '#ffffff', color: '#0f172a', fontFamily: 'Manrope, Arial, sans-serif' }}
        >
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
                <h1 style={{ fontSize: 18, fontWeight: 700, color: '#1b4e4d', margin: 0 }}>{title ?? 'Réservations'}</h1>
                <div style={{ fontSize: 12, color: '#64748b' }}>{total} réservations</div>
            </div>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 11 }}>
                <thead>
                    <tr style={{ background: '#f1f5f9' }}>
                        {['Client', 'Logement', 'Arrivée', 'Départ', 'Nuits', 'Prix', 'Canal', 'Statut', 'Paiement'].map((h) => (
                            <th key={h} style={{ textAlign: 'left', padding: '6px 8px', borderBottom: '1px solid #e2e8f0', color: '#475569' }}>
                                {h}
                            </th>
                        ))}
                    </tr>
                </thead>
                <tbody>
                    {rows.map((r, i) => (
                        <tr key={i} style={{ borderBottom: '1px solid #eef2f7' }}>
                            <td style={cellStyle}>{r.client}</td>
                            <td style={cellStyle}>{r.logement}</td>
                            <td style={cellStyle}>{r.check_in}</td>
                            <td style={cellStyle}>{r.check_out}</td>
                            <td style={cellStyle}>{r.nights}</td>
                            <td style={cellStyle}>
                                {priceFmt.format(r.price)} {r.currency}
                            </td>
                            <td style={cellStyle}>{r.channel}</td>
                            <td style={cellStyle}>{r.status}</td>
                            <td style={cellStyle}>{r.paid}</td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
});
