import { Head, useForm, router } from '@inertiajs/react';
import type { Expense } from '@/types';
import { ColumnDef } from '@tanstack/react-table';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Trash2, Pencil, ImagePlus, X } from 'lucide-react';
import { DataTable } from '@/components/data-table';
import { DataTableColumnHeader } from '@/components/data-table-column-header';
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 { useState, useRef } from 'react';
import { toast } from 'sonner';
import { TooltipContent, TooltipTrigger } from '@radix-ui/react-tooltip';
import { Tooltip } from '@/components/ui/tooltip';
import expenseRoutes from '@/routes/expense';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogMedia,
    AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { NumericFormat } from 'react-number-format';

export default function ExpenseIndex({ expenses }: { expenses: Expense[] }) {
    const [isOpen, setIsOpen] = useState(false);
    const [isEditing, setIsEditing] = useState(false);
    const [selectedExpense, setSelectedExpense] = useState<Expense | null>(null);

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

    const [imagePreview, setImagePreview] = useState<string | null>(null);
    const [selectedProof, setSelectedProof] = useState<string | null>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);

    const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
    const [isBulkDeleteDialogOpen, setIsBulkDeleteDialogOpen] = useState(false);
    const [expenseToDelete, setExpenseToDelete] = useState<Expense | null>(null);
    const [rowsToDelete, setRowsToDelete] = useState<any[]>([]);
    const [rowSelection, setRowSelection] = useState({});

    const onEdit = (expense: Expense) => {
        setIsEditing(true);
        setSelectedExpense(expense);
        setData({
            name: expense.name,
            amount: expense.amount.toString(),
            image: null,
        });
        setImagePreview(expense.proof_url || null);
        setIsOpen(true);
    };

    const onDelete = (expense: Expense) => {
        setExpenseToDelete(expense);
        setIsDeleteDialogOpen(true);
    };

    const confirmDelete = () => {
        if (expenseToDelete) {
            router.delete(expenseRoutes.destroy(expenseToDelete.id).url, {
                onSuccess: (response: any) => {
                    toast.success(response.props.flash.success);
                    setIsDeleteDialogOpen(false);
                    setExpenseToDelete(null);
                    setRowSelection({});
                },
            });
        }
    };

    const confirmBulkDelete = () => {
        router.post(expenseRoutes.bulkDestroy().url, {
            ids: rowsToDelete.map((row: any) => row.id),
            _method: 'DELETE'
        }, {
            onSuccess: (response: any) => {
                toast.success(response.props.flash.success);
                setIsBulkDeleteDialogOpen(false);
                setRowsToDelete([]);
                setRowSelection({});
            },
        });
    };

    const closeModal = () => {
        setIsOpen(false);
        setTimeout(() => {
            setIsEditing(false);
            setSelectedExpense(null);
            setImagePreview(null);
            reset();
            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 && selectedExpense) {
            router.post(expenseRoutes.update(selectedExpense.id).url, {
                ...data,
                _method: 'PATCH',
            }, {
                onSuccess: (response: any) => {
                    toast.success(response.props.flash.success);
                    closeModal();
                },
            });
        } else {
            post(expenseRoutes.store().url, {
                onSuccess: (response: any) => {
                    toast.success(response.props.flash.success);
                    closeModal();
                },
            });
        }
    };

    const formatCurrency = (amount: number) => {
        return new Intl.NumberFormat('id-ID', {
            style: 'currency',
            currency: 'IDR',
            minimumFractionDigits: 0,
        }).format(amount);
    };

    const columns: ColumnDef<Expense>[] = [
        {
            accessorKey: "proof_url",
            header: "Bukti",
            cell: ({ row }) => {
                const url = row.original.proof_url;
                return url ? (
                    <button onClick={() => setSelectedProof(url)} className="block w-fit">
                        <img src={url} alt="Proof" className="h-10 w-10 object-cover rounded-md border hover:opacity-80 transition-opacity" />
                    </button>
                ) : (
                    <div className="h-10 w-10 flex items-center justify-center bg-muted rounded-md border">
                        <ImagePlus className="h-4 w-4 text-muted-foreground" />
                    </div>
                );
            },
            meta: { title: "Bukti" },
        },
        {
            accessorKey: "user.name",
            header: ({ column }) => {
                return (
                    <DataTableColumnHeader column={column} title="Petugas" />
                )
            },
            cell: ({ row }) => row.original.user?.name,
            meta: { title: "Petugas" },
        },
        {
            accessorKey: "name",
            header: ({ column }) => {
                return (
                    <DataTableColumnHeader column={column} title="Nama" />
                )
            },
            meta: { title: "Nama" },
        },
        {
            accessorKey: "amount",
            header: ({ column }) => {
                return (
                    <DataTableColumnHeader column={column} title="Nominal" />
                )
            },
            cell: ({ row }) => formatCurrency(row.original.amount),
            meta: { title: "Nominal" },
        },
        {
            accessorKey: "created_at",
            header: ({ column }) => {
                return (
                    <DataTableColumnHeader column={column} title="Tanggal" />
                )
            },
            cell: ({ row }) => new Date(row.original.created_at).toLocaleDateString('id-ID', {
                day: '2-digit',
                month: 'long',
                year: 'numeric'
            }),
            meta: { title: "Tanggal" },
        },
        {
            id: "actions",
            header: "Aksi",
            cell: ({ row }) => {
                const expense = row.original;
                return (
                    <div className="flex items-center gap-2">
                        <Tooltip>
                            <TooltipTrigger>
                                <Button variant="ghost" size="icon" className='text-yellow-600' onClick={() => onEdit(expense)}>
                                    <Pencil className="size-4" />
                                </Button>
                            </TooltipTrigger>
                            <TooltipContent>
                                <p>Ubah</p>
                            </TooltipContent>
                        </Tooltip>
                        <Tooltip>
                            <TooltipTrigger asChild>
                                <Button variant="ghost" size="icon" className='text-red-600' onClick={() => onDelete(expense)}>
                                    <Trash2 className="size-4" />
                                </Button>
                            </TooltipTrigger>
                            <TooltipContent>
                                <p>Hapus</p>
                            </TooltipContent>
                        </Tooltip>
                    </div>
                );
            },
            meta: { title: "Aksi" },
        },
    ];

    return (
        <div className="flex flex-col gap-6 p-6">
            <Head title="Pengeluaran" />

            <div className="flex items-center justify-between">
                <div>
                    <h1 className="text-3xl font-bold tracking-tight">Pengeluaran</h1>
                </div>
                <Button onClick={() => setIsOpen(true)}>
                    Tambah
                </Button>
            </div>

            <Dialog open={isOpen} onOpenChange={(open) => !open && closeModal()}>
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>{isEditing ? 'Ubah Pengeluaran' : 'Tambah Pengeluaran'}</DialogTitle>
                    </DialogHeader>
                    <form onSubmit={onSubmit}>
                        <FieldGroup>
                            <Field>
                                <Label htmlFor="name">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">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" onClick={closeModal}>Batal</Button>
                            <Button type="submit" disabled={processing}>
                                {processing ? 'Menyimpan...' : 'Simpan'}
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>

            <Dialog open={!!selectedProof} onOpenChange={() => setSelectedProof(null)}>
                <DialogContent className="max-w-3xl p-0 overflow-hidden border-none bg-transparent shadow-none">
                    <div className="relative group">
                        <img
                            src={selectedProof || ''}
                            alt="Proof"
                            className="w-full h-auto max-h-[80vh] object-contain rounded-lg"
                        />
                        <button
                            onClick={() => setSelectedProof(null)}
                            className="absolute top-4 right-4 bg-black/50 hover:bg-black/70 text-white rounded-full p-2 backdrop-blur-sm transition-all shadow-xl"
                        >
                            <X className="size-5" />
                        </button>
                    </div>
                </DialogContent>
            </Dialog>

            <Card className="overflow-hidden border-none shadow-lg bg-card/50 backdrop-blur-sm p-5">
                <CardContent className="p-0">
                    <DataTable
                        columns={columns}
                        data={expenses}
                        rowSelection={rowSelection}
                        onRowSelectionChange={setRowSelection}
                        bulkActions={[
                            {
                                label: 'Hapus Terpilih',
                                onClick: (rows) => {
                                    setRowsToDelete(rows);
                                    setIsBulkDeleteDialogOpen(true);
                                },
                                icon: Trash2,
                                variant: 'destructive'
                            },
                        ]}
                    />
                </CardContent>
            </Card>

            <AlertDialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
                <AlertDialogContent size="default">
                    <AlertDialogHeader>
                        <AlertDialogMedia className="bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive">
                            <Trash2 className="size-5" />
                        </AlertDialogMedia>
                        <AlertDialogTitle>Hapus pengeluaran?</AlertDialogTitle>
                        <AlertDialogDescription>
                            Tindakan ini tidak dapat dibatalkan. Pengeluaran <strong>{expenseToDelete?.name}</strong> akan dihapus secara permanen.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel variant="outline">Batal</AlertDialogCancel>
                        <AlertDialogAction onClick={confirmDelete} variant="destructive">Hapus</AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>

            <AlertDialog open={isBulkDeleteDialogOpen} onOpenChange={setIsBulkDeleteDialogOpen}>
                <AlertDialogContent size="default">
                    <AlertDialogHeader>
                        <AlertDialogMedia className="bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive">
                            <Trash2 className="size-5" />
                        </AlertDialogMedia>
                        <AlertDialogTitle>Hapus {rowsToDelete.length} pengeluaran?</AlertDialogTitle>
                        <AlertDialogDescription>
                            Tindakan ini tidak dapat dibatalkan. <strong>{rowsToDelete.length}</strong> item yang terpilih akan dihapus secara permanen.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel variant="outline">Batal</AlertDialogCancel>
                        <AlertDialogAction
                            onClick={confirmBulkDelete}
                            variant="destructive"
                        >
                            Hapus
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
}

ExpenseIndex.layout = {
    breadcrumbs: [
        {
            title: 'Finance',
        },
    ],
};
