import Layout from '@/components/Layout';
import React, { useEffect, useRef, useState } from 'react';
import {
    Table,
    TableBody,
    TableCell,
    TableFooter,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { EllipsisVertical, FolderClosed, Plus, SearchIcon } from 'lucide-react';
import {
    Empty,
    EmptyDescription,
    EmptyHeader,
    EmptyMedia,
    EmptyTitle,
} from '@/components/ui/empty';
import {
    InputGroup,
    InputGroupAddon,
    InputGroupInput,
} from '@/components/ui/input-group';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { router, useForm } from '@inertiajs/react';
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import AppPagination from '@/components/AppPagination';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import PageHeader from '@/components/PageHeader';
import { Badge } from '@/components/ui/badge';
import {
    Select,
    SelectContent,
    SelectGroup,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';

interface TableData {
    id: any;
    label: string;
    bank_name: string;
    owner_name?: string;
    owner_phone?: string;
    note?: string;
    balance?: number | 0;
    status: string;
    address?: string;
}
interface FilterData {
    search?: string;
}
interface LinkData {
    url: string | null;
    label: string;
    active: boolean;
}
interface PageProps {
    data: {
        data: TableData[];
        current_page: number;
        last_page: number;
        links: LinkData[];
        from: number | null;
        to: number | null;
        total: number;
    };
    filter?: FilterData;
}

const statusItems = [
    { label: 'Active', value: 'active' },
    { label: 'Inactive', value: 'inactive' },
];

export default function bank({ data: initData, filter }: PageProps) {
    const [formDialog, setFormDialog] = useState(false);

    // form
    const { data, setData, processing, post, reset, errors } = useForm({
        id: '',
        label: '',
        bank_name: '',
        owner_name: '',
        owner_phone: '',
        note: '',
        balance: 0,
        status: 'active',
    });
    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        post(route('bank.store'), {
            preserveScroll: true,
            onSuccess: () => {
                reset();
                setFormDialog(false);
            },
        });
    };

    // deposit
    const [depositModal, setDepositModal] = useState(false);
    const depositForm = useForm({
        id: '',
        amount: 0,
        date: new Date().toISOString().split('T')[0],
        note: '',
        type: '',
    });
    const handleDeposit = (e: React.FormEvent) => {
        e.preventDefault();
        depositForm.post(route('bank.deposit'), {
            preserveScroll: true,
            onSuccess: () => {
                depositForm.reset();
                setDepositModal(false);
            },
        });
    };

    const totalBalance = initData?.data?.reduce(
        (total, item) => total + Number(item.balance || 0),
        0,
    );

    // search
    const [search, setSearch] = useState(filter?.search || '');
    const isFirstRender = useRef(true);
    useEffect(() => {
        if (isFirstRender.current) {
            isFirstRender.current = false;
            return;
        }
        const delayDebounceFn = setTimeout(() => {
            router.get(
                route('bank.index'),
                { search: search },
                {
                    preserveState: true,
                    replace: true,
                },
            );
        }, 500);
        return () => clearTimeout(delayDebounceFn);
    }, [search]);
    return (
        <Layout title="Bank">
            <PageHeader
                title="All Banks"
                subtitle="Track and manage all your business bank accounts."
            >
                <div className="flex items-center gap-2">
                    <InputGroup>
                        <InputGroupInput
                            id="inline-start-input"
                            type="search"
                            placeholder="Search..."
                            onChange={(e) => setSearch(e.target.value)}
                            value={search}
                        />
                        <InputGroupAddon align="inline-start">
                            <SearchIcon className="text-muted-foreground" />
                        </InputGroupAddon>
                    </InputGroup>
                    <Button onClick={() => setFormDialog(true)}>
                        <Plus className="size-4" />
                        Add Bank
                    </Button>
                </div>
            </PageHeader>

            <Card>
                <CardContent>
                    {initData?.data?.length > 0 ? (
                        <Table>
                            <TableHeader>
                                <TableRow>
                                    <TableHead className="w-25">ID</TableHead>
                                    <TableHead>Label</TableHead>
                                    <TableHead>Bank</TableHead>
                                    <TableHead>Owner</TableHead>
                                    <TableHead>Note</TableHead>
                                    <TableHead className="text-right">
                                        Balance
                                    </TableHead>
                                    <TableHead>Status</TableHead>
                                    <TableHead className="text-right"></TableHead>
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {initData?.data?.map((items) => (
                                    <TableRow key={items.id}>
                                        <TableCell className="font-medium">
                                            {items.id}
                                        </TableCell>
                                        <TableCell>{items.label}</TableCell>
                                        <TableCell>{items.bank_name}</TableCell>
                                        <TableCell>
                                            <p>{items?.owner_name || '--'}</p>
                                            <p>{items?.owner_phone || '--'}</p>
                                        </TableCell>
                                        <TableCell>
                                            {items?.note || '--'}
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {items?.balance?.toLocaleString(
                                                'en-BD',
                                                {
                                                    minimumFractionDigits: 1,
                                                    maximumFractionDigits: 1,
                                                },
                                            )}
                                        </TableCell>
                                        <TableCell>
                                            <Badge
                                                variant={
                                                    items.status == 'active'
                                                        ? 'default'
                                                        : 'destructive'
                                                }
                                                className="capitalize"
                                            >
                                                {items.status}
                                            </Badge>
                                        </TableCell>
                                        <TableCell className="text-right">
                                            <DropdownMenu>
                                                <DropdownMenuTrigger
                                                    render={
                                                        <Button
                                                            variant="ghost"
                                                            size="icon"
                                                            className="size-8"
                                                        >
                                                            <EllipsisVertical />
                                                            <span className="sr-only">
                                                                Open menu
                                                            </span>
                                                        </Button>
                                                    }
                                                />
                                                <DropdownMenuContent align="end">
                                                    <DropdownMenuItem
                                                        onClick={() => {
                                                            setData(
                                                                'id',
                                                                items.id,
                                                            );
                                                            setData(
                                                                'balance',
                                                                items.balance ||
                                                                    0,
                                                            );
                                                            setData(
                                                                'bank_name',
                                                                items.bank_name,
                                                            );
                                                            setData(
                                                                'label',
                                                                items?.label,
                                                            );
                                                            setData(
                                                                'note',
                                                                items.note ||
                                                                    '',
                                                            );
                                                            setData(
                                                                'owner_name',
                                                                items.owner_name ||
                                                                    '',
                                                            );
                                                            setData(
                                                                'owner_phone',
                                                                items.owner_phone ||
                                                                    '',
                                                            );
                                                            setData(
                                                                'status',
                                                                items.status,
                                                            );
                                                            setFormDialog(true);
                                                        }}
                                                    >
                                                        Edit
                                                    </DropdownMenuItem>
                                                    <DropdownMenuItem
                                                        onClick={() => {
                                                            depositForm.setData(
                                                                'id',
                                                                items.id,
                                                            );
                                                            depositForm.setData(
                                                                'type',
                                                                'in',
                                                            );
                                                            setDepositModal(
                                                                true,
                                                            );
                                                        }}
                                                    >
                                                        Deposit
                                                    </DropdownMenuItem>
                                                    <DropdownMenuItem
                                                        onClick={() => {
                                                            depositForm.setData(
                                                                'id',
                                                                items.id,
                                                            );
                                                            depositForm.setData(
                                                                'type',
                                                                'out',
                                                            );
                                                            setDepositModal(
                                                                true,
                                                            );
                                                        }}
                                                    >
                                                        Withdrawal
                                                    </DropdownMenuItem>
                                                    <DropdownMenuItem
                                                        onClick={() => {
                                                            router.get(
                                                                route(
                                                                    'bank.transaction',
                                                                    {
                                                                        id: items.id,
                                                                    },
                                                                ),
                                                            );
                                                        }}
                                                    >
                                                        Transactions
                                                    </DropdownMenuItem>
                                                    <DropdownMenuSeparator />
                                                    <DropdownMenuItem
                                                        variant="destructive"
                                                        onClick={() => {
                                                            router.get(
                                                                route(
                                                                    'bank.delete',
                                                                    {
                                                                        id: items.id,
                                                                    },
                                                                ),
                                                            );
                                                        }}
                                                    >
                                                        Delete
                                                    </DropdownMenuItem>
                                                </DropdownMenuContent>
                                            </DropdownMenu>
                                        </TableCell>
                                    </TableRow>
                                ))}
                            </TableBody>
                            <TableFooter>
                                <TableRow>
                                    <TableCell colSpan={5}>Total</TableCell>
                                    <TableCell className="text-right">
                                        {totalBalance?.toLocaleString('en-BD', {
                                            minimumFractionDigits: 1,
                                            maximumFractionDigits: 1,
                                        })}
                                    </TableCell>
                                    <TableCell colSpan={2}></TableCell>
                                </TableRow>
                                <AppPagination data={initData} />
                            </TableFooter>
                        </Table>
                    ) : (
                        <Empty>
                            <EmptyHeader>
                                <EmptyMedia variant="icon">
                                    <FolderClosed />
                                </EmptyMedia>
                                <EmptyTitle>No Bank Yet</EmptyTitle>
                                <EmptyDescription>
                                    You haven't created any bank yet. Get
                                    started by creating your first bank.
                                </EmptyDescription>
                            </EmptyHeader>
                        </Empty>
                    )}

                    <AppPagination data={initData} />
                </CardContent>
            </Card>

            {/* add and update dialog */}
            <Dialog open={formDialog}>
                <DialogContent showCloseButton={false} className="md:max-w-150">
                    <DialogHeader className="border-b border-border pb-2">
                        <DialogTitle>Add New Bank</DialogTitle>
                        <DialogDescription>
                            Add bank details to keep your business accounts
                            organized and up to date.
                        </DialogDescription>
                    </DialogHeader>

                    <div className="grid w-full grid-cols-1 gap-5 md:grid-cols-2">
                        <Field>
                            <FieldLabel>Label*</FieldLabel>
                            <Input
                                type="text"
                                value={data.label}
                                onChange={(e) =>
                                    setData('label', e.target.value)
                                }
                            />
                            {errors.label && (
                                <FieldDescription className="text-destructive">
                                    {errors.label}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Starting Balance*</FieldLabel>
                            <Input
                                type="number"
                                min={0}
                                value={data.balance}
                                onChange={(e) =>
                                    setData(
                                        'balance',
                                        Number(e.target.value || 0),
                                    )
                                }
                            />
                            {errors.balance && (
                                <FieldDescription className="text-destructive">
                                    {errors.balance}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Bank Name*</FieldLabel>
                            <Input
                                type="text"
                                value={data.bank_name}
                                onChange={(e) =>
                                    setData('bank_name', e.target.value)
                                }
                            />
                            {errors.bank_name && (
                                <FieldDescription className="text-destructive">
                                    {errors.bank_name}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Owner Name</FieldLabel>
                            <Input
                                type="text"
                                value={data.owner_name}
                                onChange={(e) =>
                                    setData('owner_name', e.target.value)
                                }
                            />
                            {errors.owner_name && (
                                <FieldDescription className="text-destructive">
                                    {errors.owner_name}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Owner Phone</FieldLabel>
                            <Input
                                type="tel"
                                value={data.owner_phone}
                                onChange={(e) =>
                                    setData('owner_phone', e.target.value)
                                }
                            />
                            {errors.owner_phone && (
                                <FieldDescription className="text-destructive">
                                    {errors.owner_phone}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Status*</FieldLabel>
                            <Select
                                items={statusItems}
                                value={data.status}
                                onValueChange={(val) =>
                                    setData('status', String(val))
                                }
                            >
                                <SelectTrigger className="w-full">
                                    <SelectValue placeholder="Status" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectGroup>
                                        {statusItems.map((item) => (
                                            <SelectItem
                                                key={item.value}
                                                value={item.value}
                                            >
                                                {item.label}
                                            </SelectItem>
                                        ))}
                                    </SelectGroup>
                                </SelectContent>
                            </Select>
                            {errors.status && (
                                <FieldDescription className="text-destructive">
                                    {errors.status}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field className="col-span-1 md:col-span-2">
                            <FieldLabel>Note</FieldLabel>
                            <Textarea
                                value={data.note}
                                onChange={(e) =>
                                    setData('note', e.target.value)
                                }
                            />
                            {errors.note && (
                                <FieldDescription className="text-destructive">
                                    {errors.note}
                                </FieldDescription>
                            )}
                        </Field>
                    </div>

                    <DialogFooter className="flex items-center justify-end gap-2">
                        <Button
                            onClick={() => {
                                reset();
                                setFormDialog(false);
                            }}
                            size="sm"
                            variant="outline"
                        >
                            Close
                        </Button>
                        <Button
                            onClick={handleSubmit}
                            size="sm"
                            variant="default"
                            disabled={processing}
                        >
                            Save Now{processing && '...'}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            {/* deposit/withdrawal dialog */}
            <Dialog open={depositModal}>
                <DialogContent showCloseButton={false}>
                    <DialogHeader className="border-b border-border pb-2">
                        <DialogTitle>
                            {depositForm?.data.type == 'in'
                                ? 'Make a Bank Deposit'
                                : 'Make a Bank Withdrawal'}
                        </DialogTitle>
                        <DialogDescription>
                            {depositForm?.data.type == 'in'
                                ? 'Record a deposit to update your bank balance and keep your financial records accurate.'
                                : ' Record a withdrawal to update your bank balance and keep your financial records accurate.'}
                        </DialogDescription>
                    </DialogHeader>

                    <div className="grid w-full space-y-5">
                        <Field>
                            <FieldLabel>Amount*</FieldLabel>
                            <Input
                                type="number"
                                value={depositForm.data.amount}
                                onChange={(e) =>
                                    depositForm.setData(
                                        'amount',
                                        Number(e.target.value || 0),
                                    )
                                }
                            />
                            {depositForm.errors.amount && (
                                <FieldDescription className="text-destructive">
                                    {depositForm.errors.amount}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Date*</FieldLabel>
                            <Input
                                type="date"
                                value={depositForm.data.date}
                                onChange={(e) =>
                                    depositForm.setData('date', e.target.value)
                                }
                            />
                            {depositForm.errors.date && (
                                <FieldDescription className="text-destructive">
                                    {depositForm.errors.date}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <FieldLabel>Note</FieldLabel>
                            <Textarea
                                value={depositForm.data.note}
                                onChange={(e) =>
                                    depositForm.setData('note', e.target.value)
                                }
                            />
                            {depositForm.errors.note && (
                                <FieldDescription className="text-destructive">
                                    {depositForm.errors.note}
                                </FieldDescription>
                            )}
                        </Field>
                    </div>

                    <DialogFooter className="flex items-center justify-end gap-2">
                        <Button
                            onClick={() => {
                                depositForm.reset();
                                setDepositModal(false);
                            }}
                            size="sm"
                            variant="outline"
                        >
                            Close
                        </Button>
                        <Button
                            onClick={handleDeposit}
                            size="sm"
                            variant="default"
                            disabled={depositForm.processing}
                        >
                            Deposit Now{depositForm.processing && '...'}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </Layout>
    );
}
