import { Head, Link, router } from '@inertiajs/react';
import {
    createColumnHelper
    
    
    
} from '@tanstack/react-table';
import type {ColumnDef, PaginationState, SortingState} from '@tanstack/react-table';
import { AlertTriangle, Download, Eye, Pencil, Plus, Printer, Trash2 } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import PurchaseOrderController from '@/actions/App/Http/Controllers/Admin/PurchaseOrderController';
import { ConfirmDialog } from '@/components/confirm-dialog';
import {
    DataTable,
    DataTableBulkDelete,
    DataTableColumnHeader,
    withSelectionColumn,
} from '@/components/data-table';
import Heading from '@/components/heading';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { useCan, useHasRole } from '@/hooks/use-can';
import { formatCurrency, formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { create, edit, exportMethod, index, pdf, show } from '@/routes/admin/purchase-orders';
import type { Paginated } from '@/types';
import { PurchaseOrderStatusBadge } from './status-badge';

type AdminPurchaseOrder = {
    id: number;
    code: string;
    supplier: { id: number; name: string } | null;
    status: string;
    status_label: string;
    order_date: string | null;
    expected_delivery_date: string | null;
    invoice_due_date: string | null;
    total_amount: string | number;
    created_at: string | null;
};

type StatusOption = { value: string; label: string };
type SupplierOption = { id: number; code: string; name: string };

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

const columnHelper = createColumnHelper<AdminPurchaseOrder>();

function visitOrders(params: {
    search: string;
    sort: string;
    direction: 'asc' | 'desc';
    page: number;
    per_page: number;
    supplier_id: number | null;
    status: string | null;
    alert: 'delivery' | 'invoice' | null;
}) {
    router.get(
        index.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,
            supplier_id: params.supplier_id ?? undefined,
            status: params.alert ? undefined : (params.status ?? undefined),
            alert: params.alert ?? undefined,
        },
        {
            preserveState: true,
            replace: true,
            preserveScroll: true,
        },
    );
}

