import { Link, router } from '@inertiajs/react';
import { Fingerprint } from 'lucide-react';
import { useEffect, useMemo } from 'react';
import { AppMonthInput } from '@/components/ui/app-month-input';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { useLanguage } from '@/contexts/language-context';
import { useSyncedState } from '@/hooks/use-synced-state';
import {
    formatMoneyAmountOrDash,
    formatPunishmentDatesForSalary,
    formatSalaryMonthOrDash,
} from '@/lib/dates';
import { cn } from '@/lib/utils';

/**
 * @param {object} props
 * @param {import('@inertiajs/core').Paginator<any>} props.payments
 * @param {{ search: string, per_page: number }} props.filters
 * @param {Record<string, string>} props.labels
 * @param {(opts?: { query?: Record<string, string | number> }) => string} props.indexUrl
 * @param {boolean} [props.showStaffColumn]
 * @param {(employeeId: number) => string} [props.employeeSalariesUrl]
 */
export function PermanentSalariesTable({
    payments,
    filters,
    labels,
    indexUrl,
    showStaffColumn = false,
    employeeSalariesUrl,
}) {
    const { locale } = useLanguage();
    const [search, setSearch] = useSyncedState(filters.search ?? '');
    const [salaryMonth, setSalaryMonth] = useSyncedState(filters.salary_month ?? '');

    useEffect(() => {
        const handle = setTimeout(() => {
            const nextSearch = search.trim();
            const currentSearch = (filters.search ?? '').trim();
            const nextMonth = salaryMonth.trim();
            const currentMonth = (filters.salary_month ?? '').trim();

            if (nextSearch === currentSearch && nextMonth === currentMonth) {
                return;
            }

            const query = {
                search: nextSearch,
                per_page: filters.per_page,
                page: 1,
            };

            if (showStaffColumn) {
                query.salary_month = nextMonth;
            }

            router.get(indexUrl({ query }), {}, { preserveState: true, preserveScroll: true, replace: true });
        }, 350);

        return () => clearTimeout(handle);
    }, [search, salaryMonth, filters.search, filters.salary_month, filters.per_page, indexUrl, showStaffColumn]);

    const rows = payments?.data ?? [];
    const currentPage = payments?.current_page ?? 1;
    const lastPage = payments?.last_page ?? 1;
    const from = payments?.from;
    const to = payments?.to;
    const total = payments?.total ?? 0;
    const perPage = payments?.per_page ?? 10;

    const summaryText = useMemo(() => {
        if (total === 0) {
            return labels.summaryEmpty;
        }
        return labels.paginationSummary
            .replace('{from}', String(from ?? 0))
            .replace('{to}', String(to ?? 0))
            .replace('{total}', String(total));
    }, [from, to, total, labels.paginationSummary, labels.summaryEmpty]);

    const pagePositionText = useMemo(
        () =>
            labels.paginationPages
                .replace('{page}', String(currentPage))
                .replace('{pages}', String(Math.max(lastPage, 1))),
        [currentPage, lastPage, labels.paginationPages],
    );

    const showPayrollBreakdown = Boolean(labels.colBaseSalary);
    const showAbsentDays = showPayrollBreakdown && Boolean(labels.colAbsentDays);
    const showPunishment = showPayrollBreakdown && Boolean(labels.colPunishment);
    const columnCount =
        6
        + (showStaffColumn ? 2 : 0)
        + (showPayrollBreakdown ? 3 : 0)
        + (showAbsentDays ? 1 : 0)
        + (showPunishment ? 2 : 0);

    return (
        <div className="space-y-4">
            <div className="flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
                <div className="flex max-w-sm flex-1 flex-col gap-2">
                    <Input
                        type="search"
                        value={search}
                        onChange={(e) => setSearch(e.target.value)}
                        placeholder={labels.searchPlaceholder}
                        className="h-9"
                    />
                </div>
                {showStaffColumn ? (
                    <div className="flex flex-col gap-2">
                        <Label htmlFor="salary-month-filter" className="text-muted-foreground text-xs">
                            {labels.filterSalaryMonth}
                        </Label>
                        <AppMonthInput
                            id="salary-month-filter"
                            value={salaryMonth}
                            onChange={setSalaryMonth}
                            className="w-[11rem]"
                        />
                    </div>
                ) : null}
            </div>

            <div className="overflow-x-auto rounded-md border">
                <Table>
                    <TableHeader>
                        <TableRow>
                            <TableHead className="w-14">{labels.colSerial}</TableHead>
                            {showStaffColumn ? (
                                <TableHead>{labels.colStaff}</TableHead>
                            ) : null}
                            <TableHead>{labels.colSalaryMonth}</TableHead>
                            {showPayrollBreakdown ? (
                                <>
                                    <TableHead className="text-end">{labels.colBaseSalary}</TableHead>
                                    <TableHead className="text-end">{labels.colAllowance}</TableHead>
                                    {showAbsentDays ? (
                                        <TableHead className="text-end">{labels.colAbsentDays}</TableHead>
                                    ) : null}
                                    {showPunishment ? (
                                        <>
                                            <TableHead className="text-end">{labels.colPunishment}</TableHead>
                                            <TableHead>{labels.colPunishmentTime}</TableHead>
                                        </>
                                    ) : null}
                                </>
                            ) : null}
                            <TableHead className={showPayrollBreakdown ? 'text-end' : undefined}>
                                {labels.colAmount}
                            </TableHead>
                            {showPayrollBreakdown ? (
                                <TableHead>{labels.colStatus}</TableHead>
                            ) : null}
                            <TableHead>{labels.colPaymentMethod}</TableHead>
                            <TableHead>{labels.colPaidAt}</TableHead>
                            <TableHead>{labels.colPaidBy}</TableHead>
                            {showStaffColumn ? (
                                <TableHead className="w-[1%] whitespace-nowrap">
                                    {labels.colAction}
                                </TableHead>
                            ) : null}
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {rows.length === 0 ? (
                            <TableRow>
                                <TableCell
                                    colSpan={columnCount}
                                    className="text-muted-foreground h-24 text-center"
                                >
                                    {labels.empty}
                                </TableCell>
                            </TableRow>
                        ) : (
                            rows.map((row, index) => {
                                const serial = (currentPage - 1) * perPage + index + 1;

                                return (
                                    <TableRow key={row.id}>
                                        <TableCell className="text-muted-foreground tabular-nums">
                                            {serial}
                                        </TableCell>
                                        {showStaffColumn ? (
                                            <TableCell className="whitespace-normal">
                                                <div className="font-medium">{row.staff_name}</div>
                                                {row.designation_name ? (
                                                    <div className="text-muted-foreground text-xs">
                                                        {row.designation_name}
                                                    </div>
                                                ) : null}
                                            </TableCell>
                                        ) : null}
                                        <TableCell className="font-medium whitespace-nowrap">
                                            {formatSalaryMonthOrDash(row.salary_month, 'fa')}
                                        </TableCell>
                                        {showPayrollBreakdown ? (
                                            <>
                                                <TableCell className="text-end tabular-nums">
                                                    {formatMoneyAmountOrDash(row.base_salary, locale)}
                                                </TableCell>
                                                <TableCell className="text-end tabular-nums">
                                                    {formatMoneyAmountOrDash(row.allowance, locale)}
                                                </TableCell>
                                                {showAbsentDays ? (
                                                    <TableCell className="text-end tabular-nums font-medium">
                                                        {row.absent_days ?? 0}
                                                    </TableCell>
                                                ) : null}
                                                {showPunishment ? (
                                                    <>
                                                        <TableCell className="text-end tabular-nums text-destructive">
                                                            {Number(row.punishment_total) > 0
                                                                ? `−${formatMoneyAmountOrDash(row.punishment_total, locale)}`
                                                                : formatMoneyAmountOrDash(0, locale)}
                                                        </TableCell>
                                                        <TableCell className="text-muted-foreground whitespace-nowrap text-sm">
                                                            {formatPunishmentDatesForSalary(
                                                                row.punishment_dates,
                                                                locale,
                                                            )}
                                                        </TableCell>
                                                    </>
                                                ) : null}
                                            </>
                                        ) : null}
                                        <TableCell
                                            className={cn(
                                                'tabular-nums',
                                                showPayrollBreakdown && 'text-end font-medium',
                                            )}
                                        >
                                            {formatMoneyAmountOrDash(row.amount, locale)}
                                        </TableCell>
                                        {showPayrollBreakdown ? (
                                            <TableCell>
                                                {row.is_draft ? (
                                                    <Badge variant="outline">{labels.statusDraft}</Badge>
                                                ) : (
                                                    <Badge variant="secondary">{labels.statusPaid}</Badge>
                                                )}
                                            </TableCell>
                                        ) : null}
                                        <TableCell>
                                            {row.is_draft ? (
                                                <span className="text-muted-foreground text-sm">—</span>
                                            ) : row.was_paid_with_fingerprint ? (
                                                <Badge variant="secondary" className="gap-1 font-normal">
                                                    <Fingerprint className="size-3.5" />
                                                    {labels.paidViaFingerprint}
                                                </Badge>
                                            ) : (
                                                <Badge variant="outline" className="font-normal">
                                                    {labels.paidManually}
                                                </Badge>
                                            )}
                                        </TableCell>
                                        <TableCell className="text-muted-foreground text-sm whitespace-nowrap">
                                            {row.paid_at ?? labels.notProvided}
                                        </TableCell>
                                        <TableCell className="whitespace-nowrap">
                                            {row.paid_by_name ?? labels.notProvided}
                                        </TableCell>
                                        {showStaffColumn && employeeSalariesUrl ? (
                                            <TableCell>
                                                <Button variant="outline" size="sm" asChild>
                                                    <Link
                                                        href={employeeSalariesUrl(
                                                            row.permanent_employee_id,
                                                        )}
                                                        prefetch
                                                    >
                                                        {labels.viewStaffSalaries}
                                                    </Link>
                                                </Button>
                                            </TableCell>
                                        ) : null}
                                    </TableRow>
                                );
                            })
                        )}
                    </TableBody>
                </Table>
            </div>

            {total > 0 ? (
                <div className="flex flex-col gap-4 border-t border-border pt-4 sm:flex-row sm:items-center sm:justify-between">
                    <p className="text-muted-foreground text-sm">{summaryText}</p>
                    <div className="flex flex-wrap items-center gap-2">
                        <Label
                            htmlFor="salaries-page-size"
                            className="text-muted-foreground whitespace-nowrap text-sm"
                        >
                            {labels.rowsPerPage}
                        </Label>
                        <select
                            id="salaries-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={perPage}
                            onChange={(e) => {
                                const query = {
                                    search: filters.search,
                                    per_page: Number(e.target.value),
                                    page: 1,
                                };
                                if (showStaffColumn && filters.salary_month) {
                                    query.salary_month = filters.salary_month;
                                }
                                router.get(indexUrl({ query }),
                                    {},
                                    { preserveState: true, preserveScroll: true },
                                );
                            }}
                        >
                            {[5, 10, 25, 50].map((n) => (
                                <option key={n} value={n}>
                                    {n}
                                </option>
                            ))}
                        </select>
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            disabled={currentPage <= 1}
                            onClick={() => {
                                const query = {
                                    search: filters.search,
                                    per_page: perPage,
                                    page: currentPage - 1,
                                };
                                if (showStaffColumn && filters.salary_month) {
                                    query.salary_month = filters.salary_month;
                                }
                                router.get(
                                    indexUrl({ query }),
                                    {},
                                    { preserveState: true, preserveScroll: true },
                                );
                            }}
                        >
                            {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"
                            disabled={currentPage >= lastPage}
                            onClick={() => {
                                const query = {
                                    search: filters.search,
                                    per_page: perPage,
                                    page: currentPage + 1,
                                };
                                if (showStaffColumn && filters.salary_month) {
                                    query.salary_month = filters.salary_month;
                                }
                                router.get(
                                    indexUrl({ query }),
                                    {},
                                    { preserveState: true, preserveScroll: true },
                                );
                            }}
                        >
                            {labels.paginationNext}
                        </Button>
                    </div>
                </div>
            ) : null}
        </div>
    );
}
