import { Form, Head, Link, router, useForm } from '@inertiajs/react';
import { useEffect, useRef, useState } from 'react';

import HeadingSmall from '@/components/heading-small';
import { SortableHeader } from '@/components/sortable-header';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { useUserTimezone } from '@/hooks/use-user-timezone';
import AppLayout from '@/layouts/app-layout';
import { formatDateTime } from '@/lib/format-date';
import { productProperName } from '@/lib/utils';
import { index, logs as logsRoute, status as statusRoute, submit as submitRoute, updateFields, archive, bulkArchive } from '@/routes/admin/supplier-enrollments';
import { index as enrollmentRequestsIndex } from '@/routes/admin/enrollment-requests';

type SupplierEnrollmentField = {
    id: number;
    supplier_field_name: string;
    form_field_id: number | null;
    value: string | null;
};

type SupplierEnrollment = {
    id: number;
    enrollment_request_id: number;
    enrollment_request: { id: number; body: Record<string, unknown> | null } | null;
    supplier: { id: number; name: string; slug: string } | null;
    product: { id: number; name: string } | null;
    status: string;
    error_message: string | null;
    supplier_tracking_id: string | null;
    body: Record<string, unknown> | null;
    fields: SupplierEnrollmentField[];
    submitted_at: string | null;
    created_at: string;
    deleted_at: string | null;
};

type PaginatedEnrollments = {
    data: SupplierEnrollment[];
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
    links: { url: string | null; label: string; active: boolean }[];
};

type Filters = {
    search: string;
    supplier_id: string;
    status: string;
    sort_by: string;
    sort_direction: string;
    trashed: string;
};

type Props = {
    enrollments: PaginatedEnrollments;
    filters: Filters;
    suppliers: { id: number; name: string }[];
};

const statusColors: Record<string, string> = {
    pending: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300',
    submitted: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300',
    confirmed: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300',
    rejected: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300',
    error: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300',
};

function StatusBadge({ status }: { status: string }) {
    return (
        <span
            className={`inline-block rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[status] ?? 'bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400'}`}
        >
            {status}
        </span>
    );
}


type EnrollmentLog = {
    id: number;
    endpoint: string;
    request_body: Record<string, unknown> | null;
    response_status: number | null;
    response_body: Record<string, unknown> | null;
    successful: boolean;
    created_at: string;
};

function downloadJson(data: Record<string, unknown>, filename: string): void {
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const anchor = document.createElement('a');
    anchor.href = url;
    anchor.download = filename;
    anchor.click();
    URL.revokeObjectURL(url);
}

function logFilename(enrollmentId: number, logId: number, type: 'request' | 'response', createdAt: string): string {
    const timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, '-');
    return `enrollment-${enrollmentId}-log-${logId}-${type}-${timestamp}.json`;
}

