import { Head, Link, router } from '@inertiajs/react';
import {
    createColumnHelper,
    type ColumnDef,
    type PaginationState,
    type SortingState,
} from '@tanstack/react-table';
import { ArrowLeft, Eye, PackagePlus } 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 { useCan } from '@/hooks/use-can';
import { formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { show as warehouseShow } from '@/routes/admin/warehouses';
import {
    create as createReceipt,
    index as receiptsIndex,
    show as receiptShow,
} from '@/routes/admin/warehouses/receipts';
import type { Paginated } from '@/types';

type Warehouse = { id: number; code: string; name: string };

type ReceiptRow = {
    id: number;
    code: string;
    received_at: string | null;
    notes: string | null;
    source: 'manual' | 'purchase_order';
    purchase_order: { id: number; code: string } | null;
    creator: { id: number; name: string } | null;
    lines: Array<{
        id: number;
        quantity: number;
        product: { id: number; code: string; name: string } | null;
    }>;
    lines_count: number;
    lines_quantity: number;
};

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

const columnHelper = createColumnHelper<ReceiptRow>();

function visitReceipts(
    warehouseId: number,
    params: {
        search: string;
        sort: string;
        direction: 'asc' | 'desc';
        page: number;
        per_page: number;
    },
) {
    router.get(
        receiptsIndex.url(warehouseId),
        {
            search: params.search || undefined,
            sort: params.sort,
            direction: params.direction,
            page: params.page > 1 ? params.page : undefined,
            per_page: params.per_page !== 15 ? params.per_page : undefined,
        },
        {
            preserveState: true,
            replace: true,
            preserveScroll: true,
        },
    );
}

export default function WarehouseReceiptsIndex({
    warehouse,
    receipts,
    filters,
    canCreateReceipt = false,
}: {
    warehouse: Warehouse;
    receipts: Paginated<ReceiptRow>;
    filters: Filters;
    canCreateReceipt?: boolean;
}) {
    const canViewWarehouseList = useCan('warehouses.view');
    const isFirstSearchEffect = useRef(true);
    const [isLoading, setIsLoading] = useState(false);
    const [search, setSearch] = useState(filters.search);
    const [sorting, setSorting] = useState<SortingState>([
        { id: filters.sort, desc: filters.direction === 'desc' },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: receipts.current_page - 1,
        pageSize: receipts.per_page,
    });

    useEffect(() => {
        const removeStart = router.on('start', () => setIsLoading(true));
        const removeFinish = router.on('finish', () => setIsLoading(false));

        return () => {
            removeStart();
            removeFinish();
        };
    }, []);

    useEffect(() => {
        setSearch(filters.search);
        setSorting([
            { id: filters.sort, desc: filters.direction === 'desc' },
        ]);
        setPagination({
            pageIndex: receipts.current_page - 1,
            pageSize: receipts.per_page,
        });
    }, [filters, receipts.current_page, receipts.per_page]);

    useEffect(() => {
        if (isFirstSearchEffect.current) {
            isFirstSearchEffect.current = false;
            return;
        }

        const timeout = window.setTimeout(() => {
            visitReceipts(warehouse.id, {
                search,
                sort: sorting[0]?.id ?? filters.sort,
                direction: sorting[0]?.desc ? 'desc' : 'asc',
                page: 1,
                per_page: pagination.pageSize,
            });
        }, 300);

        return () => window.clearTimeout(timeout);
    }, [search]);

    const columns = useMemo<ColumnDef<ReceiptRow, unknown>[]>(
        () => [
            columnHelper.accessor('code', {
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Réception" />
                ),
                meta: { label: 'Réception' },
                cell: (info) => (
                    <span className="font-mono text-sm font-medium">
                        {info.getValue()}
                    </span>
                ),
            }),
            columnHelper.accessor('received_at', {
                header: ({ column }) => (
                    <DataTableColumnHeader
                        column={column}
                        title="Date de réception"
                    />
                ),
                meta: { label: 'Date de réception' },
                cell: (info) => formatDate(info.getValue()),
            }),
            columnHelper.display({
                id: 'products',
                enableSorting: false,
                header: () => 'Produits',
                meta: { label: 'Produits' },
                cell: ({ row }) => {
                    const lines = row.original.lines;

                    if (lines.length === 0) {
                        return (
                            <span className="text-muted-foreground">—</span>
                        );
                    }

                    return (
                        <ul className="space-y-1">
                            {lines.map((line) => (
                                <li key={line.id} className="truncate text-sm">
                                    {line.product?.name ?? '—'}
                                </li>
                            ))}
                        </ul>
                    );
                },
            }),
            columnHelper.accessor('lines_quantity', {
                header: ({ column }) => (
                    <DataTableColumnHeader
                        column={column}
                        title="Quantité"
                    />
                ),
                meta: { label: 'Quantité' },
                enableSorting: false,
                cell: (info) => (
                    <span className="tabular-nums font-medium">
                        {info.getValue()} unité
                        {info.getValue() > 1 ? 's' : ''}
                    </span>
                ),
            }),
            columnHelper.accessor('source', {
                header: ({ column }) => (
                    <DataTableColumnHeader
                        column={column}
                        title="Origine"
                    />
                ),
                meta: { label: 'Origine' },
                enableSorting: false,
                cell: (info) => {
                    const receipt = info.row.original;

                    if (receipt.source === 'purchase_order') {
                        return (
                            <div className="flex flex-col gap-0.5">
                                <Badge variant="secondary" className="w-fit">
                                    Commande
                                </Badge>
                                <span className="text-muted-foreground font-mono text-xs">
                                    {receipt.purchase_order?.code ?? '—'}
                                </span>
                            </div>
                        );
                    }

                    return <Badge variant="outline">Manuelle</Badge>;
                },
            }),
            columnHelper.accessor((row) => row.creator?.name ?? '', {
                id: 'creator',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Créé par" />
                ),
                meta: { label: 'Créé par' },
                enableSorting: false,
                cell: (info) => info.row.original.creator?.name ?? '—',
            }),
            columnHelper.display({
                id: 'actions',
                enableSorting: false,
                enableHiding: false,
                header: () => <div className="text-right">Actions</div>,
                cell: ({ row }) => {
                    const receipt = row.original;

                    return (
                        <div className="flex justify-end">
                            <Button variant="outline" size="icon" asChild>
                                <Link
                                    href={receiptShow.url([
                                        warehouse.id,
                                        receipt.id,
                                    ])}
                                    aria-label={`Voir ${receipt.code}`}
                                >
                                    <Eye />
                                </Link>
                            </Button>
                        </div>
                    );
                },
            }),
        ],
        [warehouse.id],
    );

    return (
        <>
            <Head title={`Réceptions — ${warehouse.name}`} />

            <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-start sm:justify-between">
                    <Heading
                        title="Réceptions"
                        description={`${warehouse.code} — ${warehouse.name}`}
                    />
                    <div className="flex flex-wrap gap-2">
                        {canViewWarehouseList ? (
                            <Button variant="outline" asChild>
                                <Link href={warehouseShow(warehouse.id)}>
                                    <ArrowLeft />
                                    Entrepôt
                                </Link>
                            </Button>
                        ) : (
                            <Button variant="outline" asChild>
                                <Link href={dashboard()}>
                                    <ArrowLeft />
                                    Retour
                                </Link>
                            </Button>
                        )}
                        {canCreateReceipt && (
                            <Button asChild>
                                <Link href={createReceipt(warehouse.id)}>
                                    <PackagePlus />
                                    Nouvelle réception
                                </Link>
                            </Button>
                        )}
                    </div>
                </div>

                <DataTable
                    id="admin-warehouse-receipts"
                    columns={columns}
                    data={receipts.data}
                    getRowId={(row) => String(row.id)}
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher par code, produit, commande…"
                    isLoading={isLoading}
                    sorting={sorting}
                    onSortingChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(sorting)
                                : updater;
                        setSorting(next);
                        visitReceipts(warehouse.id, {
                            search,
                            sort: next[0]?.id ?? filters.sort,
                            direction: next[0]?.desc ? 'desc' : 'asc',
                            page: 1,
                            per_page: pagination.pageSize,
                        });
                    }}
                    manualSorting
                    pagination={pagination}
                    onPaginationChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(pagination)
                                : updater;
                        const sizeChanged =
                            next.pageSize !== pagination.pageSize;
                        setPagination(next);
                        visitReceipts(warehouse.id, {
                            search,
                            sort: sorting[0]?.id ?? filters.sort,
                            direction: sorting[0]?.desc ? 'desc' : 'asc',
                            page: sizeChanged ? 1 : next.pageIndex + 1,
                            per_page: next.pageSize,
                        });
                    }}
                    manualPagination
                    pageCount={receipts.last_page}
                    totalRows={receipts.total}
                    emptyMessage="Aucune réception enregistrée."
                />
            </div>
        </>
    );
}

WarehouseReceiptsIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Réceptions', href: '#' },
    ],
};
