import { Head, Link, router } from '@inertiajs/react';
import {
    createColumnHelper,
    type ColumnDef,
    type PaginationState,
    type SortingState,
} from '@tanstack/react-table';
import { Download, FileSpreadsheet, FileText } 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 {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { index as stockMovementsIndex } from '@/routes/admin/stock-movements';
import {
    excel as stockMovementsExportExcel,
    pdf as stockMovementsExportPdf,
} from '@/routes/admin/stock-movements/export';
import { show as inventoryShow } from '@/routes/admin/inventories';
import { show as stockExitShow } from '@/routes/admin/stock-exits';
import { show as receiptShow } from '@/routes/admin/warehouses/receipts';
import type { Paginated } from '@/types';

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

type MovementRow = {
    id: number;
    type: string;
    type_label: string;
    signed_quantity: number;
    quantity: number;
    motif: string | null;
    occurred_at: string | null;
    warehouse: WarehouseOption | null;
    product: { id: number; code: string; name: string } | null;
    performed_by: { id: number; name: string } | null;
    source: {
        type: string;
        label: string;
        id: number;
        code: string | null;
        warehouse_id: number | null;
    } | null;
};

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

const columnHelper = createColumnHelper<MovementRow>();

function sourceHref(source: MovementRow['source']): string | null {
    if (source === null) {
        return null;
    }

    if (source.type.includes('StockExit')) {
        return stockExitShow.url(source.id);
    }

    if (source.type.includes('StockInventory')) {
        return inventoryShow.url(source.id);
    }

    if (source.type.includes('StockReceipt') && source.warehouse_id !== null) {
        return receiptShow.url([source.warehouse_id, source.id]);
    }

    return null;
}

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

export default function StockMovementsIndex({
    movements,
    warehouses,
    types,
    filters,
    filteredProduct = null,
}: {
    movements: Paginated<MovementRow>;
    warehouses: WarehouseOption[];
    types: TypeOption[];
    filters: Filters;
    filteredProduct?: { id: number; code: string; name: string } | null;
}) {
    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 [typeFilter, setTypeFilter] = useState<string>(filters.type ?? 'all');
    const [sorting, setSorting] = useState<SortingState>([
        { id: filters.sort, desc: filters.direction === 'desc' },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: movements.current_page - 1,
        pageSize: movements.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',
        );
        setTypeFilter(filters.type ?? 'all');
        setSorting([{ id: filters.sort, desc: filters.direction === 'desc' }]);
        setPagination({
            pageIndex: movements.current_page - 1,
            pageSize: movements.per_page,
        });
    }, [filters, movements.current_page, movements.per_page]);

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

        const timeout = window.setTimeout(() => {
            visitMovements({
                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),
                type: typeFilter === 'all' ? null : typeFilter,
                product_id: filters.product_id,
            });
        }, 300);

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

    const columns = useMemo<ColumnDef<MovementRow, unknown>[]>(
        () => [
            columnHelper.accessor('occurred_at', {
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Date" />
                ),
                meta: { label: 'Date' },
                cell: (info) => formatDate(info.getValue()),
            }),
            columnHelper.accessor('type', {
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Type" />
                ),
                meta: { label: 'Type' },
                cell: (info) => (
                    <Badge
                        variant={
                            info.row.original.signed_quantity < 0
                                ? 'destructive'
                                : 'secondary'
                        }
                    >
                        {info.row.original.type_label}
                    </Badge>
                ),
            }),
            columnHelper.accessor((row) => row.product?.name ?? '', {
                id: 'product',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Produit" />
                ),
                meta: { label: 'Produit' },
                enableSorting: false,
                cell: (info) => (
                    <div className="flex flex-col gap-0.5">
                        <span className="text-sm font-medium">
                            {info.row.original.product?.name ?? '—'}
                        </span>
                        <span className="text-muted-foreground font-mono text-xs">
                            {info.row.original.product?.code ?? '—'}
                        </span>
                    </div>
                ),
            }),
            columnHelper.accessor((row) => row.warehouse?.name ?? '', {
                id: 'warehouse',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Entrepôt" />
                ),
                meta: { label: 'Entrepôt' },
                enableSorting: false,
                cell: (info) => info.row.original.warehouse?.name ?? '—',
            }),
            columnHelper.accessor('signed_quantity', {
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Quantité" />
                ),
                meta: { label: 'Quantité' },
                cell: (info) => {
                    const value = info.getValue();

                    return (
                        <span
                            className={`tabular-nums font-medium ${
                                value < 0 ? 'text-destructive' : ''
                            }`}
                        >
                            {value > 0 ? `+${value}` : value}
                        </span>
                    );
                },
            }),
            columnHelper.accessor('motif', {
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Motif" />
                ),
                meta: { label: 'Motif' },
                enableSorting: false,
                cell: (info) => (
                    <span className="text-muted-foreground text-sm">
                        {info.getValue() ?? '—'}
                    </span>
                ),
            }),
            columnHelper.display({
                id: 'source',
                enableSorting: false,
                header: () => 'Origine',
                meta: { label: 'Origine' },
                cell: ({ row }) => {
                    const source = row.original.source;

                    if (source === null) {
                        return (
                            <span className="text-muted-foreground">—</span>
                        );
                    }

                    const href = sourceHref(source);
                    const label = source.code
                        ? `${source.label} ${source.code}`
                        : source.label;

                    if (href === null) {
                        return (
                            <span className="text-sm">
                                {label}
                            </span>
                        );
                    }

                    return (
                        <Link
                            href={href}
                            className="text-sm font-medium underline-offset-4 hover:underline"
                        >
                            {label}
                        </Link>
                    );
                },
            }),
            columnHelper.accessor((row) => row.performed_by?.name ?? '', {
                id: 'performed_by',
                header: ({ column }) => (
                    <DataTableColumnHeader column={column} title="Par" />
                ),
                meta: { label: 'Par' },
                enableSorting: false,
                cell: (info) => info.row.original.performed_by?.name ?? '—',
            }),
        ],
        [],
    );

    return (
        <>
            <Head title="Mouvements de stock" />

            <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="Mouvements de stock"
                        description="Historique des entrées, sorties et ajustements"
                    />
                    <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                            <Button variant="outline">
                                <Download />
                                Exporter
                            </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                            <DropdownMenuItem asChild>
                                <a
                                    href={stockMovementsExportExcel.url({
                                        query: {
                                            search: search || undefined,
                                            sort:
                                                sorting[0]?.id ?? filters.sort,
                                            direction: sorting[0]?.desc
                                                ? 'desc'
                                                : 'asc',
                                            warehouse_id:
                                                warehouseFilter === 'all'
                                                    ? undefined
                                                    : Number(warehouseFilter),
                                            type:
                                                typeFilter === 'all'
                                                    ? undefined
                                                    : typeFilter,
                                        },
                                    })}
                                >
                                    <FileSpreadsheet />
                                    Excel
                                </a>
                            </DropdownMenuItem>
                            <DropdownMenuItem asChild>
                                <a
                                    href={stockMovementsExportPdf.url({
                                        query: {
                                            search: search || undefined,
                                            sort:
                                                sorting[0]?.id ?? filters.sort,
                                            direction: sorting[0]?.desc
                                                ? 'desc'
                                                : 'asc',
                                            warehouse_id:
                                                warehouseFilter === 'all'
                                                    ? undefined
                                                    : Number(warehouseFilter),
                                            type:
                                                typeFilter === 'all'
                                                    ? undefined
                                                    : typeFilter,
                                        },
                                    })}
                                >
                                    <FileText />
                                    PDF
                                </a>
                            </DropdownMenuItem>
                        </DropdownMenuContent>
                    </DropdownMenu>
                </div>

                {filteredProduct && (
                    <div className="flex items-center gap-2 rounded-lg border bg-muted/40 px-3 py-2 text-sm">
                        <span className="text-muted-foreground">
                            Filtré pour le produit :
                        </span>
                        <span className="font-medium">
                            {filteredProduct.code} — {filteredProduct.name}
                        </span>
                        <Button
                            variant="ghost"
                            size="sm"
                            className="ml-auto"
                            onClick={() =>
                                visitMovements({
                                    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),
                                    type:
                                        typeFilter === 'all'
                                            ? null
                                            : typeFilter,
                                    product_id: null,
                                })
                            }
                        >
                            Retirer le filtre
                        </Button>
                    </div>
                )}

                <div className="flex flex-wrap gap-3">
                    <Select
                        value={warehouseFilter}
                        onValueChange={(value) => {
                            setWarehouseFilter(value);
                            visitMovements({
                                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),
                                type: typeFilter === 'all' ? null : typeFilter,
                                product_id: filters.product_id,
                            });
                        }}
                    >
                        <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>

                    <Select
                        value={typeFilter}
                        onValueChange={(value) => {
                            setTypeFilter(value);
                            visitMovements({
                                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),
                                type: value === 'all' ? null : value,
                                product_id: filters.product_id,
                            });
                        }}
                    >
                        <SelectTrigger className="w-55">
                            <SelectValue placeholder="Type" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">Tous les types</SelectItem>
                            {types.map((type) => (
                                <SelectItem
                                    key={type.value}
                                    value={type.value}
                                >
                                    {type.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>

                <DataTable
                    id="admin-stock-movements"
                    columns={columns}
                    data={movements.data}
                    getRowId={(row) => String(row.id)}
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher par produit, motif, entrepôt…"
                    isLoading={isLoading}
                    sorting={sorting}
                    onSortingChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(sorting)
                                : updater;
                        setSorting(next);
                        visitMovements({
                            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),
                            type: typeFilter === 'all' ? null : typeFilter,
                            product_id: filters.product_id,
                        });
                    }}
                    manualSorting
                    pagination={pagination}
                    onPaginationChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(pagination)
                                : updater;
                        const sizeChanged =
                            next.pageSize !== pagination.pageSize;
                        setPagination(next);
                        visitMovements({
                            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),
                            type: typeFilter === 'all' ? null : typeFilter,
                            product_id: filters.product_id,
                        });
                    }}
                    manualPagination
                    pageCount={movements.last_page}
                    totalRows={movements.total}
                    emptyMessage="Aucun mouvement enregistré."
                />
            </div>
        </>
    );
}

StockMovementsIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Mouvements de stock', href: '#' },
    ],
};