function LogsTab({ enrollmentId }: { enrollmentId: number }) {
    const timezone = useUserTimezone();
    const [logs, setLogs] = useState<EnrollmentLog[] | null>(null);
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
        fetch(logsRoute.url(enrollmentId))
            .then((r) => {
                if (!r.ok) throw new Error('Failed to load logs');
                return r.json() as Promise<EnrollmentLog[]>;
            })
            .then(setLogs)
            .catch((e: Error) => setError(e.message));
    }, [enrollmentId]);

    if (error) {
        return <p className="text-sm text-red-600 dark:text-red-400">{error}</p>;
    }

    if (logs === null) {
        return <p className="text-sm text-zinc-500">Loading…</p>;
    }

    if (logs.length === 0) {
        return <p className="text-sm text-zinc-500">No logs recorded for this enrollment.</p>;
    }

    return (
        <div className="space-y-3">
            {logs.map((log) => (
                <div
                    key={log.id}
                    className="overflow-hidden rounded-md border border-zinc-200 dark:border-zinc-800"
                >
                    <div className="flex items-center justify-between border-b border-zinc-200 bg-zinc-50 px-3 py-2 dark:border-zinc-800 dark:bg-zinc-900">
                        <span className="font-mono text-xs text-zinc-700 dark:text-zinc-300">
                            {log.endpoint}
                        </span>
                        <div className="flex items-center gap-2">
                            <span className="font-mono text-xs text-zinc-500">{log.response_status ?? '—'}</span>
                            <span
                                className={`inline-block rounded-full px-2 py-0.5 text-xs font-medium ${
                                    log.successful
                                        ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300'
                                        : 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300'
                                }`}
                            >
                                {log.successful ? 'success' : 'error'}
                            </span>
                            <span className="text-xs text-zinc-400">{formatDateTime(log.created_at, timezone)}</span>
                        </div>
                    </div>

                    <div className="grid grid-cols-2 divide-x divide-zinc-200 dark:divide-zinc-800">
                        <div className="p-3">
                            <div className="mb-1 flex items-center justify-between">
                                <p className="text-xs font-medium text-zinc-500">Request</p>
                                {log.request_body && (
                                    <button
                                        type="button"
                                        onClick={() =>
                                            downloadJson(
                                                log.request_body!,
                                                logFilename(enrollmentId, log.id, 'request', log.created_at),
                                            )
                                        }
                                        className="text-xs text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200"
                                        title="Download request JSON"
                                    >
                                        ↓ Download
                                    </button>
                                )}
                            </div>
                            <pre className="max-h-48 overflow-auto whitespace-pre-wrap break-all font-mono text-xs text-zinc-800 dark:text-zinc-200">
                                {log.request_body ? JSON.stringify(log.request_body, null, 2) : '—'}
                            </pre>
                        </div>
                        <div className="p-3">
                            <div className="mb-1 flex items-center justify-between">
                                <p className="text-xs font-medium text-zinc-500">Response</p>
                                {log.response_body && (
                                    <button
                                        type="button"
                                        onClick={() =>
                                            downloadJson(
                                                log.response_body!,
                                                logFilename(enrollmentId, log.id, 'response', log.created_at),
                                            )
                                        }
                                        className="text-xs text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200"
                                        title="Download response JSON"
                                    >
                                        ↓ Download
                                    </button>
                                )}
                            </div>
                            <pre className="max-h-48 overflow-auto whitespace-pre-wrap break-all font-mono text-xs text-zinc-800 dark:text-zinc-200">
                                {log.response_body ? JSON.stringify(log.response_body, null, 2) : '—'}
                            </pre>
                        </div>
                    </div>
                </div>
            ))}
        </div>
    );
}

const ENROLLMENT_TERMINAL_STATUSES = new Set(['confirmed', 'rejected', 'error']);

type EnrollmentStatusData = {
    status: string;
    error_message: string | null;
    supplier_tracking_id: string | null;
    submitted_at: string | null;
};