export default function PurchaseOrdersIndex({
    orders,
    suppliers,
    statuses,
    alerts,
    filters,
}: {
    orders: Paginated<AdminPurchaseOrder>;
    suppliers: SupplierOption[];
    statuses: StatusOption[];
    alerts: { delivery: number; invoice: number };
    filters: Filters;
}) {
    const canCreate = useCan('purchase-orders.create');
    const canUpdate = useCan('purchase-orders.update');
    const canDelete =
        useCan('purchase-orders.delete') || useHasRole('super-admin');
    const isFirstSearchEffect = useRef(true);
    const [isLoading, setIsLoading] = useState(false);

    const [search, setSearch] = useState(filters.search);
    const [supplierId, setSupplierId] = useState<string>(
        filters.supplier_id ? String(filters.supplier_id) : 'all',
    );
    const [status, setStatus] = useState<string>(filters.status ?? 'all');
    const [alertFilter, setAlertFilter] = useState<
        'delivery' | 'invoice' | null
    >(filters.alert);
    const [sorting, setSorting] = useState<SortingState>([
        { id: filters.sort, desc: filters.direction === 'desc' },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: orders.current_page - 1,
        pageSize: orders.per_page,
    });

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

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

    useEffect(() => {
        setSearch(filters.search);
        setSupplierId(filters.supplier_id ? String(filters.supplier_id) : 'all');
        setStatus(filters.status ?? 'all');
        setAlertFilter(filters.alert);
        setSorting([{ id: filters.sort, desc: filters.direction === 'desc' }]);
        setPagination({
            pageIndex: orders.current_page - 1,
            pageSize: orders.per_page,
        });
    }, [filters, orders.current_page, orders.per_page]);

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

            return;
        }

        const timeout = window.setTimeout(() => {
            const sort = sorting[0];
            visitOrders({
                search,
                sort: sort?.id ?? 'created_at',
                direction: sort?.desc === false ? 'asc' : 'desc',
                page: 1,
                per_page: pagination.pageSize,
                supplier_id: supplierId === 'all' ? null : Number(supplierId),
                status: status === 'all' ? null : status,
                alert: alertFilter,
            });
        }, 300);

        return () => window.clearTimeout(timeout);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [search]);

    function currentVisitParams(overrides: {
        supplier_id?: string;
        status?: string;
        alert?: 'delivery' | 'invoice' | null;
        page?: number;
        per_page?: number;
        sort?: string;
        direction?: 'asc' | 'desc';
    } = {}) {
        const sort = sorting[0];
        const nextSupplier = overrides.supplier_id ?? supplierId;
        const nextAlert =
            overrides.alert !== undefined ? overrides.alert : alertFilter;
        const nextStatus =
            nextAlert !== null
                ? 'all'
                : (overrides.status ?? status);

        return {
            search,
            sort: overrides.sort ?? sort?.id ?? 'created_at',
            direction:
                overrides.direction ??
                (sort?.desc === false ? 'asc' : 'desc'),
            page: overrides.page ?? 1,
            per_page: overrides.per_page ?? pagination.pageSize,
            supplier_id: nextSupplier === 'all' ? null : Number(nextSupplier),
            status: nextStatus === 'all' ? null : nextStatus,
            alert: nextAlert,
        } as const;
    }

    function applyFilters(next: {
        supplier_id?: string;
        status?: string;
        alert?: 'delivery' | 'invoice' | null;
    }) {
        if (next.supplier_id !== undefined) {
            setSupplierId(next.supplier_id);
        }
        if (next.alert !== undefined) {
            setAlertFilter(next.alert);
            if (next.alert !== null) {
                setStatus('all');
            }
        }
        if (next.status !== undefined) {
            setStatus(next.status);
            setAlertFilter(null);
        }

        visitOrders(
            currentVisitParams({
                ...next,
                alert:
                    next.status !== undefined
                        ? null
                        : next.alert !== undefined
                          ? next.alert
                          : alertFilter,
            }),
        );
    }

    const columns = useMemo(
        () =>
            withSelectionColumn([
                columnHelper.accessor('code', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Code" />
                    ),
                    meta: { label: 'Code' },
                    cell: (info) => (
                        <span className="font-mono text-sm">
                            {info.getValue()}
                        </span>
                    ),
                }),
                columnHelper.accessor('supplier', {
                    header: 'Fournisseur',
                    enableSorting: false,
                    meta: { label: 'Fournisseur' },
                    cell: (info) => (
                        <span className="font-medium">
                            {info.getValue()?.name ?? '—'}
                        </span>
                    ),
                }),
                columnHelper.accessor('status', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Statut" />
                    ),
                    meta: { label: 'Statut' },
                    cell: ({ row }) => (
                        <PurchaseOrderStatusBadge
                            status={row.original.status}
                            label={row.original.status_label}
                        />
                    ),
                }),
                columnHelper.accessor('order_date', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Commande"
                        />
                    ),
                    meta: { label: 'Commande' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {formatDate(info.getValue())}
                        </span>
                    ),
                }),
                columnHelper.accessor('expected_delivery_date', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Livraison"
                        />
                    ),
                    meta: { label: 'Livraison' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {formatDate(info.getValue())}
                        </span>
                    ),
                }),
                columnHelper.accessor('invoice_due_date', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Échéance facture"
                        />
                    ),
                    meta: { label: 'Échéance facture' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {formatDate(info.getValue())}
                        </span>
                    ),
                }),
                columnHelper.accessor('total_amount', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Total" />
                    ),
                    meta: { label: 'Total' },
                    cell: (info) => (
                        <span className="tabular-nums">
                            {formatCurrency(info.getValue())}
                        </span>
                    ),
                }),
                columnHelper.display({
                    id: 'actions',
                    enableSorting: false,
                    enableHiding: false,
                    header: () => <div className="text-right">Actions</div>,
                    cell: ({ row }) => {
                        const order = row.original;

                        return (
                            <div className="flex justify-end gap-1">
                                <Button
                                    variant="outline"
                                    size="icon"
                                    asChild
                                >
                                    <Link
                                        href={show(order.id)}
                                        aria-label={`Voir ${order.code}`}
                                    >
                                        <Eye />
                                    </Link>
                                </Button>
                                <Button
                                    variant="outline"
                                    size="icon"
                                    asChild
                                >
                                    <a
                                        href={pdf(order.id).url}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        aria-label={`Imprimer ${order.code}`}
                                    >
                                        <Printer />
                                    </a>
                                </Button>
                                {canUpdate &&
                                    order.status !== 'invoiced' &&
                                    order.status !== 'cancelled' && (
                                    <Button
                                        variant="outline"
                                        size="icon"
                                        asChild
                                    >
                                        <Link
                                            href={edit(order.id)}
                                            aria-label={`Modifier ${order.code}`}
                                        >
                                            <Pencil />
                                        </Link>
                                    </Button>
                                )}
                                {canDelete &&
                                    order.status !== 'invoiced' && (
                                    <ConfirmDialog
                                        trigger={
                                            <Button
                                                variant="destructive"
                                                size="icon"
                                                aria-label={`Supprimer ${order.code}`}
                                            >
                                                <Trash2 />
                                            </Button>
                                        }
                                        title={`Supprimer la commande ${order.code} ?`}
                                        description="Cette action est irréversible."
                                        confirmLabel="Supprimer"
                                        onConfirm={() => {
                                            router.delete(
                                                PurchaseOrderController.destroy.url(
                                                    order.id,
                                                ),
                                                { preserveScroll: true },
                                            );
                                        }}
                                    />
                                )}
                            </div>
                        );
                    },
                }),
            ] as ColumnDef<AdminPurchaseOrder>[]),
        [canUpdate, canDelete],
    );

    const hasAlerts = alerts.delivery > 0 || alerts.invoice > 0;

    return (
        <>
            <Head title="Commandes" />

            <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="Commandes"
                        description="Bons de commande fournisseurs"
                    />
                    <div className="flex flex-wrap gap-2">
                        <Button variant="outline" asChild>
                            <a
                                href={exportMethod.url({
                                    query: {
                                        search: search || undefined,
                                        sort: sorting[0]?.id ?? filters.sort,
                                        direction:
                                            sorting[0]?.desc === false
                                                ? 'asc'
                                                : 'desc',
                                        supplier_id:
                                            supplierId === 'all'
                                                ? undefined
                                                : Number(supplierId),
                                        status:
                                            status === 'all'
                                                ? undefined
                                                : status,
                                        alert: alertFilter ?? undefined,
                                    },
                                })}
                            >
                                <Download />
                                Exporter
                            </a>
                        </Button>
                        {canCreate && (
                            <Button asChild>
                                <Link href={create()}>
                                    <Plus />
                                    Nouvelle commande
                                </Link>
                            </Button>
                        )}
                    </div>
                </div>

                {hasAlerts && (
                    <Alert>
                        <AlertTriangle />
                        <AlertTitle>Rappels</AlertTitle>
                        <AlertDescription className="space-y-3">
                            {alerts.delivery > 0 && (
                                <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                                    <p>
                                        {alerts.delivery} commande
                                        {alerts.delivery > 1 ? 's' : ''} en
                                        attente de livraison (échéance
                                        dépassée).
                                    </p>
                                    <Button
                                        variant={
                                            alertFilter === 'delivery'
                                                ? 'default'
                                                : 'outline'
                                        }
                                        size="sm"
                                        onClick={() =>
                                            applyFilters({
                                                alert: 'delivery',
                                            })
                                        }
                                    >
                                        Voir les livraisons en retard
                                    </Button>
                                </div>
                            )}
                            {alerts.invoice > 0 && (
                                <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                                    <p>
                                        {alerts.invoice} commande
                                        {alerts.invoice > 1 ? 's' : ''} en
                                        attente de facturation (échéance
                                        dépassée).
                                    </p>
                                    <Button
                                        variant={
                                            alertFilter === 'invoice'
                                                ? 'default'
                                                : 'outline'
                                        }
                                        size="sm"
                                        onClick={() =>
                                            applyFilters({
                                                alert: 'invoice',
                                            })
                                        }
                                    >
                                        Voir les facturations en retard
                                    </Button>
                                </div>
                            )}
                            {alertFilter !== null && (
                                <div>
                                    <Button
                                        variant="ghost"
                                        size="sm"
                                        onClick={() =>
                                            applyFilters({ alert: null })
                                        }
                                    >
                                        Effacer le rappel
                                    </Button>
                                </div>
                            )}
                        </AlertDescription>
                    </Alert>
                )}

                {!hasAlerts && alertFilter !== null && (
                    <Alert>
                        <AlertTriangle />
                        <AlertTitle>Filtre rappel actif</AlertTitle>
                        <AlertDescription className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                            <p>
                                {alertFilter === 'delivery'
                                    ? 'Affichage des livraisons en retard.'
                                    : 'Affichage des facturations en retard.'}
                            </p>
                            <Button
                                variant="outline"
                                size="sm"
                                onClick={() => applyFilters({ alert: null })}
                            >
                                Effacer le rappel
                            </Button>
                        </AlertDescription>
                    </Alert>
                )}

                <DataTable
                    id="admin-purchase-orders"
                    columns={columns}
                    data={orders.data}
                    getRowId={(row) => String(row.id)}
                    isLoading={isLoading}
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher par code ou fournisseur…"
                    emptyMessage="Aucune commande."
                    toolbarLeft={
                        <div className="flex flex-wrap gap-2">
                            <Select
                                value={supplierId}
                                onValueChange={(value) => {
                                    setSupplierId(value);
                                    applyFilters({ supplier_id: value });
                                }}
                            >
                                <SelectTrigger className="w-[180px]">
                                    <SelectValue placeholder="Fournisseur" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="all">
                                        Tous les fournisseurs
                                    </SelectItem>
                                    {suppliers.map((supplier) => (
                                        <SelectItem
                                            key={supplier.id}
                                            value={String(supplier.id)}
                                        >
                                            {supplier.name}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>

                            <Select
                                value={status}
                                onValueChange={(value) => {
                                    setStatus(value);
                                    applyFilters({ status: value });
                                }}
                            >
                                <SelectTrigger className="w-[160px]">
                                    <SelectValue placeholder="Statut" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="all">
                                        Tous les statuts
                                    </SelectItem>
                                    {statuses.map((option) => (
                                        <SelectItem
                                            key={option.value}
                                            value={option.value}
                                        >
                                            {option.label}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    }
                    sorting={sorting}
                    onSortingChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(sorting)
                                : updater;
                        setSorting(next);

                        const sort = next[0];
                        visitOrders(
                            currentVisitParams({
                                sort: sort?.id ?? 'created_at',
                                direction:
                                    sort?.desc === false ? 'asc' : 'desc',
                                page: 1,
                            }),
                        );
                    }}
                    manualSorting
                    pagination={pagination}
                    onPaginationChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(pagination)
                                : updater;
                        const pageChanged =
                            next.pageIndex !== pagination.pageIndex;
                        const sizeChanged =
                            next.pageSize !== pagination.pageSize;

                        setPagination(next);

                        if (!pageChanged && !sizeChanged) {
                            return;
                        }

                        visitOrders(
                            currentVisitParams({
                                page: sizeChanged ? 1 : next.pageIndex + 1,
                                per_page: next.pageSize,
                            }),
                        );
                    }}
                    manualPagination
                    pageCount={orders.last_page}
                    totalRows={orders.total}
                    bulkActions={
                        canDelete
                            ? ({ rows, clearSelection }) => (
                                  <DataTableBulkDelete
                                      count={rows.length}
                                      label="Supprimer"
                                      confirmTitle={`Supprimer ${rows.length} commande${rows.length > 1 ? 's' : ''} ?`}
                                      onDelete={() => {
                                          router.delete(
                                              PurchaseOrderController.bulkDestroy.url(),
                                              {
                                                  data: {
                                                      ids: rows.map(
                                                          (row) => row.id,
                                                      ),
                                                  },
                                                  preserveScroll: true,
                                                  onSuccess: () =>
                                                      clearSelection(),
                                              },
                                          );
                                      }}
                                  />
                              )
                            : undefined
                    }
                />
            </div>
        </>
    );
}

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