import { Link } from '@inertiajs/react';
import {
    flexRender,
    getCoreRowModel,
    getFilteredRowModel,
    getPaginationRowModel,
    getSortedRowModel,
    createColumnHelper,
    useReactTable,
} from '@tanstack/react-table';
import { ArrowDown, ArrowUp, ArrowUpDown, MoreHorizontal } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { show as expenseDayShow } from '@/actions/App/Http/Controllers/ExpenseDayController';
import { create as expenseCreate } from '@/actions/App/Http/Controllers/ExpenseController';
import { ExpenseStatusBadge } from '@/components/expenses/expense-status-badge';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    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 { createHiddenIdColumn, newestFirstSorting } from '@/lib/table-defaults';
import { formatExpenseDateNumericOrDash, formatExpenseWeekDayOrDash } from '@/lib/dates';
import { expensePaymentLabel, expenseCategoryLabel } from '@/lib/expense-labels';
import { cn } from '@/lib/utils';

const columnHelper = createColumnHelper();

function SortButton({ column, children }) {
    const sorted = column.getIsSorted();

    return (
        <Button type="button" variant="ghost" size="sm" className="-ms-2 h-8 font-medium" onClick={column.getToggleSortingHandler()}>
            {children}
            {sorted === 'asc' ? <ArrowUp className="ms-1 size-4 opacity-70" /> : sorted === 'desc' ? <ArrowDown className="ms-1 size-4 opacity-70" /> : <ArrowUpDown className="text-muted-foreground ms-1 size-4 opacity-50" />}
        </Button>
    );
}

export function ExpenseDaysDataTable({ expenseDays, labels, canCreate = false }) {
    const [sorting, setSorting] = useState(newestFirstSorting);
    const [columnVisibility, setColumnVisibility] = useState({ id: false });
    const [globalFilter, setGlobalFilter] = useState('');
    const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });

    useEffect(() => {
        setPagination((prev) => ({ ...prev, pageIndex: 0 }));
    }, [globalFilter, sorting]);

    const columns = useMemo(
        () => [
            createHiddenIdColumn(columnHelper),
            columnHelper.accessor('expense_date', {
                header: ({ column }) => <SortButton column={column}>{labels.colDate}</SortButton>,
                cell: (info) => {
                    const row = info.row.original;
                    return (
                        <div className="flex items-center gap-2">
                            <span className="font-medium">{formatExpenseDateNumericOrDash(row.expense_date)}</span>
                            {row.is_today ? <Badge>{labels.todayBadge}</Badge> : null}
                        </div>
                    );
                },
            }),
            columnHelper.accessor('day_label', {
                header: labels.colDay,
                cell: (info) => {
                    const row = info.row.original;
                    return formatExpenseWeekDayOrDash(row.expense_date);
                },
            }),
            columnHelper.accessor('expenses_count', {
                header: labels.colExpensesCount,
                cell: (info) => <span className="tabular-nums">{info.getValue()}</span>,
            }),
            columnHelper.accessor('total_afn', {
                header: labels.colTotal,
                cell: (info) => <span className="font-medium tabular-nums">{info.getValue()} {labels.currencyLabel}</span>,
            }),
            columnHelper.accessor('created_by_name', {
                header: labels.colCreatedBy,
                cell: (info) => info.getValue() ?? '—',
            }),
            columnHelper.display({
                id: 'actions',
                header: labels.colActions,
                cell: ({ row }) => (
                    <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="icon" className="size-8">
                                <MoreHorizontal className="size-4" />
                            </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                            <DropdownMenuItem asChild>
                                <Link href={expenseDayShow.url(row.original.id)}>{labels.showDayExpenses}</Link>
                            </DropdownMenuItem>
                            {canCreate ? (
                                <DropdownMenuItem asChild>
                                    <Link href={expenseCreate.url({ expenseDay: row.original.id })}>
                                        {labels.addExpenseForDay}
                                    </Link>
                                </DropdownMenuItem>
                            ) : null}
                        </DropdownMenuContent>
                    </DropdownMenu>
                ),
            }),
        ],
        [labels, canCreate],
    );

    const table = useReactTable({
        data: expenseDays,
        columns,
        state: { sorting, columnVisibility, globalFilter, pagination },
        onSortingChange: setSorting,
        onColumnVisibilityChange: setColumnVisibility,
        onGlobalFilterChange: setGlobalFilter,
        onPaginationChange: setPagination,
        getCoreRowModel: getCoreRowModel(),
        getSortedRowModel: getSortedRowModel(),
        getFilteredRowModel: getFilteredRowModel(),
        getPaginationRowModel: getPaginationRowModel(),
    });

    return (
        <div className="space-y-4">
            <div className="max-w-sm space-y-2">
                <Label htmlFor="expense-days-search">{labels.searchPlaceholder}</Label>
                <Input
                    id="expense-days-search"
                    value={globalFilter}
                    onChange={(e) => setGlobalFilter(e.target.value)}
                    placeholder={labels.searchPlaceholder}
                />
            </div>
            <div className="rounded-md border">
                <Table>
                    <TableHeader>
                        {table.getHeaderGroups().map((headerGroup) => (
                            <TableRow key={headerGroup.id}>
                                {headerGroup.headers.map((header) => (
                                    <TableHead key={header.id}>
                                        {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                                    </TableHead>
                                ))}
                            </TableRow>
                        ))}
                    </TableHeader>
                    <TableBody>
                        {table.getRowModel().rows.length ? (
                            table.getRowModel().rows.map((row) => (
                                <TableRow key={row.id} className={cn(row.original.is_today && 'bg-muted/40')}>
                                    {row.getVisibleCells().map((cell) => (
                                        <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
                                    ))}
                                </TableRow>
                            ))
                        ) : (
                            <TableRow>
                                <TableCell colSpan={columns.length} className="h-24 text-center text-muted-foreground">
                                    {labels.emptyTitle}
                                </TableCell>
                            </TableRow>
                        )}
                    </TableBody>
                </Table>
            </div>
        </div>
    );
}

