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 {
    Combobox,
    ComboboxContent,
    ComboboxEmpty,
    ComboboxInput,
    ComboboxItem,
    ComboboxList,
} from '@/components/ui/combobox';
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import {
    EllipsisVertical,
    FolderClosed,
    Loader,
    Plus,
    SearchIcon,
    X,
} 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 { Label } from '@/components/ui/label';

interface ProductsData {
    id: number;
    qty: number;
    name: number;
    price: number;
}
interface CompanyData {
    id: number;
    name: string;
    phone: string;
    address?: string;
}
interface TableData {
    id: any;
    subtotal: number;
    payable: number;
    payment?: number | 0;
    due?: number | 0;
    date: string;
    company?: {
        id: number;
        name: string;
        phone?: string;
    };
    products: ProductsData[];
}
interface BankData {
    id: number;
    label: string;
    bank_name: string;
    balance?: number | 0;
}
interface StaticData {
    totalPurchaseAmount: number;
    totalPayment: number;
    totalDue: number;
    totalPurchase: number;
}
interface FilterData {
    search?: string;
    company_id?: number;
    start_at?: string;
    end_at?: 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;
    stats: StaticData;
    company?: CompanyData[];
    bank?: BankData[];
}

interface DueForm {
    id: number | null;
    amount: number | 0;
    bank: number | null;
    note?: string | '';
    date: string;
    oldAmount?: number | 0;
}

