import { ActivityLogSidebar } from '@/components/activity-log/ActivityLogSidebar';
import { useModelActivityLog } from '@/components/activity-log/useModelActivityLog';
import { DataTable } from '@/components/datatable';
import { FilterConfig } from '@/components/datatable-toolbar';
import { CsvImportModal } from '@/components/modals/csv-import-modal';
import { importTableColumns } from '@/components/tableColumns/ImportTableColumns';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { useModal } from '@/components/ui/modal';
import { fetchDatatable } from '@/lib/datatable-fetch';
import { type PaginatedData } from '@/types';
import { Head, router } from '@inertiajs/react';
import axios from 'axios';
import { Activity, ArrowRight, BarChart2, Database, Download, FileSpreadsheet, Info, RefreshCw, Timer } from 'lucide-react';
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { toast } from 'sonner';

// Mirrors backend ImportResource
export type ImportItem = {
    id: number;
    model_type: string;
    file_path: string;
    status: string;
    progress: number | null;
    total_records: number | null;
    success_count: number | null;
    failure_count: number | null;
    error_log: any[] | null;
    created_by: number | null;
    creator_name?: string | null;
    creator_email?: string | null;
    started_at: string | null;
    completed_at: string | null;
};

interface SummaryCard {
    title: string;
    value: number | string;
    description: string;
    metrics?: Record<string, number | string>;
}

type ImportListProps = {
    importData?: PaginatedData<ImportItem>;
    importSummary?: SummaryCard[];
    modelType?: string;
};

