import { Link, router } from '@inertiajs/react';
import { Banknote, Eye, Gavel, MoreHorizontal, Pencil, UserCheck, UserX } from 'lucide-react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { toast } from 'sonner';
import { ConfirmActionDialog } from '@/components/confirm-action-dialog';
import { EmployeePhoto } from '@/components/employees/employee-photo';
import { PermanentEmployeeViewDialog } from '@/components/employees/permanent-employee-view-dialog';
import { Badge } from '@/components/ui/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 {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { useLanguage } from '@/contexts/language-context';
import { useInitials } from '@/hooks/use-initials';
import { useSyncedState } from '@/hooks/use-synced-state';
import { formatEmployeeJoiningDateNumericOrDash, formatMoneyAmountOrDash } from '@/lib/dates';

/**
 * @param {object} props
 * @param {import('@inertiajs/core').Paginator<any>} props.employees
 * @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 {(id: number) => string} props.editUrl
 * @param {(id: number) => string} props.statusUrl
 * @param {(id: number) => string} props.salariesUrl
 * @param {(id: number) => string} [props.punishmentsUrl]
 */
export function PermanentEmployeesTable({
    employees,
    filters,
    labels,
    indexUrl,
    editUrl,
    statusUrl,
    salariesUrl,
    punishmentsUrl,
}) {
    const { locale } = useLanguage();
    const getInitials = useInitials();
    const [search, setSearch] = useSyncedState(filters.search ?? '');
    const [viewingEmployee, setViewingEmployee] = useState(null);
    const [employeeToToggle, setEmployeeToToggle] = useState(null);
    const [pendingId, setPendingId] = useState(null);

    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 = employees?.data ?? [];
    const currentPage = employees?.current_page ?? 1;
    const lastPage = employees?.last_page ?? 1;
    const from = employees?.from;
    const to = employees?.to;
    const total = employees?.total ?? 0;
    const perPage = employees?.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],
    );

    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 },
        );
    }

    const runToggleActive = useCallback(
        (row) => {
            setPendingId(row.id);
            router.patch(
                statusUrl(row.id),
                { is_active: !row.is_active },
                {
                    preserveScroll: true,
                    onSuccess: () => {
                        setEmployeeToToggle(null);
                    },
                    onFinish: () => setPendingId(null),
                    onError: () => {
                        setPendingId(null);
                        toast.error(labels.toastActionFailed);
                    },
                },
            );
        },
        [statusUrl, labels],
    );

    return (
        <div className="space-y-4">
            <PermanentEmployeeViewDialog
                open={viewingEmployee != null}
                onOpenChange={(open) => {
                    if (!open) {
                        setViewingEmployee(null);
                    }
                }}
                employee={viewingEmployee}
                labels={labels}
                editUrl={editUrl}
            />

            <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>

            <div className="overflow-x-auto rounded-md border">
                <Table>
                    <TableHeader>
                        <TableRow>
                            <TableHead className="w-14">{labels.colSerial}</TableHead>
                            <TableHead>{labels.colFullName}</TableHead>
                            <TableHead>{labels.colDesignation}</TableHead>
                            <TableHead>{labels.colFatherName}</TableHead>
                            <TableHead>{labels.colPhone}</TableHead>
                            <TableHead className="text-end">{labels.colMonthlySalary}</TableHead>
                            <TableHead>{labels.colStatus}</TableHead>
                            <TableHead>{labels.colJoiningDate}</TableHead>
                            <TableHead className="w-[1%] whitespace-nowrap">
                                {labels.colAction}
                            </TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {rows.length === 0 ? (
                            <TableRow>
                                <TableCell
                                    colSpan={9}
                                    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>
                                        <TableCell className="font-medium whitespace-normal">
                                            <div className="flex min-w-0 items-center gap-3">
                                                <EmployeePhoto
                                                    src={row.image_url}
                                                    initials={getInitials(row.full_name)}
                                                    size="sm"
                                                />
                                                <span className="min-w-0 truncate">
                                                    {row.full_name}
                                                </span>
                                            </div>
                                        </TableCell>
                                        <TableCell className="whitespace-normal">
                                            {row.designation_name ?? labels.notProvided}
                                        </TableCell>
                                        <TableCell className="whitespace-normal">
                                            {row.father_name}
                                        </TableCell>
                                        <TableCell className="whitespace-nowrap">
                                            {row.phone_number}
                                        </TableCell>
                                        <TableCell className="text-end tabular-nums">
                                            {formatMoneyAmountOrDash(row.monthly_salary, locale)}
                                        </TableCell>
                                        <TableCell>
                                            <Badge
                                                variant={row.is_active ? 'secondary' : 'outline'}
                                            >
                                                {row.is_active
                                                    ? labels.statusActive
                                                    : labels.statusInactive}
                                            </Badge>
                                        </TableCell>
                                        <TableCell className="text-muted-foreground whitespace-nowrap text-sm tabular-nums">
                                            {formatEmployeeJoiningDateNumericOrDash(
                                                row.joining_date,
                                            )}
                                        </TableCell>
                                        <TableCell className="align-middle">
                                            <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();
                                                            setViewingEmployee(row);
                                                        }}
                                                    >
                                                        <Eye className="size-4" />
                                                        {labels.viewEmployee}
                                                    </DropdownMenuItem>
                                                    <DropdownMenuSeparator />
                                                    <DropdownMenuItem asChild>
                                                        <Link
                                                            href={editUrl(row.id)}
                                                            prefetch
                                                            className="flex cursor-pointer items-center gap-2"
                                                        >
                                                            <Pencil className="size-4" />
                                                            {labels.editEmployee}
                                                        </Link>
                                                    </DropdownMenuItem>
                                                    {salariesUrl ? (
                                                        <DropdownMenuItem asChild>
                                                            <Link
                                                                href={salariesUrl(row.id)}
                                                                prefetch
                                                                className="flex cursor-pointer items-center gap-2"
                                                            >
                                                                <Banknote className="size-4" />
                                                                {labels.monthlySalaries}
                                                            </Link>
                                                        </DropdownMenuItem>
                                                    ) : null}
                                                    {punishmentsUrl ? (
                                                        <DropdownMenuItem asChild>
                                                            <Link
                                                                href={punishmentsUrl(row.id)}
                                                                prefetch
                                                                className="flex cursor-pointer items-center gap-2"
                                                            >
                                                                <Gavel className="size-4" />
                                                                {labels.punishments}
                                                            </Link>
                                                        </DropdownMenuItem>
                                                    ) : null}
                                                    <DropdownMenuSeparator />
                                                    <DropdownMenuItem
                                                        disabled={pendingId === row.id}
                                                        onSelect={(e) => {
                                                            e.preventDefault();
                                                            setEmployeeToToggle(row);
                                                        }}
                                                    >
                                                        {row.is_active ? (
                                                            <>
                                                                <UserX className="size-4" />
                                                                {labels.deactivateEmployee}
                                                            </>
                                                        ) : (
                                                            <>
                                                                <UserCheck className="size-4" />
                                                                {labels.activateEmployee}
                                                            </>
                                                        )}
                                                    </DropdownMenuItem>
                                                </DropdownMenuContent>
                                            </DropdownMenu>
                                        </TableCell>
                                    </TableRow>
                                );
                            })
                        )}
                    </TableBody>
                </Table>
            </div>

            <div className="flex flex-col gap-3 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">
                    <span className="text-muted-foreground text-sm">{pagePositionText}</span>
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        disabled={currentPage <= 1}
                        onClick={() => goToPage(currentPage - 1)}
                    >
                        {labels.paginationPrevious}
                    </Button>
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        disabled={currentPage >= lastPage}
                        onClick={() => goToPage(currentPage + 1)}
                    >
                        {labels.paginationNext}
                    </Button>
                    <select
                        className="border-input bg-background h-9 rounded-md border px-2 text-sm"
                        value={filters.per_page}
                        onChange={(e) => setPerPage(Number(e.target.value))}
                        aria-label={labels.rowsPerPage}
                    >
                        {[5, 10, 25, 50].map((n) => (
                            <option key={n} value={n}>
                                {n}
                            </option>
                        ))}
                    </select>
                </div>
            </div>

            <ConfirmActionDialog
                open={employeeToToggle != null}
                onOpenChange={(open) => {
                    if (!open) {
                        setEmployeeToToggle(null);
                    }
                }}
                title={
                    employeeToToggle?.is_active
                        ? labels.confirmDeactivateTitle
                        : labels.confirmActivateTitle
                }
                description={
                    employeeToToggle?.is_active
                        ? labels.confirmDeactivateBody
                        : labels.confirmActivateBody
                }
                confirmLabel={
                    employeeToToggle?.is_active
                        ? labels.deactivateEmployee
                        : labels.activateEmployee
                }
                cancelLabel={labels.cancel}
                destructive={employeeToToggle?.is_active === true}
                processing={pendingId != null}
                onConfirm={() => {
                    if (employeeToToggle) {
                        runToggleActive(employeeToToggle);
                    }
                }}
            />
        </div>
    );
}
