import { Link, router } from '@inertiajs/react';
import { Banknote, Eye, MoreHorizontal, Pencil, Wallet } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { edit as purchasesEdit } from '@/actions/App/Http/Controllers/PurchaseController';
import { show as supplierAccount } from '@/actions/App/Http/Controllers/PurchaseSupplierAccountController';
import { PurchaseDetailsDialog } from '@/components/purchases/purchase-details-dialog';
import { PurchaseRecordPaymentDialog } from '@/components/purchases/purchase-record-payment-dialog';
import { PurchasePaymentStatusBadge } from '@/components/purchases/purchase-payment-status-badge';
import { Button } from '@/components/ui/button';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import {
    formatAppDateOrDash,
    formatMoneyAmountOrDash,
    formatPurchaseCurrencyLabel,
} from '@/lib/dates';
import { useSyncedState } from '@/hooks/use-synced-state';

/**
 * @param {object} props
 * @param {import('@inertiajs/core').Paginator<any>} props.purchases
 * @param {{ search: string, per_page: number }} props.filters
 * @param {Record<string, string>} props.labels
 * @param {Record<string, string>} props.paymentLabels
 * @param {Record<string, string>} props.validation
 * @param {Record<string, string>} props.appActions
 * @param {'en'|'fa'} props.locale
 * @param {(opts?: { query?: Record<string, string | number> }) => string} props.indexUrl
 * @param {boolean} [props.canUpdate]
 * @param {boolean} [props.canCreatePayments]
 * @param {boolean} [props.canViewSupplierAccount]
 * @param {Array<string>} [props.currencies]
 * @param {Array<string>} [props.paymentMethods]
 */