function EnrollmentModal({
    enrollment,
    open,
    onOpenChange,
}: {
    enrollment: SupplierEnrollment | null;
    open: boolean;
    onOpenChange: (open: boolean) => void;
}) {
    const timezone = useUserTimezone();

    if (!enrollment) return null;

    const [activeTab, setActiveTab] = useState<'fields' | 'logs'>('fields');
    const [liveStatus, setLiveStatus] = useState(enrollment.status);
    const [liveErrorMessage, setLiveErrorMessage] = useState(enrollment.error_message);
    const [liveTrackingId, setLiveTrackingId] = useState(enrollment.supplier_tracking_id);
    const [liveSubmittedAt, setLiveSubmittedAt] = useState(enrollment.submitted_at);
    const [logsKey, setLogsKey] = useState(0);
    const liveStatusRef = useRef(enrollment.status);

    const isEditable = liveStatus !== 'submitted';
    const isPolling = open && !ENROLLMENT_TERMINAL_STATUSES.has(liveStatus);

    useEffect(() => {
        if (!open || ENROLLMENT_TERMINAL_STATUSES.has(liveStatusRef.current)) return;

        const id = setInterval(() => {
            void (async () => {
                try {
                    const r = await fetch(statusRoute.url(enrollment.id));
                    if (!r.ok) return;
                    const data = await r.json() as EnrollmentStatusData;

                    if (data.status !== liveStatusRef.current) {
                        liveStatusRef.current = data.status;
                        setLiveStatus(data.status);
                        setLogsKey((k) => k + 1);

                        if (ENROLLMENT_TERMINAL_STATUSES.has(data.status)) {
                            clearInterval(id);
                        }
                    }

                    setLiveErrorMessage(data.error_message);
                    setLiveTrackingId(data.supplier_tracking_id);
                    setLiveSubmittedAt(data.submitted_at);
                } catch {
                    // ignore network errors
                }
            })();
        }, 3000);

        return () => clearInterval(id);
    }, [open, enrollment.id]);

    const form = useForm({
        fields: enrollment.fields.map((f) => ({
            id: f.id,
            value: f.value ?? '',
        })),
    });

    function handleSubmit(e: React.FormEvent) {
        e.preventDefault();
        form.put(updateFields.url(enrollment!.id), {
            onSuccess: () => onOpenChange(false),
        });
    }

    const tabClass = (tab: 'fields' | 'logs') =>
        `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${
            activeTab === tab
                ? 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
                : 'text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100'
        }`;

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-h-[80vh] max-w-5xl overflow-y-auto">
                <DialogHeader>
                    <DialogTitle>Enrollment #{enrollment.id}</DialogTitle>
                </DialogHeader>

                <div className="space-y-4 pt-2">
                    <div className="flex items-start justify-between gap-4">
                        <dl className="flex-1 divide-y divide-zinc-100 dark:divide-zinc-800">
                            {[
                                ['Supplier', enrollment.supplier?.name ?? '—'],
                                ['Product', enrollment.product ? productProperName(enrollment.product.name) : '—'],
                                ['Status', (
                                    <span className="inline-flex items-center gap-1.5">
                                        <StatusBadge status={liveStatus} />
                                        {isPolling && (
                                            <span className="inline-block size-3 animate-spin rounded-full border border-zinc-400 border-t-transparent dark:border-zinc-500" />
                                        )}
                                    </span>
                                )],
                                ['Created', formatDateTime(enrollment.created_at, timezone)],
                                ['Submitted', formatDateTime(liveSubmittedAt, timezone)],
                                ...(liveTrackingId
                                    ? [['Tracking ID', <span key="tracking" className="font-mono text-xs">{liveTrackingId}</span>]]
                                    : []),
                                ['Enrollment Request', (
                                    <Link
                                        href={enrollmentRequestsIndex.url({ query: { id: enrollment.enrollment_request_id } })}
                                        className="font-mono text-xs text-blue-600 hover:underline dark:text-blue-400"
                                        onClick={(e) => e.stopPropagation()}
                                    >
                                        #{enrollment.enrollment_request_id}
                                    </Link>
                                )],
                            ].map(([label, value]) => (
                                <div key={String(label)} className="grid grid-cols-[160px_1fr] gap-2 py-2 text-sm">
                                    <dt className="font-medium text-zinc-500 dark:text-zinc-400">{label}</dt>
                                    <dd className="text-zinc-900 dark:text-zinc-100">{value}</dd>
                                </div>
                            ))}
                        </dl>

                        {liveStatus !== 'submitted' && liveStatus !== 'confirmed' && (
                            <Form method="post" action={submitRoute.url(enrollment.id)}>
                                {({ processing, errors }) => (
                                    <>
                                        <button
                                            type="submit"
                                            disabled={processing}
                                            className="shrink-0 rounded-md bg-blue-600 px-3 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-60 dark:bg-blue-500 dark:hover:bg-blue-600"
                                        >
                                            {processing ? 'Submitting…' : 'Submit to supplier'}
                                        </button>
                                        {errors.submit && (
                                            <p className="mt-1 text-right text-xs text-red-600 dark:text-red-400">{errors.submit}</p>
                                        )}
                                    </>
                                )}
                            </Form>
                        )}
                    </div>

                    {liveErrorMessage && (
                        <div className="rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-800 dark:border-red-900 dark:bg-red-950 dark:text-red-300">
                            {liveErrorMessage}
                        </div>
                    )}

                    <div className="flex gap-1 border-b border-zinc-200 pb-2 dark:border-zinc-800">
                        <button type="button" className={tabClass('fields')} onClick={() => setActiveTab('fields')}>
                            Fields
                        </button>
                        <button type="button" className={tabClass('logs')} onClick={() => setActiveTab('logs')}>
                            Logs
                        </button>
                    </div>

                    {activeTab === 'fields' && (
                        <form onSubmit={handleSubmit}>
                            <div className="divide-y divide-zinc-100 dark:divide-zinc-800">
                                {enrollment.fields.map((field, idx) => (
                                    <div
                                        key={field.id}
                                        className="grid grid-cols-[160px_1fr] gap-2 py-2 text-sm"
                                    >
                                        <dt className="flex items-center truncate font-medium text-zinc-500 dark:text-zinc-400">
                                            {field.supplier_field_name}
                                        </dt>
                                        <dd>
                                            {isEditable ? (
                                                <input
                                                    value={form.data.fields[idx].value}
                                                    onChange={(e) => {
                                                        const updated = [...form.data.fields];
                                                        updated[idx] = { ...updated[idx], value: e.target.value };
                                                        form.setData('fields', updated);
                                                    }}
                                                    className="w-full rounded-md border border-zinc-200 bg-white px-2 py-1 text-sm dark:border-zinc-800 dark:bg-zinc-950"
                                                />
                                            ) : (
                                                <span className="text-zinc-900 dark:text-zinc-100">
                                                    {field.value ?? <span className="text-zinc-400">—</span>}
                                                </span>
                                            )}
                                        </dd>
                                    </div>
                                ))}
                            </div>

                            {isEditable && enrollment.fields.length > 0 && (
                                <div className="flex items-center gap-3 pt-4">
                                    <button
                                        type="submit"
                                        disabled={form.processing}
                                        className="rounded-md bg-zinc-900 px-3 py-2 text-sm font-medium text-white disabled:opacity-60 dark:bg-zinc-100 dark:text-zinc-900"
                                    >
                                        Save fields
                                    </button>
                                    <button
                                        type="button"
                                        onClick={() => onOpenChange(false)}
                                        className="text-sm text-zinc-600 hover:underline dark:text-zinc-400"
                                    >
                                        Cancel
                                    </button>
                                </div>
                            )}
                        </form>
                    )}

                    {activeTab === 'logs' && <LogsTab key={logsKey} enrollmentId={enrollment.id} />}
                </div>
            </DialogContent>
        </Dialog>
    );
}