export default function ImportList({ importData, importSummary = [], modelType }: ImportListProps) {
    // Detect model type from URL if not explicitly provided
    const detectedModelType = modelType || (window.location.pathname.includes('/contacts/import') ? 'Contact' : 'User');
    const [selectedImports, setSelectedImports] = useState<ImportItem[]>([]);
    const modelTypeParam = useMemo(() => ({ model_type: detectedModelType }), [detectedModelType]);
    const { isOpen: isCsvModalOpen, openModal: openCsvModal, closeModal: closeCsvModal } = useModal();
    const [liveSummary, setLiveSummary] = useState(importSummary);
    const [polling, setPolling] = useState(false);
    const [sseState, setSseState] = useState<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected');
    const activityLogCtl = useModelActivityLog();
    const isInitialMounted = useRef(false);
    const lastRealUpdateRef = useRef<Record<number, number>>({}); // timestamp of last server progress for each import
    const optimisticTimersRef = useRef<Record<number, any>>({});
    const prevStatusRef = useRef<Record<number, { status: string | number | null; progress: number | null }>>({});

    // Fallback placeholder when no data passed yet
    const fallbackPaginated: PaginatedData<ImportItem> = {
        data: [],
        queryParams: {} as any,
        meta: { from: 0, to: 0, total: 0, current_page: 1, last_page: 1 } as any,
        links: { prev: null, next: null } as any,
        userSummary: [],
    };
    const [clientData, setClientData] = useState<PaginatedData<ImportItem>>(importData ?? fallbackPaginated);
    const paginated = clientData;
    // Local mutable copy of imports so we can update progress without full page reload
    const [imports, setImports] = useState<ImportItem[]>(paginated.data);
    const debugMode = typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('import_debug');

    // Keep local list in sync if server re-sends a different dataset (pagination / filter change)
    useEffect(() => {
        setImports(paginated.data);
    }, [paginated.data]);

    // When a Contact import transitions to completed, set a cross-page flag and dispatch a global event
    useEffect(() => {
        const prev = prevStatusRef.current;
        let fired = false;
        imports.forEach((imp) => {
            const prevEntry = prev[imp.id];
            const prevStatus = prevEntry?.status ?? null;
            const prevProgress = prevEntry?.progress ?? null;
            const currStatus =
                (imp as any).status_label ||
                (typeof imp.status === 'number'
                    ? (
                          {
                              2: 'pending',
                              10: 'processing',
                              5: 'completed',
                              7: 'failed',
                          } as Record<number, string>
                      )[imp.status] || String(imp.status)
                    : String(imp.status));
            const transitionedToCompleted = prevStatus !== 'completed' && currStatus?.toLowerCase() === 'completed';
            const reached100 = (prevProgress ?? 0) < 100 && (imp.progress ?? 0) >= 100;
            if (imp.model_type === 'Contact' && (transitionedToCompleted || reached100) && !fired) {
                try {
                    localStorage.setItem('contacts:needs-refresh', '1');
                    window.dispatchEvent(new CustomEvent('contacts:refresh', { detail: { action: 'import-completed' } }));
                } catch {}
                fired = true;
            }
            // store current snapshot
            prev[imp.id] = { status: currStatus, progress: imp.progress ?? null };
        });
    }, [imports]);

    // Derived flag to know if any import is active (processing or pending)
    const hasActiveImports = useMemo(() => imports.some((i) => i.status === 'processing' || i.status === 'pending'), [imports]);

    // Track the most recent import (by highest id) and whether it needs auto-reload
    const latestImport = useMemo(() => {
        if (!imports.length) return null as ImportItem | null;
        return imports.reduce((acc, cur) => (acc === null || cur.id > acc.id ? cur : acc), null as ImportItem | null);
    }, [imports]);
    const shouldAutoReloadLatest = useMemo(() => {
        if (!latestImport) return false;
        const pct = latestImport.progress ?? 0;
        const active = latestImport.status === 'processing' || latestImport.status === 'pending';
        return active && pct < 100;
    }, [latestImport]);

    // Simple periodic table reload every 3s while the latest import hasn't reached 100%
    useEffect(() => {
        if (!shouldAutoReloadLatest) return;
        let inflight = false;
        const tick = async () => {
            if (inflight) return;
            inflight = true;
            try {
                const params = { ...(paginated.queryParams || ({} as any)), ...modelTypeParam } as any;
                const url = route('imports.data');
                const json = await fetchDatatable<ImportItem>(url, params);
                setClientData({
                    data: json.data,
                    meta: json.meta,
                    queryParams: params,
                    links: {
                        prev: json.meta.current_page > 1 ? '' : null,
                        next: json.meta.current_page < json.meta.last_page ? '' : null,
                    },
                } as any);
                setImports(json.data);
                if ((json as any).importSummary) {
                    setLiveSummary((json as any).importSummary);
                }
            } catch (_) {
                // ignore transient errors
            } finally {
                inflight = false;
            }
        };
        const id = setInterval(tick, 3000);
        // initial kick so user sees progress quickly
        tick();
        return () => clearInterval(id);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [shouldAutoReloadLatest, paginated.queryParams]);

    // Realtime progress via SSE (fallback to polling if not supported or fails)
    useEffect(() => {
        let interval: any = null;
        let es: EventSource | null = null;
        const startPolling = () => {
            setPolling(true);
            interval = setInterval(async () => {
                try {
                    const activeIds = imports.filter((i) => i.status === 'processing' || i.status === 'pending').map((i) => i.id);
                    if (activeIds.length === 0) {
                        return;
                    }
                    const results = await Promise.allSettled(activeIds.map((id) => axios.get(route('imports.status', id))));
                    const updated: Record<number, ImportItem> = {};
                    results.forEach((res) => {
                        if (res.status === 'fulfilled') {
                            const imp: ImportItem = res.value.data.import;
                            updated[imp.id] = imp;
                        }
                    });
                    if (Object.keys(updated).length) {
                        setImports((prev) => prev.map((imp) => (updated[imp.id] ? { ...imp, ...updated[imp.id] } : imp)));
                    }
                    axios.get(route('imports.summary'), { params: modelTypeParam }).then((r) => setLiveSummary(r.data.data));
                } catch (_) {}
            }, 5000);
        };

        const stopPolling = () => {
            if (interval) clearInterval(interval);
            setPolling(false);
        };

        const startSSE = () => {
            if (!hasActiveImports) return; // nothing to watch
            try {
                setSseState('connecting');
                es = new EventSource(route('imports.stream'));
                setPolling(true); // reuse badge
                es.onopen = () => setSseState('connected');
                es.addEventListener('import-progress', (e: MessageEvent) => {
                    try {
                        const data = JSON.parse(e.data);
                        lastRealUpdateRef.current[data.id] = Date.now();
                        setImports((prev) =>
                            prev.map((imp) =>
                                imp.id === data.id
                                    ? {
                                          ...imp,
                                          ...data,
                                          status: (data.status_label || data.status || imp.status).toLowerCase(),
                                      }
                                    : imp,
                            ),
                        );
                    } catch (_) {}
                });
                es.addEventListener('import-progress-batch', (e: MessageEvent) => {
                    try {
                        const batch = JSON.parse(e.data);
                        const now = Date.now();
                        if (debugMode) console.log('[SSE] batch received', batch);
                        setImports((prev) =>
                            prev.map((p) => {
                                const updated = batch.find((b: any) => b.id === p.id);
                                if (!updated) return p;
                                lastRealUpdateRef.current[updated.id] = now;
                                return {
                                    ...p,
                                    ...updated,
                                    status: (updated.status_label || updated.status || p.status).toLowerCase(),
                                };
                            }),
                        );
                    } catch (_) {}
                });
                es.addEventListener('heartbeat', () => {
                    if (sseState !== 'connected') setSseState('connected');
                });
                es.addEventListener('import-idle', () => {
                    // refresh summary final state then close
                    axios.get(route('imports.summary'), { params: modelTypeParam }).then((r) => setLiveSummary(r.data.data));
                    es?.close();
                    setTimeout(() => setPolling(false), 500);
                    setSseState('disconnected');
                });
                es.addEventListener('stream-end', () => {
                    // gracefully end; client may reconnect if still active
                    es?.close();
                    setPolling(false);
                    setSseState('disconnected');
                });
                es.onerror = () => {
                    setSseState('error');
                    es?.close();
                    // fallback to polling & schedule reconnect attempt
                    startPolling();
                    setTimeout(() => {
                        if (hasActiveImports) startSSE();
                    }, 7000);
                };
            } catch (_) {
                setSseState('error');
                startPolling();
            }
        };

        // Decide strategy
        if (hasActiveImports) {
            startSSE();
        } else {
            // ensure final summary if we just ended
            if (polling && isInitialMounted.current) {
                axios
                    .get(route('imports.summary'), { params: modelTypeParam })
                    .then((r) => setLiveSummary(r.data.data))
                    .finally(() => setPolling(false));
            } else {
                setPolling(false);
            }
        }
        isInitialMounted.current = true;

        return () => {
            stopPolling();
            if (es) es.close();
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [hasActiveImports]);

    // Fallback per-row lightweight polling when SSE is unavailable or stale
    useEffect(() => {
        if (!hasActiveImports) return;
        const tick = setInterval(async () => {
            const now = Date.now();
            const candidates = imports.filter((i) => {
                const active = i.status === 'processing' || i.status === 'pending';
                if (!active) return false;
                const lastTs = lastRealUpdateRef.current[i.id] || 0;
                const stale = now - lastTs > 6000; // no real updates in >6s
                const sseDown = sseState !== 'connected';
                return sseDown || stale;
            });
            if (!candidates.length) return;
            try {
                const results = await Promise.allSettled(candidates.map((c) => axios.get(route('imports.status', c.id))));
                const updated: Record<number, ImportItem> = {};
                results.forEach((r) => {
                    if (r.status === 'fulfilled') {
                        const imp: ImportItem = r.value.data.import;
                        updated[imp.id] = imp;
                        lastRealUpdateRef.current[imp.id] = Date.now();
                    }
                });
                if (Object.keys(updated).length) {
                    setImports((prev) => prev.map((p) => (updated[p.id] ? { ...p, ...updated[p.id] } : p)));
                }
            } catch (_) {}
        }, 4000);
        return () => clearInterval(tick);
    }, [imports, hasActiveImports, sseState]);

    // Optimistic progress animation if no real updates for >6s (improves perceived feedback)
    useEffect(() => {
        const now = Date.now();
        imports.forEach((imp) => {
            const active = imp.status === 'processing' || imp.status === 'pending';
            const lastTs = lastRealUpdateRef.current[imp.id] || 0;
            const stale = now - lastTs > 6000;

            // Clear any timer when finished or when real updates resume
            if (!active || !stale) {
                if (optimisticTimersRef.current[imp.id]) {
                    clearInterval(optimisticTimersRef.current[imp.id]);
                    delete optimisticTimersRef.current[imp.id];
                }
            }

            // Start optimistic timer when active and stale and no existing timer
            if (active && stale && !optimisticTimersRef.current[imp.id]) {
                optimisticTimersRef.current[imp.id] = setInterval(() => {
                    setImports((prev) =>
                        prev.map((p) => {
                            if (p.id !== imp.id) return p;
                            const current = p.progress ?? 0;
                            // Cap optimistic progress so real updates can overtake
                            if (current >= 75) return p;
                            return { ...p, progress: current + 1 };
                        }),
                    );
                }, 1000);
            }
        });
        return () => {
            // timers are cleared per-import above when finishing or resuming real updates
        };
    }, [imports, sseState]);

    // Reintroduced: status filter only
    const filters: FilterConfig[] = [
        {
            type: 'dropdown',
            label: 'Status',
            name: 'status',
            value: paginated.queryParams?.status || '',
            options: [
                { label: 'Pending', value: 'pending' },
                { label: 'Processing', value: 'processing' },
                { label: 'Completed', value: 'completed' },
                { label: 'Failed', value: 'failed' },
            ],
        },
    ];

    const bulkActions = [
        {
            label: 'Retry Failed',
            icon: RefreshCw,
            confirm: false,
            onClick: (items: ImportItem[]) => {
                items.forEach((imp) => {
                    if (imp.failure_count && imp.failure_count > 0) {
                        router.post(
                            route('imports.retry', imp.id),
                            {},
                            {
                                onSuccess: () => toast.success(`Retry started for #${imp.id}`),
                            },
                        );
                    }
                });
            },
        },
        {
            label: 'Export Errors',
            icon: Download,
            confirm: false,
            onClick: (items: ImportItem[]) => {
                items.forEach((imp) => {
                    if (imp.failure_count && imp.failure_count > 0) {
                        window.open(route('imports.export-errors', imp.id), '_blank');
                    }
                });
            },
        },
    ];

    return (
        <>
            <Head title="Imports" />
            <div className="flex h-full flex-1 flex-col gap-4 overflow-x-auto rounded-xl p-2">
                <div className="mb-6 flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center">
                    <div className="grid grid-cols-1 gap-1">
                        <h2 className="text-xl font-bold sm:text-2xl">Imports</h2>
                        <div className="flex items-center text-sm text-gray-500">
                            <span>Data</span>
                            <span className="mx-2">›</span>
                            <span>Imports</span>
                            {hasActiveImports && (
                                <span className="ml-3 flex items-center gap-1 text-[10px] font-medium">
                                    <span
                                        className={`h-2 w-2 rounded-full ${sseState === 'connected' ? 'animate-pulse bg-green-500' : sseState === 'connecting' ? 'animate-ping bg-amber-500' : sseState === 'error' ? 'bg-red-500' : 'bg-gray-400'}`}
                                    ></span>
                                    <span className="tracking-wide text-gray-500 uppercase">{sseState}</span>
                                </span>
                            )}
                        </div>
                    </div>
                    <div className="flex flex-wrap gap-2">
                        <Button variant="outline" size="sm" onClick={() => activityLogCtl.show({ modelClass: 'Import', title: 'Import Activity' })}>
                            <Activity className="mr-2 h-4 w-4" /> Activity
                        </Button>
                    </div>
                </div>
                {/* Summary Cards */}
                <SummaryCards summary={liveSummary} polling={polling} />
                {/* Quick Import Card */}
                <QuickImportCard onImportClick={openCsvModal} modelType={detectedModelType as 'User' | 'Contact'} />
                <div className="w-96 sm:w-full">
                    <DataTable
                        columns={importTableColumns()}
                        data={imports}
                        paginatedData={paginated}
                        bulkActions={bulkActions}
                        tableKey="import-table"
                        filters={filters}
                        enableRowClick={false}
                        showToolbar={true}
                        onNavigate={async (params) => {
                            const url = route('imports.data');
                            const json = await fetchDatatable<ImportItem>(url, { ...params, ...modelTypeParam } as any);
                            setClientData({
                                data: json.data,
                                meta: json.meta,
                                queryParams: params,
                                links: {
                                    prev: json.meta.current_page > 1 ? '' : null,
                                    next: json.meta.current_page < json.meta.last_page ? '' : null,
                                },
                            } as any);
                            if ((json as any).importSummary) {
                                setLiveSummary((json as any).importSummary);
                            }
                        }}
                    />
                </div>
            </div>
            <CsvImportModal
                isOpen={isCsvModalOpen}
                onClose={closeCsvModal}
                title={detectedModelType === 'Contact' ? 'Import Contacts from CSV' : 'Import Users from CSV'}
                fields={
                    detectedModelType === 'Contact'
                        ? [
                              { key: 'name', label: 'Name' },
                              { key: 'email', label: 'Email' },
                              { key: 'phone', label: 'Phone Number' },
                              { key: 'notes', label: 'Notes' },
                          ]
                        : [
                              { key: 'first_name', label: 'First Name' },
                              { key: 'last_name', label: 'Last Name' },
                              { key: 'phone', label: 'Phone Number' },
                              { key: 'email', label: 'Email' },
                              { key: 'role', label: 'Role' },
                          ]
                }
                postRouteName={detectedModelType === 'Contact' ? 'contacts.import' : 'users.import'}
                onImported={(imp) => {
                    const activeStatusFilter = (paginated.queryParams?.status ?? '').toString();
                    if (activeStatusFilter && activeStatusFilter !== '' && activeStatusFilter !== 'null') {
                        const mapped =
                            (imp as any).status_label ||
                            (typeof imp.status === 'number'
                                ? (
                                      {
                                          2: 'pending',
                                          10: 'processing',
                                          5: 'completed',
                                          7: 'failed',
                                      } as Record<number, string>
                                  )[imp.status] || ''
                                : String(imp.status));
                        if (mapped.toLowerCase() !== activeStatusFilter.toLowerCase()) {
                            return;
                        }
                    }
                    setImports((prev) => {
                        if (prev.some((p) => p.id === imp.id)) return prev;
                        return [imp as ImportItem, ...prev];
                    });
                    axios
                        .get(route('imports.summary'), { params: modelTypeParam })
                        .then((r) => setLiveSummary(r.data.data))
                        .catch(() => {});
                }}
            />
            <ActivityLogSidebar
                open={activityLogCtl.open}
                onOpenChange={activityLogCtl.setOpen}
                modelClass={activityLogCtl.modelClass}
                modelId={activityLogCtl.modelId}
                title={activityLogCtl.title}
            />
            {debugMode && (
                <div className="fixed right-2 bottom-2 z-50 max-h-[50vh] w-[360px] overflow-auto rounded border bg-card p-3 text-[11px] shadow-lg">
                    <div className="mb-1 flex items-center justify-between">
                        <strong className="font-semibold">Import Debug</strong>
                        <button
                            className="rounded bg-gray-100 px-2 py-0.5 text-[10px]"
                            onClick={() => {
                                console.log('[IMPORT DEBUG SNAPSHOT]', imports);
                            }}
                        >
                            Dump
                        </button>
                    </div>
                    <ul className="space-y-1">
                        {imports.slice(0, 15).map((i) => (
                            <li key={i.id} className="rounded border px-2 py-1">
                                <div className="flex justify-between">
                                    <span className="font-medium">#{i.id}</span>
                                    <span>{i.status}</span>
                                </div>
                                <div className="flex items-center gap-2">
                                    <div className="h-1 flex-1 overflow-hidden rounded bg-gray-200">
                                        <div className="h-full bg-brand-500" style={{ width: `${i.progress ?? 0}%` }} />
                                    </div>
                                    <span className="w-10 text-right tabular-nums">{i.progress ?? 0}%</span>
                                </div>
                                <div className="mt-1 flex flex-wrap gap-2 text-[9px] text-gray-500">
                                    <span>S:{i.success_count ?? 0}</span>
                                    <span>F:{i.failure_count ?? 0}</span>
                                    <span>T:{i.total_records ?? 0}</span>
                                </div>
                            </li>
                        ))}
                    </ul>
                </div>
            )}
        </>
    );
}

ImportList.layout = (page: ReactNode) => page;

// ICON / COLOR helpers
const summaryIcon = (title: string) => {
    const t = title.toLowerCase();
    if (t.includes('overview')) return BarChart2;
    if (t.includes('performance')) return Activity;
    if (t.includes('volume')) return Database;
    if (t.includes('time')) return Timer;
    return BarChart2;
};

interface SummaryCardsProps {
    summary: SummaryCard[];
    polling: boolean;
}

function SummaryCards({ summary, polling }: SummaryCardsProps) {
    if (!summary || summary.length === 0) {
        // skeleton
        return (
            <div className="mb-4 grid gap-4 bg-card sm:grid-cols-2 lg:grid-cols-4">
                {Array.from({ length: 4 }).map((_, i) => (
                    <Card key={i} className="animate-pulse border">
                        <CardHeader className="pb-2">
                            <div className="h-4 w-32 rounded bg-gray-200" />
                            <div className="mt-2 h-3 w-24 rounded bg-gray-100" />
                        </CardHeader>
                        <CardContent className="space-y-3 pt-0">
                            <div className="h-8 w-20 rounded bg-gray-200" />
                            <div className="grid grid-cols-2 gap-2">
                                {Array.from({ length: 4 }).map((__, j) => (
                                    <div key={j} className="h-6 rounded bg-gray-100" />
                                ))}
                            </div>
                        </CardContent>
                    </Card>
                ))}
            </div>
        );
    }
    return (
        <div className="mb-4 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
            {summary.map((card, idx) => {
                const Icon = summaryIcon(card.title);
                return (
                    <Card key={idx} className="relative overflow-hidden border">
                        <div className="absolute opacity-60" />
                        <CardHeader className="relative z-10 pb-2">
                            <div className="flex items-center justify-between">
                                <CardTitle className="flex items-center gap-2 text-sm font-medium">
                                    <Icon className="h-4 w-4 text-brand-600" />
                                    {card.title}
                                </CardTitle>
                                {polling && <span className="animate-pulse text-[10px] text-brand-600">live</span>}
                            </div>
                            <CardDescription className="text-xs text-muted-foreground">{card.description}</CardDescription>
                        </CardHeader>
                        <CardContent className="relative z-10 pt-0">
                            <div className="mb-3 text-3xl font-bold text-gray-900">{card.value}</div>
                            {card.metrics && (
                                <div className="grid grid-cols-2 gap-2 text-[11px]">
                                    {Object.entries(card.metrics).map(([k, v]) => (
                                        <div key={k} className="flex justify-between rounded bg-card px-2 py-1">
                                            <span className="text-gray-500 capitalize">{k.replace(/_/g, ' ')}</span>
                                            <span className="font-semibold text-gray-900">{v}</span>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </CardContent>
                    </Card>
                );
            })}
        </div>
    );
}

// Polling effect
// Poll summary (and optionally reload table) while there are processing imports
// Soft refresh every 15s
// placed after component to avoid redeclaration issues
// eslint-disable-next-line
(function attachPollingHook() {
    // we cannot hook inside component after export easily without rewriting; leaving util for clarity
})();

// Quick Import Card Component
interface QuickImportCardProps {
    onImportClick: () => void;
    modelType?: 'User' | 'Contact';
}

function QuickImportCard({ onImportClick, modelType = 'User' }: QuickImportCardProps) {
    const isContact = modelType === 'Contact';
    const SAMPLE_HEADERS = isContact ? ['name', 'email', 'phone', 'notes'] : ['first_name', 'last_name', 'phone', 'email', 'role'];
    const SAMPLE_ROWS = isContact
        ? [
              ['Acme Buyer', 'buyer@acme.test', '+15551234567', 'VIP lead'],
              ['Globex CTO', 'cto@globex.test', '+15557654321', 'Met at summit'],
          ]
        : [
              ['Jane', 'Doe', '+15551234567', 'jane@example.com', 'Admin'],
              ['John', 'Smith', '+15557654321', 'john@example.com', 'User'],
          ];

    const downloadSample = () => {
        const headerLine = SAMPLE_HEADERS.join(',');
        const rows = SAMPLE_ROWS.map((r) => r.join(',')).join('\n');
        const csv = headerLine + '\n' + rows + '\n';
        const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = isContact ? 'sample_contacts_import.csv' : 'sample_users_import.csv';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    };

    return (
        <Card className="relative mb-8 min-h-[270px] overflow-hidden border bg-card">
            {/* Decorative background */}

            <div className="pointer-events-none absolute -top-16 -right-16 h-56 w-56 rounded-full" />
            <CardHeader className="relative z-10 pb-4">
                <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
                    <div className="space-y-1.5">
                        <CardTitle className="flex items-center gap-2 text-lg font-semibold tracking-tight">
                            <FileSpreadsheet className="h-5 w-5 text-primary" /> Quick Import
                        </CardTitle>
                        <CardDescription className="text-xs leading-relaxed">
                            {isContact
                                ? 'Start a contact import in seconds. Use the sample template or drag a compatible CSV. Extra columns are ignored.'
                                : 'Start a user import in seconds. Use the sample template or drag a compatible CSV. Extra columns are ignored. The role column is optional.'}
                        </CardDescription>
                    </div>
                    <div className="hidden gap-2 sm:flex">
                        <Button variant="outline" size="sm" onClick={downloadSample} className="backdrop-blur supports-[backdrop-filter]:bg-card">
                            <Download className="mr-2 h-4 w-4" /> Sample CSV
                        </Button>
                        <Button size="sm" onClick={onImportClick} className="shadow-sm">
                            <FileSpreadsheet className="mr-2 h-4 w-4" /> Import File
                        </Button>
                    </div>
                </div>
            </CardHeader>
            <CardContent className="relative z-10 pt-0">
                <div className="grid gap-8 lg:grid-cols-12">
                    {/* Column chips + notes */}
                    <div className="flex flex-col gap-5 lg:col-span-5">
                        <div>
                            <p className="text-xs font-medium tracking-wide text-gray-500 uppercase">Template Columns</p>
                            <div className="flex flex-wrap gap-2">
                                {SAMPLE_HEADERS.map((h) => {
                                    const isRole = !isContact && h === 'role';
                                    return (
                                        <span
                                            key={h}
                                            className="group relative inline-flex items-center gap-1 overflow-hidden rounded-full bg-card px-3 py-1 text-xs font-medium text-gray-700 shadow-sm ring-1 ring-border"
                                        >
                                            <span className="relative z-10 capitalize">{h}</span>
                                            {isRole && (
                                                <span className="rounded-full bg-amber-100 px-2 py-0.5 text-[10px] font-medium text-amber-700 ring-1 ring-amber-200">
                                                    Optional
                                                </span>
                                            )}
                                            <span className="pointer-events-none absolute inset-0 bg-gradient-to-r from-primary/0 via-primary/20 to-primary/0 opacity-0 transition-opacity group-hover:opacity-100" />
                                        </span>
                                    );
                                })}
                            </div>
                        </div>
                        <div className="grid grid-cols-2 gap-4 text-[11px]">
                            <div className="rounded-md border border-border bg-card p-3 backdrop-blur-sm">
                                <p className="mb-1 font-semibold text-gray-700">Tips</p>
                                <ul className="list-disc space-y-1 pl-4 text-gray-500">
                                    <li>No headers → first row treated as data.</li>
                                    <li>Unknown columns are skipped.</li>
                                </ul>
                            </div>
                            <div className="rounded-md border border-border bg-card p-3 backdrop-blur-sm">
                                <p className="mb-1 font-semibold text-gray-700">Support</p>
                                <ul className="list-disc space-y-1 pl-4 text-gray-500">
                                    <li>UTF‑8 CSV only.</li>
                                    <li>Max 5MB file.</li>
                                </ul>
                            </div>
                        </div>
                        <div className="mt-1 flex gap-2 sm:hidden">
                            <Button variant="outline" size="sm" className="flex-1" onClick={downloadSample}>
                                <Download className="mr-2 h-4 w-4" /> Sample
                            </Button>
                            <Button size="sm" className="flex-1" onClick={onImportClick}>
                                <FileSpreadsheet className="mr-2 h-4 w-4" /> Import
                            </Button>
                        </div>
                    </div>
                    {/* Preview + meta */}
                    <div className="space-y-4 lg:col-span-7">
                        <div>
                            <div className="mb-2 flex items-center justify-between">
                                <p className="text-xs font-medium tracking-wide text-gray-500 uppercase">Sample Preview</p>
                                <span className="rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary ring-1 ring-primary/30">
                                    CSV
                                </span>
                            </div>
                            <div className="overflow-hidden rounded-lg border bg-card shadow-sm">
                                <table className="w-full border-collapse text-xs">
                                    <thead className="bg-card text-gray-500">
                                        <tr>
                                            {SAMPLE_HEADERS.map((h) => (
                                                <th key={h} className="px-3 py-2 text-left font-medium">
                                                    {h}
                                                </th>
                                            ))}
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {SAMPLE_ROWS.map((row, i) => (
                                            <tr key={i} className="even:bg-card">
                                                {row.map((cell, j) => (
                                                    <td key={j} className="px-3 py-2 font-mono text-[11px] text-gray-500">
                                                        {cell}
                                                    </td>
                                                ))}
                                            </tr>
                                        ))}
                                    </tbody>
                                </table>
                            </div>
                        </div>
                        <div className="flex flex-wrap items-center gap-3 text-[11px] text-gray-500">
                            <div className="flex items-center gap-1">
                                <ArrowRight className="h-3 w-3" /> Extra columns ignored automatically.
                            </div>
                            {!isContact ? (
                                <div className="flex items-center gap-1">
                                    <Info className="h-3 w-3" /> Roles should match allowed system roles.
                                </div>
                            ) : (
                                <div className="flex items-center gap-1">
                                    <Info className="h-3 w-3" /> Email is optional; duplicates by email are skipped.
                                </div>
                            )}
                        </div>
                    </div>
                </div>
            </CardContent>
        </Card>
    );
}