export default function index({
    data: initData,
    filter,
    stats,
    company,
    bank,
}: PageProps) {
    // search
    const [search, setSearch] = useState(filter?.search || '');
    const [searchCompany, setSearchCompany] = useState<number | ''>(
        filter?.company_id || '',
    );
    const [searchStartAt, setSearchStartAt] = useState(filter?.start_at || '');
    const [searchEndAt, setSearchEndAt] = useState(filter?.end_at || '');
    const isFirstRender = useRef(true);
    useEffect(() => {
        if (isFirstRender.current) {
            isFirstRender.current = false;
            return;
        }
        const delayDebounceFn = setTimeout(() => {
            router.get(
                route('purchase.index'),
                {
                    search: search,
                    company_id: searchCompany,
                    start_at: searchStartAt,
                    end_at: searchEndAt,
                },
                {
                    preserveState: true,
                    replace: true,
                },
            );
        }, 500);
        return () => clearTimeout(delayDebounceFn);
    }, [search, searchCompany, searchStartAt, searchEndAt]);

    // statics
    const staticsData = [
        {
            name: 'Total Purchases',
            stat: stats.totalPurchaseAmount?.toLocaleString('en-BD', {
                minimumFractionDigits: 1,
                maximumFractionDigits: 1,
            }),
        },
        {
            name: 'Total Payment',
            stat: `+${stats.totalPayment?.toLocaleString('en-BD', {
                minimumFractionDigits: 1,
                maximumFractionDigits: 1,
            })}`,
        },
        {
            name: 'Total Due',
            stat: `-${stats.totalDue?.toLocaleString('en-BD', {
                minimumFractionDigits: 1,
                maximumFractionDigits: 1,
            })}`,
        },
        {
            name: 'Total Transactions',
            stat: stats.totalPurchase,
        },
    ];

    // view
    const [viewModal, setViewModal] = useState<ProductsData[] | null>(null);
    const viewModelSubtotal = viewModal?.reduce((total, p) => {
        return (total += p.price * p.qty);
    }, 0);

    // due dialog
    const [dueDialog, setDueDialog] = useState(false);
    const dueForm = useForm<DueForm>({
        id: null,
        amount: 0,
        bank: null,
        note: '',
        date: new Date().toISOString().split('T')[0],
        oldAmount: 0,
    });
    const handleDueForm = (e: React.FormEvent) => {
        e.preventDefault();
        dueForm.post(route('purchase.due'), {
            preserveScroll: true,
            onSuccess: () => {
                dueForm.reset();
                setDueDialog(false);
            },
        });
    };
    // warning
    const [amountWarning, setAmountWarning] = useState(false);
    useEffect(() => {
        if (!dueForm.data.bank || Number(dueForm.data.amount) <= 0) {
            setAmountWarning(false);
            return;
        }

        const currentBank = bank?.find(
            (b) => b.id === Number(dueForm.data.bank),
        );

        setAmountWarning(
            Number(currentBank?.balance ?? 0) < Number(dueForm.data.amount),
        );
    }, [dueForm.data.bank, dueForm.data.amount, bank]);
    return (
        <Layout title="Purchases">
            <PageHeader
                title="All Purchases"
                subtitle="Track and manage all your business purchases and payments."
            >
                <div className="flex flex-col items-center gap-2 md:flex-row">
                    <InputGroup className="w-full md:max-w-40">
                        <InputGroupInput
                            type="search"
                            placeholder="Search..."
                            onChange={(e) => setSearch(e.target.value)}
                            value={search}
                        />
                        <InputGroupAddon align="inline-start">
                            <SearchIcon className="text-muted-foreground" />
                        </InputGroupAddon>
                    </InputGroup>
                    <div className="flex flex-col items-center gap-2 md:flex-row">
                        <Combobox
                            items={company}
                            onValueChange={(value) =>
                                setSearchCompany(Number(value) || '')
                            }
                        >
                            <ComboboxInput
                                value={
                                    company?.find(
                                        (p) => p.id == filter?.company_id,
                                    )?.name ?? ''
                                }
                                placeholder="Select a company"
                                showClear
                                className="w-full md:max-w-40"
                            />
                            <ComboboxContent>
                                <ComboboxEmpty>No items found.</ComboboxEmpty>
                                <ComboboxList>
                                    {(item) => (
                                        <ComboboxItem
                                            key={item.id}
                                            value={item.id}
                                        >
                                            {item.name}
                                        </ComboboxItem>
                                    )}
                                </ComboboxList>
                            </ComboboxContent>
                        </Combobox>
                        <div className="grid grid-cols-2 gap-2">
                            <Input
                                type="date"
                                value={searchStartAt}
                                onChange={(e) =>
                                    setSearchStartAt(e.target.value)
                                }
                            />
                            <Input
                                type="date"
                                value={searchEndAt}
                                onChange={(e) => setSearchEndAt(e.target.value)}
                            />
                        </div>
                        <Button
                            onClick={() => router.get(route('purchase.add'))}
                        >
                            <Plus className="size-4" />
                            New Purchases
                        </Button>
                        {(search ||
                            searchStartAt ||
                            searchEndAt ||
                            searchCompany) && (
                            <Button
                                onClick={() =>
                                    router.get(route('purchase.index'))
                                }
                                variant="destructive"
                                size="icon"
                            >
                                <X />
                            </Button>
                        )}
                    </div>
                </div>
            </PageHeader>

            <div className="mb-5 flex w-full items-center justify-center">
                <dl className="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
                    {staticsData.map((item) => (
                        <Card className="p-6 py-4 shadow-2xs" key={item.name}>
                            <CardContent className="p-0">
                                <dt className="text-sm font-medium text-muted-foreground">
                                    {item.name}
                                </dt>
                                <dd className="mt-2 flex items-baseline space-x-2.5">
                                    <span className="text-3xl font-semibold text-foreground tabular-nums">
                                        {item.stat}
                                    </span>
                                </dd>
                            </CardContent>
                        </Card>
                    ))}
                </dl>
            </div>

            <Card>
                <CardContent>
                    {initData?.data?.length > 0 ? (
                        <Table>
                            <TableHeader>
                                <TableRow>
                                    <TableHead className="w-25">ID</TableHead>
                                    <TableHead>Date</TableHead>
                                    <TableHead>Company</TableHead>
                                    <TableHead className="text-right">
                                        Subtotal
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Payable
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Payment
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Due
                                    </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.date}</TableCell>
                                        <TableCell>
                                            <p className="font-medium">
                                                {items.company?.name}
                                            </p>
                                            <p className="text-xs">
                                                {items.company?.phone}
                                            </p>
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {items.subtotal.toLocaleString(
                                                'en-BD',
                                                {
                                                    minimumFractionDigits: 1,
                                                    maximumFractionDigits: 1,
                                                },
                                            )}
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {items.payable.toLocaleString(
                                                'en-BD',
                                                {
                                                    minimumFractionDigits: 1,
                                                    maximumFractionDigits: 1,
                                                },
                                            )}
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {(
                                                items.payment || 0
                                            ).toLocaleString('en-BD', {
                                                minimumFractionDigits: 1,
                                                maximumFractionDigits: 1,
                                            })}
                                        </TableCell>
                                        <TableCell className="text-right text-destructive">
                                            {(items?.due || 0).toLocaleString(
                                                'en-BD',
                                                {
                                                    minimumFractionDigits: 1,
                                                    maximumFractionDigits: 1,
                                                },
                                            )}
                                        </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">
                                                    {(items?.due || 0) > 0 && (
                                                        <DropdownMenuItem
                                                            onClick={() => {
                                                                dueForm.setData(
                                                                    'id',
                                                                    items.id,
                                                                );
                                                                dueForm.setData(
                                                                    'oldAmount',
                                                                    items.due,
                                                                );
                                                                setDueDialog(
                                                                    true,
                                                                );
                                                            }}
                                                        >
                                                            Payment Due
                                                        </DropdownMenuItem>
                                                    )}
                                                    <DropdownMenuItem
                                                        onClick={() => {
                                                            setViewModal(
                                                                items.products ??
                                                                    null,
                                                            );
                                                        }}
                                                    >
                                                        View Purchases
                                                    </DropdownMenuItem>
                                                    <DropdownMenuItem
                                                        onClick={() => {
                                                            router.get(
                                                                route(
                                                                    'purchase.transactions',
                                                                    {
                                                                        id: items
                                                                            .company
                                                                            ?.id,
                                                                        pid: items.id,
                                                                    },
                                                                ),
                                                            );
                                                        }}
                                                    >
                                                        Transactions
                                                    </DropdownMenuItem>
                                                    <DropdownMenuSeparator />
                                                    <DropdownMenuItem
                                                        variant="destructive"
                                                        onClick={() => {
                                                            router.get(
                                                                route(
                                                                    'purchase.delete',
                                                                    {
                                                                        id: items.id,
                                                                    },
                                                                ),
                                                            );
                                                        }}
                                                    >
                                                        Delete
                                                    </DropdownMenuItem>
                                                </DropdownMenuContent>
                                            </DropdownMenu>
                                        </TableCell>
                                    </TableRow>
                                ))}
                            </TableBody>
                        </Table>
                    ) : (
                        <Empty>
                            <EmptyHeader>
                                <EmptyMedia variant="icon">
                                    <FolderClosed />
                                </EmptyMedia>
                                <EmptyTitle>No Purchases Yet</EmptyTitle>
                                <EmptyDescription>
                                    You haven't recorded any purchases yet. Get
                                    started by creating your first purchase.
                                </EmptyDescription>
                            </EmptyHeader>
                        </Empty>
                    )}

                    <AppPagination data={initData} />
                </CardContent>
            </Card>

            {/* view model */}
            <Dialog open={viewModal ? true : false}>
                <DialogContent showCloseButton={false} className="md:max-w-150">
                    <DialogHeader className="border-b border-border pb-2">
                        <DialogTitle>Purchase Details</DialogTitle>
                        <DialogDescription>
                            Review the purchase details, including products,
                            quantities, payments, and transaction information.
                        </DialogDescription>
                    </DialogHeader>

                    <div className="max-h-200 w-full space-y-5 overflow-auto">
                        <Table>
                            <TableHeader>
                                <TableRow>
                                    <TableHead className="w-[100px]">
                                        Name
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Price
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Quantity
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Subtotal
                                    </TableHead>
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {viewModal?.map((invoice, i) => (
                                    <TableRow key={i}>
                                        <TableCell className="font-medium">
                                            {invoice.name}
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {invoice.price.toLocaleString(
                                                'en-BD',
                                            )}
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {invoice.qty}
                                        </TableCell>
                                        <TableCell className="text-right">
                                            {(
                                                invoice.price * invoice.qty
                                            ).toLocaleString('en-BD')}
                                        </TableCell>
                                    </TableRow>
                                ))}
                            </TableBody>
                            <TableFooter>
                                <TableRow>
                                    <TableCell colSpan={3}>Total</TableCell>
                                    <TableCell className="text-right">
                                        {viewModelSubtotal?.toLocaleString(
                                            'en-BD',
                                        )}
                                    </TableCell>
                                </TableRow>
                            </TableFooter>
                        </Table>
                    </div>

                    <DialogFooter className="flex items-center justify-end gap-2">
                        <Button
                            onClick={() => {
                                setViewModal(null);
                            }}
                            size="sm"
                            variant="outline"
                        >
                            Close
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            {/* due dialog */}
            <Dialog open={dueDialog}>
                <DialogContent showCloseButton={false} className="md:w-120">
                    <DialogHeader className="border-b border-border pb-2">
                        <DialogTitle>Make Due Payment</DialogTitle>
                        <DialogDescription>
                            Record a payment against your outstanding due to
                            keep your purchase balance and financial records up
                            to date.
                        </DialogDescription>
                    </DialogHeader>

                    <div className="w-full space-y-5">
                        <Card>
                            <CardHeader>
                                <CardTitle>Total Payable</CardTitle>
                                <CardDescription>
                                    {(
                                        dueForm.data.oldAmount || 0
                                    ).toLocaleString('en-BD')}{' '}
                                    Tk
                                </CardDescription>
                            </CardHeader>
                        </Card>
                        <Field>
                            <FieldLabel htmlFor="checkout-7j9-card-name-43j">
                                Bank*
                            </FieldLabel>
                            <Combobox
                                items={bank}
                                onValueChange={(value) =>
                                    dueForm.setData(
                                        'bank',
                                        Number(value) || null,
                                    )
                                }
                            >
                                <ComboboxInput
                                    value={
                                        bank?.find(
                                            (p) => p.id == dueForm.data.bank,
                                        )?.label ?? ''
                                    }
                                    placeholder="Select a bank"
                                    showClear
                                />
                                <ComboboxContent>
                                    <ComboboxEmpty>
                                        No items found.
                                    </ComboboxEmpty>
                                    <ComboboxList>
                                        {(item) => (
                                            <ComboboxItem
                                                key={item.id}
                                                value={item.id}
                                            >
                                                {item.label} - {item.balance}
                                            </ComboboxItem>
                                        )}
                                    </ComboboxList>
                                </ComboboxContent>
                            </Combobox>
                            {amountWarning && (
                                <FieldDescription className="text-destructive">
                                    Insufficient bank balance. Available
                                    balance: ৳
                                    {Number(
                                        bank?.find(
                                            (b) =>
                                                b.id ===
                                                Number(dueForm.data.bank),
                                        )?.balance ?? 0,
                                    ).toLocaleString('en-BD', {
                                        minimumFractionDigits: 2,
                                    })}
                                </FieldDescription>
                            )}
                            {dueForm.errors.bank && (
                                <FieldDescription className="text-destructive">
                                    {dueForm.errors.bank}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <Label>Amount*</Label>
                            <Input
                                type="number"
                                min={0}
                                value={dueForm.data.amount}
                                onChange={(e) => {
                                    let amount = Number(e.target.value || 0);
                                    if (
                                        amount > (dueForm.data.oldAmount || 0)
                                    ) {
                                        amount = dueForm.data.oldAmount || 0;
                                    }
                                    dueForm.setData('amount', amount);
                                }}
                            />
                            {dueForm.errors.amount && (
                                <FieldDescription className="text-destructive">
                                    {dueForm.errors.amount}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <Label>Date*</Label>
                            <Input
                                type="date"
                                value={dueForm.data.date}
                                onChange={(e) => {
                                    let date = e.target.value;
                                    dueForm.setData('date', date);
                                }}
                            />
                            {dueForm.errors.date && (
                                <FieldDescription className="text-destructive">
                                    {dueForm.errors.date}
                                </FieldDescription>
                            )}
                        </Field>
                        <Field>
                            <Label>Note</Label>
                            <Textarea
                                value={dueForm.data.note}
                                onChange={(e) => {
                                    dueForm.setData('note', e.target.value);
                                }}
                            />
                            {dueForm.errors.note && (
                                <FieldDescription className="text-destructive">
                                    {dueForm.errors.note}
                                </FieldDescription>
                            )}
                        </Field>
                    </div>

                    <DialogFooter className="flex items-center justify-end gap-2">
                        <Button
                            onClick={() => {
                                dueForm.reset();
                                setDueDialog(false);
                            }}
                            size="sm"
                            variant="outline"
                            disabled={dueForm.processing}
                        >
                            Close
                        </Button>
                        <Button
                            onClick={handleDueForm}
                            disabled={dueForm.processing}
                            size="sm"
                            variant="default"
                        >
                            {dueForm.processing ? (
                                <Loader className="animate-spin" />
                            ) : (
                                'Payment Now'
                            )}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </Layout>
    );
}