function ArchiveConfirmDialog({
    open,
    onOpenChange,
    onConfirm,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    onConfirm: () => void;
}) {
    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-sm">
                <DialogHeader>
                    <DialogTitle>Archive supplier enrollment?</DialogTitle>
                </DialogHeader>
                <p className="text-sm text-zinc-600 dark:text-zinc-400">
                    This record will be soft-deleted and hidden from the default view. You can view archived records using the "Show archived" toggle.
                </p>
                <div className="flex justify-end gap-2 pt-2">
                    <button
                        type="button"
                        onClick={() => onOpenChange(false)}
                        className="rounded-md px-3 py-2 text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                    >
                        Cancel
                    </button>
                    <button
                        type="button"
                        onClick={onConfirm}
                        className="rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-white hover:bg-red-700 dark:bg-red-700 dark:hover:bg-red-600"
                    >
                        Archive
                    </button>
                </div>
            </DialogContent>
        </Dialog>
    );
}

function BulkArchiveConfirmDialog({
    open,
    onOpenChange,
    onConfirm,
    count,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    onConfirm: () => void;
    count: number;
}) {
    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-sm">
                <DialogHeader>
                    <DialogTitle>Archive {count} supplier {count === 1 ? 'enrollment' : 'enrollments'}?</DialogTitle>
                </DialogHeader>
                <p className="text-sm text-zinc-600 dark:text-zinc-400">
                    These records will be soft-deleted and hidden from the default view. You can view archived records using the "Show archived" toggle.
                </p>
                <div className="flex justify-end gap-2 pt-2">
                    <button
                        type="button"
                        onClick={() => onOpenChange(false)}
                        className="rounded-md px-3 py-2 text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                    >
                        Cancel
                    </button>
                    <button
                        type="button"
                        onClick={onConfirm}
                        className="rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-white hover:bg-red-700 dark:bg-red-700 dark:hover:bg-red-600"
                    >
                        Archive
                    </button>
                </div>
            </DialogContent>
        </Dialog>
    );
}