export function ExpenseDayCategoryTable({ rows, labels, dayTotal }) {
    return (
        <div className="rounded-md border">
            <Table>
                <TableHeader>
                    <TableRow>
                        <TableHead>{labels.colCategory}</TableHead>
                        <TableHead>{labels.colExpensesCount}</TableHead>
                        <TableHead className="text-end">{labels.colAmount}</TableHead>
                    </TableRow>
                </TableHeader>
                <TableBody>
                    {rows.map((row) => (
                        <TableRow key={row.category_id}>
                            <TableCell>{expenseCategoryLabel(row.category_slug, row.category_name, labels)}</TableCell>
                            <TableCell>{row.count}</TableCell>
                            <TableCell className="text-end tabular-nums">{row.amount_afn} {labels.currencyLabel}</TableCell>
                        </TableRow>
                    ))}
                    <TableRow>
                        <TableCell colSpan={2} className="font-medium">{labels.dayTotal}</TableCell>
                        <TableCell className="text-end font-semibold tabular-nums">{dayTotal} {labels.currencyLabel}</TableCell>
                    </TableRow>
                </TableBody>
            </Table>
        </div>
    );
}

export function ExpenseDayExpensesTable({
    expenses,
    labels,
    canEdit = false,
    canDelete = false,
    onCancel,
}) {
    return (
        <div className="rounded-md border">
            <Table>
                <TableHeader>
                    <TableRow>
                        <TableHead>{labels.colVoucher}</TableHead>
                        <TableHead>{labels.colCategory}</TableHead>
                        <TableHead>{labels.colDescription}</TableHead>
                        <TableHead>{labels.colVendor}</TableHead>
                        <TableHead>{labels.colAmount}</TableHead>
                        <TableHead>{labels.colPayment}</TableHead>
                        <TableHead>{labels.colStatus}</TableHead>
                        <TableHead>{labels.colActions}</TableHead>
                    </TableRow>
                </TableHeader>
                <TableBody>
                    {expenses.map((expense) => (
                        <TableRow key={expense.id} className={cn(expense.is_cancelled && 'opacity-60')}>
                            <TableCell className="font-medium">{expense.voucher_number}</TableCell>
                            <TableCell>{expenseCategoryLabel(expense.category_slug, expense.category_name, labels)}</TableCell>
                            <TableCell>{expense.description || '—'}</TableCell>
                            <TableCell>{expense.vendor_paid_to || '—'}</TableCell>
                            <TableCell className="tabular-nums">{expense.amount_afn} {labels.currencyLabel}</TableCell>
                            <TableCell>{expensePaymentLabel(expense.payment_method, labels)}</TableCell>
                            <TableCell>
                                <ExpenseStatusBadge status={expense.status} label={expense.status_label} />
                            </TableCell>
                            <TableCell>
                                <DropdownMenu>
                                    <DropdownMenuTrigger asChild>
                                        <Button variant="ghost" size="icon" className="size-8">
                                            <MoreHorizontal className="size-4" />
                                        </Button>
                                    </DropdownMenuTrigger>
                                    <DropdownMenuContent align="end">
                                        <DropdownMenuItem asChild>
                                            <Link href={`/expenses/${expense.id}`}>{labels.viewExpense}</Link>
                                        </DropdownMenuItem>
                                        {canEdit && expense.can_edit ? (
                                            <DropdownMenuItem asChild>
                                                <Link href={`/expenses/${expense.id}/edit`}>{labels.editExpense}</Link>
                                            </DropdownMenuItem>
                                        ) : null}
                                        <DropdownMenuItem asChild>
                                            <a href={`/expenses/${expense.id}/print?print=1`} target="_blank" rel="noreferrer">
                                                {labels.printExpense}
                                            </a>
                                        </DropdownMenuItem>
                                        {canDelete && expense.can_edit ? (
                                            <DropdownMenuItem onClick={() => onCancel?.(expense)}>
                                                {labels.cancelExpense}
                                            </DropdownMenuItem>
                                        ) : null}
                                    </DropdownMenuContent>
                                </DropdownMenu>
                            </TableCell>
                        </TableRow>
                    ))}
                </TableBody>
            </Table>
        </div>
    );
}
