import { Head, Link, router } from '@inertiajs/react';
import {
    createColumnHelper,
    type ColumnDef,
    type PaginationState,
    type SortingState,
} from '@tanstack/react-table';
import { ArrowLeft, Eye, Pencil } 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 {
    Card,
    CardContent,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { useCan } from '@/hooks/use-can';
import { formatCurrency, formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { show as showPurchaseOrder } from '@/routes/admin/purchase-orders';
import { index as supplierInvoicesIndex } from '@/routes/admin/supplier-invoices';
import { index, show } from '@/routes/admin/suppliers';
import type { Paginated } from '@/types';
import { PurchaseOrderStatusBadge } from '../purchase-orders/status-badge';
import {
    SupplierFormModal,
    type SupplierFormValues,
} from './supplier-form-modal';

type Supplier = {
    id: number;
    code: string;
    name: string;
    contact_name: string | null;
    email: string | null;
    phone: string | null;
    address: string | null;
    payment_terms: string | null;
    is_active: boolean;
};

type SupplierOrder = {
    id: number;
    code: string;
    status: string;
    status_label: string;
    order_date: string | null;
    expected_delivery_date: string | null;
    invoice_due_date: string | null;
    total_amount: string | number;
};

type Summary = {
    orders_count: number;
    total_amount: string;
    next_delivery_due: string | null;
    next_invoice_due: string | null;
    pending_invoices_count: number;
    pending_invoices_amount: string;
};

type StatusOption = { value: string; label: string };

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

const columnHelper = createColumnHelper<SupplierOrder>();

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

export default function SuppliersShow({
    supplier,
    orders,
    summary,
    filters,
    statuses,
    can_view_orders: canViewOrders,
}: {
    supplier: Supplier;
    orders: Paginated<SupplierOrder> | null;
    summary: Summary | null;
    filters: Filters;
    statuses: StatusOption[];
    can_view_orders: boolean;
}) {
    const canUpdate = useCan('suppliers.update');
    const isFirstSearchEffect = useRef(true);
    const [isLoading, setIsLoading] = useState(false);
    const [modalOpen, setModalOpen] = useState(false);

    const [search, setSearch] = useState(filters.search);
    const [status, setStatus] = useState<string>(filters.status ?? 'all');
    const [sorting, setSorting] = useState<SortingState>([
        { id: filters.sort, desc: filters.direction === 'desc' },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: orders?.current_page ? orders.current_page - 1 : 0,
        pageSize: orders?.per_page ?? filters.per_page,
    });

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

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

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

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

            return;
        }

        if (!canViewOrders || !orders) {
            return;
        }

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

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

    function applyFilters(overrides: {
        status?: string;
    } = {}) {
        const nextStatus = overrides.status ?? status;
        const sort = sorting[0];

        visitOrders(supplier.id, {
            search,
            sort: sort?.id ?? 'created_at',
            direction: sort?.desc === false ? 'asc' : 'desc',
            page: 1,
            per_page: pagination.pageSize,
            status: nextStatus === 'all' ? null : nextStatus,
        });
    }

    const columns = useMemo(
        () =>
            [
                columnHelper.accessor('code', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Code" />
                    ),
                    meta: { label: 'Code' },
                    cell: (info) => (
                        <span className="font-medium">{info.getValue()}</span>
                    ),
                }),
                columnHelper.accessor('order_date', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Date commande"
                        />
                    ),
                    meta: { label: 'Date commande' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {formatDate(info.getValue())}
                        </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('total_amount', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Montant"
                        />
                    ),
                    meta: { label: 'Montant' },
                    cell: (info) => (
                        <span className="tabular-nums">
                            {formatCurrency(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.display({
                    id: 'actions',
                    enableSorting: false,
                    enableHiding: false,
                    header: () => <div className="text-right">Actions</div>,
                    cell: ({ row }) => (
                        <div className="flex justify-end">
                            <Button variant="outline" size="icon" asChild>
                                <Link
                                    href={showPurchaseOrder(row.original.id)}
                                    aria-label={`Voir ${row.original.code}`}
                                >
                                    <Eye />
                                </Link>
                            </Button>
                        </div>
                    ),
                }),
            ] as ColumnDef<SupplierOrder>[],
        [],
    );

    const formSupplier: SupplierFormValues = {
        id: supplier.id,
        code: supplier.code,
        name: supplier.name,
        contact_name: supplier.contact_name,
        email: supplier.email,
        phone: supplier.phone,
        address: supplier.address,
        payment_terms: supplier.payment_terms,
        is_active: supplier.is_active,
    };

    return (
        <>
            <Head title={supplier.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">
                    <div className="space-y-2">
                        <Heading
                            title={supplier.name}
                            description={supplier.code}
                        />
                        {supplier.is_active ? (
                            <Badge variant="secondary">Actif</Badge>
                        ) : (
                            <Badge variant="outline">Inactif</Badge>
                        )}
                    </div>
                    <div className="flex flex-wrap gap-2">
                        <Button variant="outline" asChild>
                            <Link href={index()}>
                                <ArrowLeft />
                                Retour
                            </Link>
                        </Button>
                        {canUpdate && (
                            <Button
                                variant="outline"
                                onClick={() => setModalOpen(true)}
                            >
                                <Pencil />
                                Modifier
                            </Button>
                        )}
                    </div>
                </div>

                <div className="grid gap-6 lg:grid-cols-3">
                    <Card className="lg:col-span-2">
                        <CardHeader>
                            <CardTitle>Identité</CardTitle>
                        </CardHeader>
                        <CardContent>
                            <dl className="grid gap-4 sm:grid-cols-2">
                                <div>
                                    <dt className="text-muted-foreground text-sm">
                                        Personne de contact
                                    </dt>
                                    <dd>{supplier.contact_name || '—'}</dd>
                                </div>
                                <div>
                                    <dt className="text-muted-foreground text-sm">
                                        Email
                                    </dt>
                                    <dd>{supplier.email || '—'}</dd>
                                </div>
                                <div>
                                    <dt className="text-muted-foreground text-sm">
                                        Téléphone
                                    </dt>
                                    <dd>{supplier.phone || '—'}</dd>
                                </div>
                                <div>
                                    <dt className="text-muted-foreground text-sm">
                                        Conditions de paiement
                                    </dt>
                                    <dd>{supplier.payment_terms || '—'}</dd>
                                </div>
                                <div className="sm:col-span-2">
                                    <dt className="text-muted-foreground text-sm">
                                        Adresse
                                    </dt>
                                    <dd className="whitespace-pre-line">
                                        {supplier.address || '—'}
                                    </dd>
                                </div>
                            </dl>
                        </CardContent>
                    </Card>

                    {canViewOrders && summary && (
                        <Card>
                            <CardHeader>
                                <CardTitle>Résumé commandes</CardTitle>
                            </CardHeader>
                            <CardContent className="space-y-4">
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Commandes
                                    </p>
                                    <p className="text-2xl font-semibold tabular-nums">
                                        {summary.orders_count}
                                    </p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Montant cumulé
                                    </p>
                                    <p className="text-2xl font-semibold tabular-nums">
                                        {formatCurrency(summary.total_amount)}
                                    </p>
                                    <p className="text-muted-foreground text-xs">
                                        Hors commandes annulées
                                    </p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Prochaine livraison
                                    </p>
                                    <p>{formatDate(summary.next_delivery_due)}</p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Prochaine échéance facture
                                    </p>
                                    <p>{formatDate(summary.next_invoice_due)}</p>
                                </div>
                                <div>
                                    <p className="text-muted-foreground text-sm">
                                        Factures en attente de paiement
                                    </p>
                                    <p className="text-2xl font-semibold tabular-nums">
                                        {summary.pending_invoices_count}
                                    </p>
                                    {summary.pending_invoices_count > 0 && (
                                        <p className="text-muted-foreground text-xs">
                                            {formatCurrency(
                                                summary.pending_invoices_amount,
                                            )}{' '}
                                            au total
                                        </p>
                                    )}
                                </div>
                                <Button
                                    variant="outline"
                                    className="w-full"
                                    asChild
                                >
                                    <Link
                                        href={`${supplierInvoicesIndex.url()}?supplier_id=${supplier.id}`}
                                    >
                                        Voir les factures fournisseur
                                    </Link>
                                </Button>
                            </CardContent>
                        </Card>
                    )}
                </div>

                {canViewOrders && orders ? (
                    <div className="space-y-4">
                        <Heading
                            title="Historique des commandes"
                            description="Montants et échéances de ce fournisseur"
                        />
                        <DataTable
                            id="admin-supplier-purchase-orders"
                            columns={columns}
                            data={orders.data}
                            getRowId={(row) => String(row.id)}
                            isLoading={isLoading}
                            searchValue={search}
                            onSearchChange={setSearch}
                            searchPlaceholder="Rechercher par code…"
                            emptyMessage="Aucune commande pour ce fournisseur."
                            toolbarLeft={
                                <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>
                            }
                            sorting={sorting}
                            onSortingChange={(updater) => {
                                const next =
                                    typeof updater === 'function'
                                        ? updater(sorting)
                                        : updater;
                                setSorting(next);
                                const sort = next[0];
                                visitOrders(supplier.id, {
                                    search,
                                    sort: sort?.id ?? 'created_at',
                                    direction:
                                        sort?.desc === false ? 'asc' : 'desc',
                                    page: 1,
                                    per_page: pagination.pageSize,
                                    status: status === 'all' ? null : status,
                                });
                            }}
                            manualSorting
                            pagination={pagination}
                            onPaginationChange={(updater) => {
                                const next =
                                    typeof updater === 'function'
                                        ? updater(pagination)
                                        : updater;
                                const sizeChanged =
                                    next.pageSize !== pagination.pageSize;
                                setPagination(next);
                                const sort = sorting[0];
                                visitOrders(supplier.id, {
                                    search,
                                    sort: sort?.id ?? 'created_at',
                                    direction:
                                        sort?.desc === false ? 'asc' : 'desc',
                                    page: sizeChanged ? 1 : next.pageIndex + 1,
                                    per_page: next.pageSize,
                                    status: status === 'all' ? null : status,
                                });
                            }}
                            manualPagination
                            pageCount={orders.last_page}
                            totalRows={orders.total}
                        />
                    </div>
                ) : (
                    <Card>
                        <CardContent className="text-muted-foreground py-8 text-center text-sm">
                            Vous n&apos;avez pas accès à l&apos;historique des
                            commandes.
                        </CardContent>
                    </Card>
                )}
            </div>

            {canUpdate && (
                <SupplierFormModal
                    open={modalOpen}
                    onOpenChange={setModalOpen}
                    supplier={formSupplier}
                />
            )}
        </>
    );
}

SuppliersShow.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Fournisseurs', href: index() },
        { title: 'Fiche', href: '#' },
    ],
};