const selectClasses =
    'rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm shadow-sm dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-100';

function customerName(enrollment: SupplierEnrollment): string {
    const body = enrollment.enrollment_request?.body;
    if (!body) return '—';
    const first = body.first_name as string | undefined;
    const last = body.last_name as string | undefined;
    return [first, last].filter(Boolean).join(' ') || '—';
}

const breadcrumbs = [{ title: 'Supplier Enrollments', href: index.url() }];

export default function SupplierEnrollments({ enrollments, filters, suppliers }: Props) {
    const timezone = useUserTimezone();
    const [selected, setSelected] = useState<SupplierEnrollment | null>(null);
    const [archiveTarget, setArchiveTarget] = useState<SupplierEnrollment | null>(null);
    const [selectedIds, setSelectedIds] = useState<number[]>([]);
    const [bulkArchiveOpen, setBulkArchiveOpen] = useState(false);

    const sortColumn = filters.sort_by || 'created_at';
    const sortDirection = (filters.sort_direction || 'desc') as 'asc' | 'desc';
    const showTrashed = filters.trashed === '1';

    function toggleSort(column: string) {
        if (column === sortColumn) {
            applyFilters({ sort_by: column, sort_direction: sortDirection === 'asc' ? 'desc' : 'asc' });
        } else {
            applyFilters({ sort_by: column, sort_direction: 'asc' });
        }
    }

    function applyFilters(overrides: Partial<Filters> = {}) {
        const merged = { ...filters, ...overrides };

        const params = new URLSearchParams(
            Object.entries(merged).filter(([, v]) => v !== '') as [string, string][],
        );
        window.location.href = index.url() + (params.toString() ? '?' + params.toString() : '');
    }

    function confirmArchive() {
        if (!archiveTarget) return;
        router.delete(archive.url(archiveTarget.id), {
            preserveScroll: true,
            onFinish: () => setArchiveTarget(null),
        });
    }

    const archivableIds = enrollments.data.filter((e) => !e.deleted_at).map((e) => e.id);
    const allSelected = archivableIds.length > 0 && archivableIds.every((id) => selectedIds.includes(id));

    function toggleSelectAll() {
        setSelectedIds(allSelected ? [] : archivableIds);
    }

    function toggleSelected(id: number) {
        setSelectedIds((prev) => (prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]));
    }

    function confirmBulkArchive() {
        router.delete(bulkArchive.url(), {
            data: { ids: selectedIds },
            preserveScroll: true,
            onFinish: () => {
                setBulkArchiveOpen(false);
                setSelectedIds([]);
            },
        });
    }

    const hasActiveFilters = filters.search || filters.supplier_id || filters.status || filters.trashed;

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Supplier Enrollments" />

            <h1 className="sr-only">Supplier Enrollments</h1>

            <div className="space-y-6">
                <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
                    <HeadingSmall
                        title="Supplier Enrollments"
                        description="View and manage supplier enrollment submissions"
                    />

                    <div className="flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end">
                        <div className="flex flex-col gap-1">
                            <label className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
                                Search
                            </label>
                            <input
                                type="search"
                                value={filters.search}
                                onChange={(e) => applyFilters({ search: e.target.value })}
                                placeholder="Customer name or tracking ID…"
                                className="rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm shadow-sm dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-100"
                            />
                        </div>

                        <div className="flex flex-col gap-1">
                            <label className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
                                Supplier
                            </label>
                            <select
                                value={filters.supplier_id}
                                onChange={(e) => applyFilters({ supplier_id: e.target.value })}
                                className={selectClasses}
                            >
                                <option value="">All suppliers</option>
                                {suppliers.map((s) => (
                                    <option key={s.id} value={s.id}>
                                        {s.name}
                                    </option>
                                ))}
                            </select>
                        </div>

                        <div className="flex flex-col gap-1">
                            <label className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
                                Status
                            </label>
                            <select
                                value={filters.status}
                                onChange={(e) => applyFilters({ status: e.target.value })}
                                className={selectClasses}
                            >
                                <option value="">All</option>
                                <option value="pending">Pending</option>
                                <option value="submitted">Submitted</option>
                                <option value="confirmed">Confirmed</option>
                                <option value="rejected">Rejected</option>
                                <option value="error">Error</option>
                            </select>
                        </div>

                        <label className="flex cursor-pointer items-center gap-2 self-end pb-2">
                            <input
                                type="checkbox"
                                checked={showTrashed}
                                onChange={(e) => applyFilters({ trashed: e.target.checked ? '1' : '' })}
                                className="size-4 rounded border-zinc-300 dark:border-zinc-700"
                            />
                            <span className="text-sm text-zinc-700 dark:text-zinc-300">Show archived</span>
                        </label>

                        {hasActiveFilters && (
                            <button
                                type="button"
                                onClick={() => applyFilters({ search: '', supplier_id: '', status: '', trashed: '' })}
                                className="rounded-md px-3 py-2 text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                            >
                                Clear
                            </button>
                        )}
                    </div>
                </div>

                {selectedIds.length > 0 && (
                    <div className="flex items-center justify-between rounded-md border border-zinc-200 bg-zinc-50 px-4 py-2.5 dark:border-zinc-800 dark:bg-zinc-900">
                        <span className="text-sm text-zinc-700 dark:text-zinc-300">
                            {selectedIds.length} selected
                        </span>
                        <div className="flex items-center gap-3">
                            <button
                                type="button"
                                onClick={() => setSelectedIds([])}
                                className="text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                            >
                                Clear selection
                            </button>
                            <button
                                type="button"
                                onClick={() => setBulkArchiveOpen(true)}
                                className="rounded-md border border-red-200 bg-white px-3 py-1.5 text-sm font-medium text-red-600 hover:bg-red-50 dark:border-red-800 dark:bg-zinc-900 dark:text-red-400 dark:hover:bg-red-950"
                            >
                                Archive selected
                            </button>
                        </div>
                    </div>
                )}

                <div className="overflow-hidden rounded-md border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950">
                    <div className="overflow-x-auto">
                        <table className="w-full text-left text-sm">
                            <thead className="border-b border-zinc-200 text-xs uppercase text-zinc-600 dark:border-zinc-800 dark:text-zinc-400">
                                <tr>
                                    <th className="w-10 px-4 py-3">
                                        <input
                                            type="checkbox"
                                            checked={allSelected}
                                            onChange={toggleSelectAll}
                                            disabled={archivableIds.length === 0}
                                            className="size-4 rounded border-zinc-300 dark:border-zinc-700"
                                            aria-label="Select all"
                                        />
                                    </th>
                                    <SortableHeader label="ID" column="id" sortColumn={sortColumn} sortDirection={sortDirection} onSort={toggleSort} />
                                    <th className="px-4 py-3">Request</th>
                                    <th className="px-4 py-3">Customer</th>
                                    <th className="px-4 py-3">Supplier</th>
                                    <th className="px-4 py-3">Product</th>
                                    <th className="px-4 py-3">Tracking ID</th>
                                    <SortableHeader label="Status" column="status" sortColumn={sortColumn} sortDirection={sortDirection} onSort={toggleSort} />
                                    <SortableHeader label="Created" column="created_at" sortColumn={sortColumn} sortDirection={sortDirection} onSort={toggleSort} />
                                    <th className="px-4 py-3" />
                                </tr>
                            </thead>
                            <tbody className="divide-y divide-zinc-200 dark:divide-zinc-800">
                                {enrollments.data.map((e) => (
                                    <tr
                                        key={e.id}
                                        onClick={() => setSelected(e)}
                                        className={`cursor-pointer hover:bg-zinc-50 dark:hover:bg-zinc-900 ${e.deleted_at ? 'opacity-60' : ''}`}
                                    >
                                        <td className="px-4 py-3" onClick={(ev) => ev.stopPropagation()}>
                                            {!e.deleted_at && (
                                                <input
                                                    type="checkbox"
                                                    checked={selectedIds.includes(e.id)}
                                                    onChange={() => toggleSelected(e.id)}
                                                    className="size-4 rounded border-zinc-300 dark:border-zinc-700"
                                                    aria-label={`Select supplier enrollment ${e.id}`}
                                                />
                                            )}
                                        </td>
                                        <td className="px-4 py-3 font-medium">{e.id}</td>
                                        <td className="px-4 py-3" onClick={(ev) => ev.stopPropagation()}>
                                            <Link
                                                href={enrollmentRequestsIndex.url({ query: { id: e.enrollment_request_id } })}
                                                className="font-mono text-xs text-blue-600 hover:underline dark:text-blue-400"
                                            >
                                                #{e.enrollment_request_id}
                                            </Link>
                                        </td>
                                        <td className="px-4 py-3">{customerName(e)}</td>
                                        <td className="px-4 py-3">{e.supplier?.name ?? '—'}</td>
                                        <td className="px-4 py-3">{e.product ? productProperName(e.product.name) : '—'}</td>
                                        <td className="px-4 py-3 font-mono text-xs">{e.supplier_tracking_id ?? '—'}</td>
                                        <td className="px-4 py-3">
                                            <StatusBadge status={e.status} />
                                        </td>
                                        <td className="px-4 py-3">{formatDateTime(e.created_at, timezone)}</td>
                                        <td className="px-4 py-3 text-right" onClick={(ev) => ev.stopPropagation()}>
                                            {!e.deleted_at ? (
                                                <button
                                                    type="button"
                                                    onClick={(ev) => {
                                                        ev.stopPropagation();
                                                        setArchiveTarget(e);
                                                    }}
                                                    className="rounded-md border border-red-200 bg-white px-2.5 py-1 text-xs font-medium text-red-600 hover:bg-red-50 dark:border-red-800 dark:bg-zinc-900 dark:text-red-400 dark:hover:bg-red-950"
                                                >
                                                    Archive
                                                </button>
                                            ) : (
                                                <span className="text-xs text-zinc-400 italic">Archived</span>
                                            )}
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>

                    {enrollments.data.length === 0 && (
                        <div className="p-4 text-sm text-zinc-600 dark:text-zinc-400">
                            No supplier enrollments yet.
                        </div>
                    )}
                </div>

                {enrollments.last_page > 1 && (
                    <div className="flex items-center justify-between text-sm">
                        <span className="text-zinc-500 dark:text-zinc-400">
                            Showing{' '}
                            {(enrollments.current_page - 1) * enrollments.per_page + 1}–
                            {Math.min(enrollments.current_page * enrollments.per_page, enrollments.total)}{' '}
                            of {enrollments.total}
                        </span>
                        <div className="flex gap-1">
                            {enrollments.links.map((link) => (
                                <Link
                                    key={link.label}
                                    href={link.url ?? '#'}
                                    preserveState
                                    className={`rounded-md px-3 py-1.5 text-xs ${
                                        link.active
                                            ? 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
                                            : link.url
                                              ? 'text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800'
                                              : 'pointer-events-none text-zinc-300 dark:text-zinc-700'
                                    }`}
                                    dangerouslySetInnerHTML={{ __html: link.label }}
                                />
                            ))}
                        </div>
                    </div>
                )}
            </div>

            <EnrollmentModal
                key={selected?.id ?? 'none'}
                enrollment={selected}
                open={selected !== null}
                onOpenChange={(open) => !open && setSelected(null)}
            />
            <ArchiveConfirmDialog
                open={archiveTarget !== null}
                onOpenChange={(open) => { if (!open) setArchiveTarget(null); }}
                onConfirm={confirmArchive}
            />
            <BulkArchiveConfirmDialog
                open={bulkArchiveOpen}
                onOpenChange={setBulkArchiveOpen}
                onConfirm={confirmBulkArchive}
                count={selectedIds.length}
            />
        </AppLayout>
    );
}
