import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "@/components/ui/dialog"
import { Field, FieldGroup } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Expense } from '@/types';
import { useForm, router } from '@inertiajs/react';
import { useEffect, useState, useRef } from 'react';
import expenseRoutes from '@/routes/expense';
import { toast } from 'sonner';
import { NumericFormat } from 'react-number-format';
import { ImagePlus, X, Save, Loader } from 'lucide-react';

interface ExpenseFormModalProps {
    isOpen: boolean;
    onClose: () => void;
    expense: Expense | null;
}

export function ExpenseFormModal({ isOpen, onClose, expense }: ExpenseFormModalProps) {
    const isEditing = !!expense;
    const fileInputRef = useRef<HTMLInputElement>(null);
    const [imagePreview, setImagePreview] = useState<string | null>(null);

    const { data, setData, post, processing, errors, reset, clearErrors } = useForm<{
        name: string;
        amount: string;
        image: File | null;
    }>({
        name: '',
        amount: '',
        image: null,
    });

    useEffect(() => {
        if (expense) {
            setData({
                name: expense.name,
                amount: expense.amount.toString(),
                image: null,
            });
            setImagePreview(expense.proof_url || null);
        } else {
            reset();
            setImagePreview(null);
        }
    }, [expense]);

    const handleClose = () => {
        onClose();
        setTimeout(() => {
            reset();
            setImagePreview(null);
            clearErrors();
        }, 200);
    };

    const onImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file) {
            setData('image', file);
            const reader = new FileReader();
            reader.onloadend = () => {
                setImagePreview(reader.result as string);
            };
            reader.readAsDataURL(file);
        }
    };

    const removeImage = () => {
        setData('image', null);
        setImagePreview(null);
        if (fileInputRef.current) {
            fileInputRef.current.value = '';
        }
    };

    const onSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        if (isEditing && expense) {
            router.post(expenseRoutes.update(expense.id).url, {
                ...data,
                _method: 'PATCH',
            }, {
                onSuccess: (response: any) => {
                    toast.success(response.props.flash.success);
                    handleClose();
                },
            });
        } else {
            post(expenseRoutes.store().url, {
                onSuccess: (response: any) => {
                    toast.success(response.props.flash.success);
                    handleClose();
                },
            });
        }
    };

    return (
        <Dialog open={isOpen} onOpenChange={(open) => !open && handleClose()}>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>{isEditing ? 'Ubah Pengeluaran' : 'Tambah Pengeluaran'}</DialogTitle>
                </DialogHeader>
                <form onSubmit={onSubmit}>
                    <FieldGroup>
                        <Field>
                            <Label htmlFor="name" required>Nama</Label>
                            <Input
                                id="name"
                                name="name"
                                value={data.name}
                                onChange={e => setData('name', e.target.value)}
                                autoComplete='off'
                                placeholder='Contoh: Bayar Listrik'
                                maxLength={100}
                            />
                            {errors.name && <p className="text-xs text-red-500">{errors.name}</p>}
                        </Field>

                        <Field>
                            <Label htmlFor="amount" required>Nominal</Label>
                            <NumericFormat
                                id="amount"
                                customInput={Input}
                                thousandSeparator="."
                                decimalSeparator=","
                                prefix="Rp "
                                value={data.amount}
                                onValueChange={(values) => {
                                    setData('amount', values.value)
                                }}
                                placeholder="Rp 0"
                                autoComplete='off'
                            />
                            {errors.amount && <p className="text-xs text-red-500">{errors.amount}</p>}
                        </Field>

                        <Field>
                            <Label>Bukti</Label>
                            <div className="mt-2">
                                {imagePreview ? (
                                    <div className="relative inline-block">
                                        <img
                                            src={imagePreview}
                                            alt="Preview"
                                            className="object-cover rounded-lg border shadow-sm"
                                        />
                                        <button
                                            type="button"
                                            onClick={removeImage}
                                            className="absolute -top-2 -right-2 bg-red-500 text-white rounded-full p-1 shadow-md hover:bg-red-600 transition-colors"
                                        >
                                            <X className="h-4 w-4" />
                                        </button>
                                    </div>
                                ) : (
                                    <div
                                        onClick={() => fileInputRef.current?.click()}
                                        className="h-40 w-full flex flex-col items-center justify-center border-2 border-dashed rounded-lg cursor-pointer hover:bg-accent/50 transition-colors"
                                    >
                                        <ImagePlus className="h-8 w-8 text-muted-foreground mb-2" />
                                        <span className="text-sm text-muted-foreground font-medium">Klik untuk upload bukti</span>
                                        <span className="text-xs text-muted-foreground mt-1">PNG, JPG up to 5MB</span>
                                    </div>
                                )}
                                <input
                                    type="file"
                                    ref={fileInputRef}
                                    className="hidden"
                                    accept="image/*"
                                    onChange={onImageChange}
                                />
                            </div>
                            {errors.image && <p className="text-xs text-red-500 mt-1">{errors.image}</p>}
                        </Field>
                    </FieldGroup>
                    <DialogFooter className="mt-6">
                        <Button type="button" variant="outline" className="gap-2" onClick={handleClose}>
                            <X className="size-4" />
                            Batal
                        </Button>
                        <Button type="submit" className="gap-2" disabled={processing}>
                            {processing ? <Loader className="size-4 animate-spin" /> : <Save className="size-4" />}
                            {processing ? 'Menyimpan...' : 'Simpan'}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
