import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { router } from '@inertiajs/react';
import axios from 'axios';
import { FileSpreadsheet, Loader2 } from 'lucide-react';
import * as React from 'react';
import { toast } from 'sonner';
import { FrDateInput } from './fr-date-input';

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

interface EditData {
    type: 'expense';
    id: number;
    fields: {
        date_dep: string | null;
        title: string | null;
        amount: number;
        housing_id: number | null;
        pic_name: string | null;
    };
    context: {
        property_name: string | null;
    };
}

export function ExpenseEditDialog({ open, onOpenChange, expenseId }: Props) {
    const [data, setData] = React.useState<EditData | null>(null);
    const [loading, setLoading] = React.useState(false);
    const [submitting, setSubmitting] = React.useState(false);

    const [dateDep, setDateDep] = React.useState('');
    const [title, setTitle] = React.useState('');
    const [amount, setAmount] = React.useState<number>(0);
    const [picFile, setPicFile] = React.useState<File | null>(null);

    React.useEffect(() => {
        if (!open || !expenseId) return;
        let cancelled = false;
        setLoading(true);
        setData(null);
        setPicFile(null);
        axios
            .get<EditData>(`/fond-de-caisse/source/expense/${expenseId}/edit-data`)
            .then((res) => {
                if (cancelled) return;
                setData(res.data);
                const f = res.data.fields;
                setDateDep(f.date_dep ?? new Date().toISOString().slice(0, 10));
                setTitle(f.title ?? '');
                setAmount(f.amount);
            })
            .catch(() => toast.error('Erreur lors du chargement de la dépense'))
            .finally(() => {
                if (!cancelled) setLoading(false);
            });
        return () => { cancelled = true; };
    }, [open, expenseId]);

    const submit = () => {
        if (!data || submitting) return;
        if (amount <= 0) {
            toast.error('Saisissez un montant supérieur à 0');
            return;
        }
        if (title.trim().length === 0) {
            toast.error('Saisissez un titre');
            return;
        }

        const payload: Record<string, unknown> = {
            amount: amount.toFixed(2),
            title: title.trim(),
            date_dep: dateDep,
        };
        if (picFile) payload.pic_name = picFile;

        setSubmitting(true);
        router.post(
            route('depenses.update', { id: expenseId }),
            payload,
            {
                preserveScroll: true,
                only: ['rows', 'summary', 'flash'],
                forceFormData: true, // needed because pic_name may be a File
                onSuccess: () => {
                    toast.success('Dépense mise à jour');
                    onOpenChange(false);
                },
                onError: (errors) => {
                    const first = Object.values(errors)[0];
                    if (typeof first === 'string') toast.error(first);
                    else toast.error('Erreur lors de la mise à jour');
                },
                onFinish: () => setSubmitting(false),
            },
        );
    };

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="sm:max-w-xl">
                <DialogHeader>
                    <DialogTitle className="flex items-center gap-2">
                        <FileSpreadsheet className="h-5 w-5 text-amber-600" />
                        Modifier la dépense #{expenseId}
                    </DialogTitle>
                    <DialogDescription>
                        Les changements seront synchronisés dans la caisse automatiquement.
                    </DialogDescription>
                </DialogHeader>

                {loading && (
                    <div className="text-muted-foreground flex items-center gap-2 py-8 text-sm">
                        <Loader2 className="h-4 w-4 animate-spin" /> Chargement…
                    </div>
                )}

                {!loading && data && (
                    <div className="grid gap-4 py-2">
                        {data.context.property_name && (
                            <div className="bg-muted/40 border-input flex items-center gap-2 rounded-md border px-3 py-2 text-sm">
                                <span className="text-muted-foreground">Logement :</span>
                                <span className="font-medium">{data.context.property_name}</span>
                            </div>
                        )}

                        <div className="grid gap-1.5">
                            <Label className="text-sm">Date de la dépense</Label>
                            <FrDateInput value={dateDep} onChange={setDateDep} inputClassName="h-11 text-base" />
                        </div>

                        <div className="grid gap-1.5">
                            <Label className="text-sm">Titre</Label>
                            <Input
                                value={title}
                                onChange={(e) => setTitle(e.target.value)}
                                className="h-11"
                                placeholder="Description de la dépense…"
                            />
                        </div>

                        <div className="grid gap-1.5">
                            <Label className="text-sm">Montant (TND)</Label>
                            <Input
                                type="number"
                                step="0.01"
                                min="0"
                                value={amount || ''}
                                onChange={(e) => setAmount(parseFloat(e.target.value) || 0)}
                                placeholder="0.00"
                                className="h-11 text-right text-lg font-semibold tabular-nums text-red-700"
                            />
                        </div>

                        <div className="grid gap-1.5">
                            <Label className="text-sm">
                                Justificatif
                                {data.fields.pic_name && (
                                    <span className="text-muted-foreground ml-1 text-xs font-normal">
                                        (actuel : <code>{data.fields.pic_name}</code> — remplacé si vous choisissez un nouveau fichier)
                                    </span>
                                )}
                            </Label>
                            <Input
                                type="file"
                                accept="image/jpeg,image/png,image/jpg,image/gif,image/svg+xml"
                                onChange={(e) => setPicFile(e.target.files?.[0] ?? null)}
                                className="h-11"
                            />
                        </div>
                    </div>
                )}

                <DialogFooter>
                    <Button variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
                        Annuler
                    </Button>
                    <Button onClick={submit} disabled={loading || submitting || !data}>
                        {submitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                        Enregistrer
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
}
