import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { router } from '@inertiajs/react';
import axios from 'axios';
import { AlertCircle, CheckCircle2, FileSpreadsheet, Loader2, Upload } from 'lucide-react';
import * as React from 'react';
import { toast } from 'sonner';

interface PreviewRow {
    line: number;
    date: string | null;
    designation: string;
    type: 'entree' | 'sortie' | null;
    amount: number | null;
    errors: string[];
    valid: boolean;
}

interface PreviewResponse {
    rows: PreviewRow[];
    total: number;
    valid_count: number;
    invalid_count: number;
}

interface Props {
    open: boolean;
    onOpenChange: (v: boolean) => void;
}

export function ImportDialog({ open, onOpenChange }: Props) {
    const [file, setFile] = React.useState<File | null>(null);
    const [preview, setPreview] = React.useState<PreviewResponse | null>(null);
    const [loading, setLoading] = React.useState(false);
    const [submitting, setSubmitting] = React.useState(false);

    const reset = () => {
        setFile(null);
        setPreview(null);
        setLoading(false);
        setSubmitting(false);
    };

    React.useEffect(() => {
        if (!open) reset();
    }, [open]);

    const onSelectFile = (f: File | null) => {
        setFile(f);
        setPreview(null);
        if (!f) return;
        upload(f);
    };

    const upload = async (f: File) => {
        const form = new FormData();
        form.append('file', f);
        setLoading(true);
        try {
            const res = await axios.post<PreviewResponse>(route('fond-de-caisse.import.preview'), form, {
                headers: { 'Content-Type': 'multipart/form-data' },
            });
            setPreview(res.data);
        } catch (e: any) {
            toast.error(e?.response?.data?.message ?? 'Erreur lors de la lecture du fichier');
        } finally {
            setLoading(false);
        }
    };

    const confirm = () => {
        if (!preview) return;
        const validRows = preview.rows.filter((r) => r.valid);
        if (validRows.length === 0) {
            toast.error('Aucune ligne valide à importer');
            return;
        }
        setSubmitting(true);
        router.post(
            route('fond-de-caisse.import.confirm'),
            { rows: validRows },
            {
                preserveScroll: true,
                only: ['rows', 'summary', 'flash'],
                onSuccess: () => {
                    onOpenChange(false);
                },
                onFinish: () => setSubmitting(false),
            },
        );
    };

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-4xl">
                <DialogHeader>
                    <DialogTitle>Importer des lignes</DialogTitle>
                    <DialogDescription>
                        Sélectionnez un fichier <strong>CSV</strong>. Colonnes attendues :{' '}
                        <code className="bg-muted px-1 rounded text-xs">date ; désignation ; entrée ; sortie</code>. Les
                        montants sont en <strong>TND</strong>. Une ligne avec une valeur en Entrée OU en Sortie (pas
                        les deux). Depuis Excel : <em>Fichier → Enregistrer sous → CSV UTF-8</em>.
                    </DialogDescription>
                </DialogHeader>

                {!preview && (
                    <div className="flex flex-col gap-3 py-2">
                        <label className="border-input flex flex-col items-center gap-2 rounded-lg border-2 border-dashed py-10 cursor-pointer hover:bg-muted/50">
                            <FileSpreadsheet className="text-muted-foreground h-10 w-10" />
                            <span className="text-sm font-medium">
                                {file ? file.name : 'Cliquez pour sélectionner un fichier'}
                            </span>
                            <span className="text-muted-foreground text-xs">CSV (séparateur ; ou ,)</span>
                            <Input
                                type="file"
                                accept=".csv,.txt"
                                className="hidden"
                                onChange={(e) => onSelectFile(e.target.files?.[0] ?? null)}
                            />
                        </label>
                        {loading && (
                            <div className="text-muted-foreground flex items-center gap-2 text-sm">
                                <Loader2 className="h-4 w-4 animate-spin" />
                                Analyse du fichier…
                            </div>
                        )}
                    </div>
                )}

                {preview && (
                    <>
                        <div className="flex items-center gap-4 text-sm">
                            <span className="flex items-center gap-1.5">
                                <CheckCircle2 className="h-4 w-4 text-emerald-600" />
                                <strong>{preview.valid_count}</strong> ligne(s) valides
                            </span>
                            {preview.invalid_count > 0 && (
                                <span className="flex items-center gap-1.5">
                                    <AlertCircle className="h-4 w-4 text-red-600" />
                                    <strong>{preview.invalid_count}</strong> ligne(s) avec erreurs (ignorées)
                                </span>
                            )}
                            <span className="text-muted-foreground ml-auto">Total : {preview.total}</span>
                        </div>

                        <div className="max-h-[400px] overflow-auto rounded-md border">
                            <Table className="text-sm">
                                <TableHeader className="bg-muted/50 sticky top-0">
                                    <TableRow>
                                        <TableHead className="w-12">#</TableHead>
                                        <TableHead className="w-28">Date</TableHead>
                                        <TableHead>Désignation</TableHead>
                                        <TableHead className="w-28 text-right">Entrée</TableHead>
                                        <TableHead className="w-28 text-right">Sortie</TableHead>
                                        <TableHead className="w-48">Statut</TableHead>
                                    </TableRow>
                                </TableHeader>
                                <TableBody>
                                    {preview.rows.map((r) => (
                                        <TableRow key={r.line} className={r.valid ? '' : 'bg-red-50'}>
                                            <TableCell className="text-muted-foreground">{r.line}</TableCell>
                                            <TableCell>{r.date ?? '—'}</TableCell>
                                            <TableCell>{r.designation}</TableCell>
                                            <TableCell className="text-right tabular-nums">
                                                {r.type === 'entree' && r.amount != null
                                                    ? r.amount.toLocaleString('fr-TN', { minimumFractionDigits: 2 })
                                                    : ''}
                                            </TableCell>
                                            <TableCell className="text-right tabular-nums">
                                                {r.type === 'sortie' && r.amount != null
                                                    ? r.amount.toLocaleString('fr-TN', { minimumFractionDigits: 2 })
                                                    : ''}
                                            </TableCell>
                                            <TableCell>
                                                {r.valid ? (
                                                    <span className="text-emerald-700 inline-flex items-center gap-1 text-xs">
                                                        <CheckCircle2 className="h-3.5 w-3.5" /> OK
                                                    </span>
                                                ) : (
                                                    <span className="text-red-700 text-xs">
                                                        {r.errors.join(', ')}
                                                    </span>
                                                )}
                                            </TableCell>
                                        </TableRow>
                                    ))}
                                </TableBody>
                            </Table>
                        </div>
                    </>
                )}

                <DialogFooter className="gap-2">
                    {preview && (
                        <Button variant="outline" onClick={() => setPreview(null)}>
                            Choisir un autre fichier
                        </Button>
                    )}
                    <Button variant="outline" onClick={() => onOpenChange(false)}>
                        Annuler
                    </Button>
                    <Button
                        disabled={!preview || preview.valid_count === 0 || submitting}
                        onClick={confirm}
                    >
                        {submitting ? (
                            <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                        ) : (
                            <Upload className="mr-2 h-4 w-4" />
                        )}
                        Importer {preview ? `${preview.valid_count} ligne(s)` : ''}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}