export function PurchasesTable({
    purchases,
    filters,
    labels,
    paymentLabels,
    validation,
    appActions,
    locale,
    indexUrl,
    canUpdate = false,
    canCreatePayments = false,
    canViewSupplierAccount = false,
    currencies = ['afn', 'usd'],
    paymentMethods = ['cash', 'bank', 'other'],
}) {
    const [search, setSearch] = useSyncedState(filters.search ?? '');
    const [paymentTarget, setPaymentTarget] = useState(null);
    const [paymentDialogOpen, setPaymentDialogOpen] = useState(false);
    const [detailsTarget, setDetailsTarget] = useState(null);
    const [detailsDialogOpen, setDetailsDialogOpen] = useState(false);

    useEffect(() => {
        const handle = setTimeout(() => {
            const next = search.trim();
            const current = (filters.search ?? '').trim();
            if (next === current) {
                return;
            }
            router.get(
                indexUrl({
                    query: {
                        search: next,
                        per_page: filters.per_page,
                        page: 1,
                    },
                }),
                {},
                { preserveState: true, preserveScroll: true, replace: true },
            );
        }, 350);

        return () => clearTimeout(handle);
    }, [search, filters.search, filters.per_page, indexUrl]);

    const rows = purchases?.data ?? [];
    const currentPage = purchases?.current_page ?? 1;
    const lastPage = purchases?.last_page ?? 1;
    const from = purchases?.from;
    const to = purchases?.to;
    const total = purchases?.total ?? 0;

    const summaryText = useMemo(() => {
        if (total === 0) {
            return labels.empty;
        }
        return labels.paginationSummary
            .replace('{from}', String(from ?? 0))
            .replace('{to}', String(to ?? 0))
            .replace('{total}', String(total));
    }, [from, to, total, labels.empty, labels.paginationSummary]);

    const pagePositionText = useMemo(
        () =>
            labels.paginationPages
                .replace('{page}', String(currentPage))
                .replace('{pages}', String(Math.max(lastPage, 1))),
        [currentPage, lastPage, labels.paginationPages],
    );

    function goToPage(page) {
        if (page < 1 || page > lastPage) {
            return;
        }
        router.get(
            indexUrl({
                query: {
                    search: filters.search ?? '',
                    per_page: filters.per_page,
                    page,
                },
            }),
            {},
            { preserveState: true, preserveScroll: true },
        );
    }

    function setPerPage(next) {
        router.get(
            indexUrl({
                query: {
                    search: filters.search ?? '',
                    per_page: next,
                    page: 1,
                },
            }),
            {},
            { preserveState: true, preserveScroll: true },
        );
    }

    function openPaymentDialog(row) {
        setPaymentTarget(row);
        setPaymentDialogOpen(true);
    }

    function openDetailsDialog(row) {
        setDetailsTarget(row);
        setDetailsDialogOpen(true);
    }

    function canRecordPaymentForRow(row) {
        return (
            canCreatePayments &&
            row.supplier_id != null &&
            Number(row.due_amount) > 0.001
        );
    }

    function canEditPurchase(row) {
        return canUpdate && !row.has_payments;
    }

    return (
        <div className="space-y-4">
            <PurchaseDetailsDialog
                purchase={detailsTarget}
                open={detailsDialogOpen}
                onOpenChange={(open) => {
                    setDetailsDialogOpen(open);
                    if (!open) {
                        setDetailsTarget(null);
                    }
                }}
                labels={labels}
                canUpdate={canUpdate}
            />

            <PurchaseRecordPaymentDialog
                purchase={paymentTarget}
                open={paymentDialogOpen}
                onOpenChange={(open) => {
                    setPaymentDialogOpen(open);
                    if (!open) {
                        setPaymentTarget(null);
                    }
                }}
                labels={paymentLabels}
                validation={validation}
                appActions={appActions}
                locale={locale}
                currencies={currencies}
                paymentMethods={paymentMethods}
            />

            <div className="flex max-w-sm flex-col gap-2">
                <Input
                    type="search"
                    value={search}
                    onChange={(e) => setSearch(e.target.value)}
                    placeholder={labels.searchPlaceholder}
                    className="h-9"
                />
            </div>

            <Table>
                <TableHeader>
                    <TableRow>
                        <TableHead>{labels.colSerial}</TableHead>
                        <TableHead>{labels.colBillNumber}</TableHead>
                        <TableHead>{labels.colProducts}</TableHead>
                        <TableHead>{labels.colTotal}</TableHead>
                        <TableHead>{labels.colPaid}</TableHead>
                        <TableHead>{labels.colDue}</TableHead>
                        <TableHead>{labels.colPaymentStatus}</TableHead>
                        <TableHead>{labels.colCurrency}</TableHead>
                        <TableHead>{labels.colDate}</TableHead>
                        <TableHead>{labels.colSupplier}</TableHead>
                        <TableHead>{labels.colAction}</TableHead>
                    </TableRow>
                </TableHeader>
                <TableBody>
                    {rows.length === 0 ? (
                        <TableRow>
                            <TableCell
                                colSpan={11}
                                className="text-muted-foreground h-24 text-center"
                            >
                                {labels.empty}
                            </TableCell>
                        </TableRow>
                    ) : (
                        rows.map((row, index) => (
                            <TableRow key={row.id}>
                                <TableCell className="text-muted-foreground tabular-nums">
                                    {from != null ? from + index : index + 1}
                                </TableCell>
                                <TableCell className="font-medium tabular-nums">
                                    <button
                                        type="button"
                                        onClick={() => openDetailsDialog(row)}
                                        className="text-primary text-start font-medium underline-offset-4 hover:underline"
                                    >
                                        {row.bill_number || '—'}
                                    </button>
                                </TableCell>
                                <TableCell className="max-w-xs whitespace-normal">
                                    <div className="font-medium">{row.items_summary || '—'}</div>
                                    {row.items_count > 0 ? (
                                        <div className="text-muted-foreground text-xs">
                                            {labels.itemsCountLabel.replace(
                                                '{count}',
                                                String(row.items_count),
                                            )}
                                        </div>
                                    ) : null}
                                </TableCell>
                                <TableCell className="tabular-nums font-medium">
                                    {formatMoneyAmountOrDash(row.total_amount, locale)}
                                </TableCell>
                                <TableCell className="tabular-nums">
                                    {formatMoneyAmountOrDash(row.paid_amount, locale)}
                                </TableCell>
                                <TableCell className="tabular-nums">
                                    {formatMoneyAmountOrDash(row.due_amount, locale)}
                                </TableCell>
                                <TableCell>
                                    <PurchasePaymentStatusBadge
                                        status={row.payment_status}
                                        labels={labels}
                                    />
                                </TableCell>
                                <TableCell>
                                    {formatPurchaseCurrencyLabel(row.currency, locale)}
                                </TableCell>
                                <TableCell>
                                    {formatAppDateOrDash(row.purchased_at, locale)}
                                </TableCell>
                                <TableCell>{row.supplier_name || '—'}</TableCell>
                                <TableCell>
                                    <DropdownMenu>
                                        <DropdownMenuTrigger asChild>
                                            <Button
                                                type="button"
                                                variant="ghost"
                                                size="icon"
                                                className="size-8"
                                                aria-label={labels.actionsMenuAria}
                                            >
                                                <MoreHorizontal className="size-4" />
                                            </Button>
                                        </DropdownMenuTrigger>
                                        <DropdownMenuContent align="end" className="min-w-44">
                                            <DropdownMenuItem
                                                onSelect={(e) => {
                                                    e.preventDefault();
                                                    openDetailsDialog(row);
                                                }}
                                            >
                                                <Eye className="size-4" />
                                                {labels.viewPurchaseDetails}
                                            </DropdownMenuItem>
                                            {canEditPurchase(row) ? (
                                                <DropdownMenuItem asChild>
                                                    <Link
                                                        href={purchasesEdit.url(row.id)}
                                                        prefetch
                                                    >
                                                        <Pencil className="size-4" />
                                                        {labels.editPurchase}
                                                    </Link>
                                                </DropdownMenuItem>
                                            ) : null}
                                            {canRecordPaymentForRow(row) ? (
                                                <DropdownMenuItem
                                                    onSelect={(e) => {
                                                        e.preventDefault();
                                                        openPaymentDialog(row);
                                                    }}
                                                >
                                                    <Banknote className="size-4" />
                                                    {labels.recordPayment}
                                                </DropdownMenuItem>
                                            ) : null}
                                            {canViewSupplierAccount && row.supplier_id ? (
                                                <>
                                                    {canEditPurchase(row) ||
                                                    canRecordPaymentForRow(row) ? (
                                                        <DropdownMenuSeparator />
                                                    ) : null}
                                                    <DropdownMenuItem asChild>
                                                        <Link
                                                            href={supplierAccount.url(
                                                                row.supplier_id,
                                                            )}
                                                            prefetch
                                                        >
                                                            <Wallet className="size-4" />
                                                            {labels.viewSupplierAccount}
                                                        </Link>
                                                    </DropdownMenuItem>
                                                </>
                                            ) : null}
                                        </DropdownMenuContent>
                                    </DropdownMenu>
                                </TableCell>
                            </TableRow>
                        ))
                    )}
                </TableBody>
            </Table>

            {total > 0 ? (
                <div className="flex flex-col gap-4 border-t border-border pt-4 sm:flex-row sm:items-center sm:justify-between">
                    <div className="flex flex-wrap items-center gap-2">
                        <Label
                            htmlFor="purchases-page-size"
                            className="text-muted-foreground whitespace-nowrap text-sm"
                        >
                            {labels.rowsPerPage}
                        </Label>
                        <select
                            id="purchases-page-size"
                            className="border-input bg-background h-9 rounded-md border px-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
                            value={filters.per_page}
                            onChange={(e) => setPerPage(Number(e.target.value))}
                        >
                            {[5, 10, 25, 50].map((n) => (
                                <option key={n} value={n}>
                                    {n}
                                </option>
                            ))}
                        </select>
                    </div>
                    <div className="flex flex-col gap-2 sm:items-end">
                        <span className="text-muted-foreground text-sm">{summaryText}</span>
                        <div className="flex flex-wrap items-center gap-2">
                            <Button
                                type="button"
                                variant="outline"
                                size="sm"
                                onClick={() => goToPage(currentPage - 1)}
                                disabled={currentPage <= 1}
                            >
                                {labels.paginationPrevious}
                            </Button>
                            <span className="text-muted-foreground min-w-[8rem] text-center text-sm tabular-nums">
                                {pagePositionText}
                            </span>
                            <Button
                                type="button"
                                variant="outline"
                                size="sm"
                                onClick={() => goToPage(currentPage + 1)}
                                disabled={currentPage >= lastPage}
                            >
                                {labels.paginationNext}
                            </Button>
                        </div>
                    </div>
                </div>
            ) : null}
        </div>
    );
}
