import { router } from '@inertiajs/react';
import { useRef, useState, type ReactNode } from 'react';
import { Reveal } from '@/components/motion';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Dialog } from '@/components/ui/dialog';
import { FieldError } from '@/components/ui/label';
import { xsrfToken } from '@/lib/http';

type ImportResult = { created: number; updated: number; skipped: number; total: number; errors: { row: number; message: string }[] };

/** CSV import with a row-level report. Headers are matched loosely (Quotient / Outlook / spreadsheet exports). */
export function CsvImportDialog({ open, onOpenChange, url, reload, title, description, help, updateLabel }: {
    open: boolean; onOpenChange: (o: boolean) => void; url: string; reload: string; title: string; description: string; help: ReactNode; updateLabel: string;
}) {
    const file = useRef<HTMLInputElement>(null);
    const [update, setUpdate] = useState(false);
    const [busy, setBusy] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [result, setResult] = useState<ImportResult | null>(null);

    const run = async () => {
        const f = file.current?.files?.[0];
        if (!f) { setError('Choose a CSV file first.'); return; }
        setBusy(true); setError(null); setResult(null);
        try {
            const body = new FormData();
            body.append('file', f);
            body.append('update_existing', update ? '1' : '0');
            const res = await fetch(url, { method: 'POST', body, credentials: 'same-origin', headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest', 'X-XSRF-TOKEN': xsrfToken() } });
            const data = await res.json().catch(() => ({}));
            if (!res.ok) throw new Error(data?.errors?.file?.[0] ?? data?.message ?? 'Import failed.');
            setResult(data);
            if (data.created || data.updated) router.reload({ only: [reload] });
        } catch (e) {
            setError(e instanceof Error ? e.message : 'Import failed.');
        } finally {
            setBusy(false);
        }
    };
    const close = (o: boolean) => { onOpenChange(o); if (!o) { setResult(null); setError(null); if (file.current) file.current.value = ''; } };

    return (
        <Dialog open={open} onOpenChange={close} title={title} description={description}>
            <div className="space-y-4">
                <input ref={file} type="file" accept=".csv,text/csv" aria-label="CSV file" data-testid="import-file"
                    className="block w-full text-sm file:mr-3 file:rounded-md file:border file:border-line-strong file:bg-surface file:px-3 file:py-1.5 file:text-sm file:font-semibold" />
                <p className="text-xs text-ink-muted">{help}</p>
                <Checkbox label={updateLabel} checked={update} onChange={(e) => setUpdate(e.target.checked)} />
                <Reveal show={!!error}><FieldError message={error ?? undefined} /></Reveal>
                <Reveal show={!!result}>
                    {result && (
                        <div className="rounded-md border border-line bg-stone-50 p-3 text-sm" data-testid="import-result" role="status">
                            <p className="font-medium">
                                {result.created} added · {result.updated} updated · {result.skipped} skipped · {result.errors.filter((e) => !/skipped/.test(e.message)).length} with errors
                            </p>
                            {result.errors.length > 0 && (
                                <ul className="mt-2 max-h-48 space-y-1 overflow-auto text-xs">
                                    {result.errors.map((e, i) => <li key={i}><span className="font-mono text-ink-muted">Row {e.row}</span> {e.message}</li>)}
                                </ul>
                            )}
                        </div>
                    )}
                </Reveal>
                <div className="flex justify-end gap-2">
                    <Button variant="secondary" onClick={() => close(false)}>{result ? 'Done' : 'Cancel'}</Button>
                    <Button onClick={run} disabled={busy} data-testid="run-import">{busy ? 'Importing…' : 'Import'}</Button>
                </div>
            </div>
        </Dialog>
    );
}
