import { Head, Link, router } from '@inertiajs/react';
import {
    createColumnHelper,
    type ColumnDef,
    type PaginationState,
    type SortingState,
} from '@tanstack/react-table';
import { AlertTriangle, Eye, History } 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 { dashboard } from '@/routes';
import { index as stockLevelsIndex } from '@/routes/admin/stock-levels';
import { index as stockMovementsIndex } from '@/routes/admin/stock-movements';
import { show as warehouseShow } from '@/routes/admin/warehouses';
import type { Paginated } from '@/types';

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

type StockRow = {
    id: number;
    quantity: number;
    warehouse: WarehouseOption | null;
    product: { id: number; code: string; name: string; min_stock: number } | null;
    is_low_stock: boolean;
};

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

const columnHelper = createColumnHelper<StockRow>();

function visitStockLevels(params: {
    search: string;
    sort: string;
    direction: 'asc' | 'desc';
    page: number;
    per_page: number;
    warehouse_id: number | null;
}) {
    router.get(
        stockLevelsIndex.url(),
        {
            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,
            warehouse_id: params.warehouse_id ?? undefined,
        },
        {
            preserveState: true,
            replace: true,
            preserveScroll: true,
        },
    );
}

export default function StockLevelsIndex({
    stocks,
    warehouses,
    filters,
}: {
    stocks: Paginated<StockRow>;
    warehouses: WarehouseOption[];
    filters: Filters;
}) {
    const isFirstSearchEffect = useRef(true);
    const [isLoading, setIsLoading] = useState(false);
    const [search, setSearch] = useState(filters.search);
    const [warehouseFilter, setWarehouseFilter] = useState<string>(
        filters.warehouse_id ? String(filters.warehouse_id) : 'all',
    );
    const [sorting, setSorting] = useState<SortingState>([
        { id: filters.sort, desc: filters.direction === 'desc' },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: stocks.current_page - 1,
        pageSize: stocks.per_page,
    });

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

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

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

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

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

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

    const columns = useMemo<ColumnDef<StockRow, unknown>[]>(
        () => [
            columnHelper.accessor((row) => row.product?.code ?? '', {
                id: 'product_code',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Code" />
                ),
                meta: { label: 'Code' },
                cell: (info) => (
                    <span className="font-mono text-sm">
                        {info.row.original.product?.code ?? '—'}
                    </span>
                ),
            }),
            columnHelper.accessor((row) => row.product?.name ?? '', {
                id: 'product_name',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Produit" />
                ),
                meta: { label: 'Produit' },
                cell: (info) => info.row.original.product?.name ?? '—',
            }),
            columnHelper.accessor((row) => row.warehouse?.name ?? '', {
                id: 'warehouse_name',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Entrepôt" />
                ),
                meta: { label: 'Entrepôt' },
                cell: (info) => {
                    const warehouse = info.row.original.warehouse;

                    if (warehouse === null) {
                        return '—';
                    }

                    return (
                        <div className="flex flex-col gap-0.5">
                            <span className="text-sm font-medium">
                                {warehouse.name}
                            </span>
                            <span className="text-muted-foreground font-mono text-xs">
                                {warehouse.code}
                            </span>
                        </div>
                    );
                },
            }),
            columnHelper.accessor('quantity', {
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Quantité" />
                ),
                meta: { label: 'Quantité' },
                cell: (info) => {
                    const isLowStock = info.row.original.is_low_stock;

                    return (
                        <div className="flex items-center gap-2">
                            <span className="tabular-nums font-medium">
                                {info.getValue()} unité
                                {info.getValue() > 1 ? 's' : ''}
                            </span>
                            {isLowStock && (
                                <Badge
                                    variant="destructive"
                                    className="gap-1"
                                >
                                    <AlertTriangle className="size-3" />
                                    Stock bas
                                </Badge>
                            )}
                        </div>
                    );
                },
            }),
            columnHelper.display({
                id: 'actions',
                enableSorting: false,
                enableHiding: false,
                header: () => <div className="text-right">Actions</div>,
                cell: ({ row }) => {
                    const warehouse = row.original.warehouse;

                    if (warehouse === null) {
                        return null;
                    }

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

    return (
        <>
            <Head title="Stock actuel" />

            <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="Stock actuel"
                        description="Consultation des quantités en stock par entrepôt"
                    />
                    <Button variant="outline" asChild>
                        <Link href={stockMovementsIndex.url()}>
                            <History />
                            Historique des mouvements
                        </Link>
                    </Button>
                </div>

                <Select
                    value={warehouseFilter}
                    onValueChange={(value) => {
                        setWarehouseFilter(value);
                        visitStockLevels({
                            search,
                            sort: sorting[0]?.id ?? filters.sort,
                            direction: sorting[0]?.desc ? 'desc' : 'asc',
                            page: 1,
                            per_page: pagination.pageSize,
                            warehouse_id:
                                value === 'all' ? null : Number(value),
                        });
                    }}
                >
                    <SelectTrigger className="w-55">
                        <SelectValue placeholder="Entrepôt" />
                    </SelectTrigger>
                    <SelectContent>
                        <SelectItem value="all">Tous les entrepôts</SelectItem>
                        {warehouses.map((warehouse) => (
                            <SelectItem
                                key={warehouse.id}
                                value={String(warehouse.id)}
                            >
                                {warehouse.code} — {warehouse.name}
                            </SelectItem>
                        ))}
                    </SelectContent>
                </Select>

                <DataTable
                    id="admin-stock-levels"
                    columns={columns}
                    data={stocks.data}
                    getRowId={(row) => String(row.id)}
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher par produit ou entrepôt…"
                    isLoading={isLoading}
                    sorting={sorting}
                    onSortingChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(sorting)
                                : updater;
                        setSorting(next);
                        visitStockLevels({
                            search,
                            sort: next[0]?.id ?? filters.sort,
                            direction: next[0]?.desc ? 'desc' : 'asc',
                            page: 1,
                            per_page: pagination.pageSize,
                            warehouse_id:
                                warehouseFilter === 'all'
                                    ? null
                                    : Number(warehouseFilter),
                        });
                    }}
                    manualSorting
                    pagination={pagination}
                    onPaginationChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(pagination)
                                : updater;
                        const sizeChanged =
                            next.pageSize !== pagination.pageSize;
                        setPagination(next);
                        visitStockLevels({
                            search,
                            sort: sorting[0]?.id ?? filters.sort,
                            direction: sorting[0]?.desc ? 'desc' : 'asc',
                            page: sizeChanged ? 1 : next.pageIndex + 1,
                            per_page: next.pageSize,
                            warehouse_id:
                                warehouseFilter === 'all'
                                    ? null
                                    : Number(warehouseFilter),
                        });
                    }}
                    manualPagination
                    pageCount={stocks.last_page}
                    totalRows={stocks.total}
                    emptyMessage="Aucun stock enregistré."
                />
            </div>
        </>
    );
}

StockLevelsIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Stock actuel', href: '#' },
    ],
};
