import { Head, Link, router } from '@inertiajs/react';
import { createColumnHelper } from '@tanstack/react-table';
import type { ColumnDef, PaginationState, SortingState } from '@tanstack/react-table';
import { Eye, Plus } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { DataTable, DataTableColumnHeader } from '@/components/data-table';
import Heading from '@/components/heading';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { formatCurrency, formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { create, index, show } from '@/routes/admin/payroll-runs';
import type { Paginated } from '@/types';

type PayrollRunRow = {
    id: number;
    code: string;
    period_label: string;
    period_start: string;
    status: string;
    status_label: string;
    payslips_count: number;
    total_gross: number;
    total_net: number;
    created_at: string | null;
};

type Filters = {
    search: string;
    sort: string;
    direction: 'asc' | 'desc';
    per_page: number;
    status: string | null;
};

const columnHelper = createColumnHelper<PayrollRunRow>();

export default function PayrollRunsIndex({
    runs,
    filters,
    statuses,
    can,
}: {
    runs: Paginated<PayrollRunRow>;
    filters: Filters;
    statuses: Array<{ value: string; label: string }>;
    can: { create: boolean };
}) {
    const [search, setSearch] = useState(filters.search);
    const [sorting, setSorting] = useState<SortingState>([
        { id: filters.sort, desc: filters.direction === 'desc' },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: runs.current_page - 1,
        pageSize: runs.per_page,
    });
    const isFirstSearch = useRef(true);

    useEffect(() => {
        if (isFirstSearch.current) {
            isFirstSearch.current = false;
            return;
        }
        const timeout = window.setTimeout(() => {
            router.get(index.url(), {
                search: search || undefined,
                status: filters.status ?? undefined,
                sort: sorting[0]?.id,
                direction: sorting[0]?.desc ? 'desc' : 'asc',
            }, { preserveState: true, replace: true });
        }, 300);
        return () => window.clearTimeout(timeout);
    }, [search, filters.status, sorting]);

    const columns = useMemo((): ColumnDef<PayrollRunRow, any>[] => [
        columnHelper.accessor('code', {
            header: ({ column }) => <DataTableColumnHeader column={column} title="Cycle" />,
            cell: (info) => <span className="font-mono text-sm">{info.getValue()}</span>,
        }),
        columnHelper.accessor('period_label', {
            header: ({ column }) => <DataTableColumnHeader column={column} title="Période" />,
        }),
        columnHelper.accessor('status_label', {
            header: ({ column }) => <DataTableColumnHeader column={column} title="Statut" />,
            cell: (info) => <Badge variant="secondary">{info.getValue()}</Badge>,
        }),
        columnHelper.accessor('payslips_count', {
            header: ({ column }) => <DataTableColumnHeader column={column} title="Bulletins" />,
        }),
        columnHelper.accessor('total_net', {
            header: ({ column }) => <DataTableColumnHeader column={column} title="Net" />,
            cell: (info) => formatCurrency(info.getValue()),
        }),
        columnHelper.accessor('created_at', {
            header: ({ column }) => <DataTableColumnHeader column={column} title="Créé le" />,
            cell: (info) => formatDate(info.getValue()),
        }),
        columnHelper.display({
            id: 'actions',
            cell: (info) => (
                <Button variant="ghost" size="sm" asChild>
                    <Link href={show.url(info.row.original.code)}>
                        <Eye className="size-4" />
                    </Link>
                </Button>
            ),
        }),
    ], []);

    return (
        <>
            <Head title="Paie" />
            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
                    <Heading
                        title="Cycles de paie"
                        description="Calcul, validation et états de paie mensuels"
                    />
                    {can.create && (
                        <Button asChild>
                            <Link href={create.url()}>
                                <Plus className="size-4" />
                                Nouveau cycle
                            </Link>
                        </Button>
                    )}
                </div>
                <div className="flex gap-3">
                    <Select
                        value={filters.status ?? 'all'}
                        onValueChange={(value) =>
                            router.get(index.url(), {
                                search: search || undefined,
                                status: value === 'all' ? undefined : value,
                            }, { preserveState: true, replace: true })
                        }
                    >
                        <SelectTrigger className="w-48">
                            <SelectValue placeholder="Statut" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">Tous les statuts</SelectItem>
                            {statuses.map((status) => (
                                <SelectItem key={status.value} value={status.value}>
                                    {status.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
                <DataTable
                    id="admin-payroll-runs"
                    columns={columns}
                    data={runs.data}
                    getRowId={(row) => String(row.id)}
                    pageCount={runs.last_page}
                    pagination={pagination}
                    onPaginationChange={(updater) => {
                        const next = typeof updater === 'function' ? updater(pagination) : updater;
                        setPagination(next);
                        router.get(index.url(), {
                            search: search || undefined,
                            status: filters.status ?? undefined,
                            page: next.pageIndex + 1,
                            per_page: next.pageSize,
                        }, { preserveState: true, replace: true });
                    }}
                    manualPagination
                    sorting={sorting}
                    onSortingChange={setSorting}
                    manualSorting
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher un cycle…"
                    emptyMessage="Aucun cycle de paie."
                />
            </div>
        </>
    );
}

PayrollRunsIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Paie', href: index() },
    ],
};
