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 { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
import { useModal } from '@/components/ui/modal';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
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, RefreshCw, Timer, Upload } from 'lucide-react';
// @ts-expect-error: papaparse lacks bundled types
import Papa from 'papaparse';
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { toast } from 'sonner';

const WC_REQUIRED_COLUMNS = ['ID', 'Type', 'Name', 'SKU'];
const WC_RECOMMENDED_COLUMNS = ['Published', 'Regular price', 'Stock', 'In stock?', 'Categories', 'Images', 'Brands'];

const WC_COLUMN_MAP: { systemField: string; wcColumn: string; required: boolean; note?: string }[] = [
    { systemField: 'Product Name',      wcColumn: 'Name',                      required: true  },
    { systemField: 'SKU',               wcColumn: 'SKU',                       required: true  },
    { systemField: 'Product Type',      wcColumn: 'Type',                      required: true  },
    { systemField: 'External ID',       wcColumn: 'ID',                        required: true  },
    { systemField: 'Status',            wcColumn: 'Published',                 required: false },
    { systemField: 'Retail Price',      wcColumn: 'Regular price',             required: false },
    { systemField: 'Sale Price',        wcColumn: 'Sale price',                required: false },
    { systemField: 'Sale Start Date',   wcColumn: 'Date sale price starts',    required: false },
    { systemField: 'Sale End Date',     wcColumn: 'Date sale price ends',      required: false },
    { systemField: 'Stock Quantity',    wcColumn: 'Stock',                     required: false },
    { systemField: 'Track Inventory',   wcColumn: 'In stock?',                 required: false },
    { systemField: 'Category',          wcColumn: 'Categories',                required: false },
    { systemField: 'Brand',             wcColumn: 'Brands',                    required: false },
    { systemField: 'Description',       wcColumn: 'Description',               required: false },
    { systemField: 'Short Description', wcColumn: 'Short description',         required: false },
    { systemField: 'Featured',          wcColumn: 'Is featured?',              required: false },
    { systemField: 'Weight',            wcColumn: 'Weight (g)',                required: false },
    { systemField: 'Length',            wcColumn: 'Length (cm)',               required: false },
    { systemField: 'Width',             wcColumn: 'Width (cm)',                required: false },
    { systemField: 'Height',            wcColumn: 'Height (cm)',               required: false },
    { systemField: 'Product Image',     wcColumn: 'Images',                    required: false },
    { systemField: 'Parent Product',    wcColumn: 'Parent',                    required: false, note: 'variations only' },
    { systemField: 'Specifications',    wcColumn: 'Attribute N name/value(s)', required: false, note: 'dynamic, up to 6 attrs' },
];

// 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 | string[];
    tableHeaders?: string[];
    tableRows?: string[][];
    csvModalContent?: { key: string; label: string }[];
    sampleCsvFilename?: string;
    importModalTitle?: string;
    importPostRoute?: string;
    postRouteParams?: Record<string, any>;
    pageTitle?: string;
    section?: string;
    woocommerceMode?: boolean;
    woocommercePostRoute?: string;
    woocommerceIndexHref?: string;
};

export default function ImportList({
    importData,
    importSummary = [],
    modelType,
    tableHeaders,
    tableRows,
    csvModalContent,
    sampleCsvFilename,
    importModalTitle = 'Import from CSV',
    importPostRoute = 'users.import',
    postRouteParams,
    pageTitle = 'Imports',
    section = 'Data',
    woocommerceMode = false,
    woocommercePostRoute,
    woocommerceIndexHref,
}: ImportListProps) {
    // Detect model type from URL if not explicitly provided
    const detectedModelType = modelType;
    const [selectedImports, setSelectedImports] = useState<ImportItem[]>([]);
    const modelTypeParam = useMemo(() => ({ model_type: detectedModelType }), [detectedModelType]);
    const { isOpen: isCsvModalOpen, openModal: openCsvModal, closeModal: closeCsvModal } = useModal();

    // Type-picker modal state (shown when woocommercePostRoute is set)
    const [pickerOpen, setPickerOpen] = useState(false);
    const [pickerType, setPickerType] = useState<'default' | 'woocommerce'>(woocommerceMode ? 'woocommerce' : 'default');
    const [wcImportMode, setWcImportMode] = useState<'upsert' | 'update' | 'skip'>('upsert');
    const [wcFile, setWcFile] = useState<File | null>(null);
    const [wcUploading, setWcUploading] = useState(false);
    const [wcStep, setWcStep] = useState<'upload' | 'mapping'>('upload');
    const [wcColumnCheck, setWcColumnCheck] = useState<{
        state: 'idle' | 'valid' | 'warn' | 'error';
        missingRequired: string[];
        missingOptional: string[];
    } | null>(null);

    const handleImportButtonClick = () => {
        if (woocommercePostRoute) {
            setPickerType(woocommerceMode ? 'woocommerce' : 'default');
            setWcFile(null);
            setWcImportMode('upsert');
            setWcStep('upload');
            setWcColumnCheck(null);
            setPickerOpen(true);
        } else {
            openCsvModal();
        }
    };

    const handlePickerContinue = () => {
        if (pickerType === 'default') {
            setPickerOpen(false);
            openCsvModal();
        }
        // WooCommerce stays in the modal — user uploads file there
    };

    const handleWcUpload = async () => {
        if (!wcFile || !woocommercePostRoute) return;
        setWcUploading(true);
        const formData = new FormData();
        formData.append('file', wcFile);
        formData.append('import_mode', wcImportMode);
        try {
            const url = route(woocommercePostRoute);
            await axios.post(url, formData);
            toast.success('WooCommerce import started', { description: 'Products will be imported in the background.' });
            setPickerOpen(false);
            setWcFile(null);
            setWcColumnCheck(null);
            setWcStep('upload');
            if (woocommerceIndexHref) {
                router.visit(woocommerceIndexHref);
            } else {
                router.reload({ only: ['importData', 'importSummary'] });
            }
        } catch (err: any) {
            const msg = err?.response?.data?.message ?? err?.response?.data?.errors?.file?.[0] ?? 'Upload failed.';
            toast.error('Import failed', { description: msg });
        } finally {
            setWcUploading(false);
        }
    };
    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={pageTitle} />
            <div className="no-scrollbar rounded-xl bg-gray-100/55 p-2 sm:p-4">
                <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">{pageTitle}</h2>
                        <div className="flex items-center text-sm text-gray-600">
                            <span>{section}</span>
                            <span className="mx-2">›</span>
                            <span>{pageTitle}</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={handleImportButtonClick}
                    modelType={detectedModelType as string | any}
                    tableHeaders={tableHeaders}
                    tableRows={tableRows}
                    sampleCsvFilename={sampleCsvFilename}
                    woocommerceMode={woocommerceMode}
                />
                <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>
            <CsvImportModal
                isOpen={isCsvModalOpen}
                onClose={closeCsvModal}
                title={importModalTitle}
                fields={csvModalContent || []}
                postRouteName={importPostRoute}
                postRouteParams={postRouteParams}
                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>
            )}
            {/* Import Type Picker Modal — shown when woocommercePostRoute is available */}
            {woocommercePostRoute && (
                <Dialog open={pickerOpen} onOpenChange={(o) => { if (!o && !wcUploading) { setPickerOpen(false); setWcColumnCheck(null); setWcStep('upload'); } }}>
                    <DialogContent className="max-w-md">
                        <DialogHeader>
                            <DialogTitle className="flex items-center gap-2">
                                <FileSpreadsheet className="h-5 w-5 text-primary" />
                                {woocommerceMode ? 'WooCommerce Import' : 'Select Import Type'}
                            </DialogTitle>
                        </DialogHeader>

                        {/* Radio selection — hidden when on the dedicated WooCommerce import page */}
                        {!woocommerceMode && (
                            <RadioGroup
                                value={pickerType}
                                onValueChange={(v) => setPickerType(v as 'default' | 'woocommerce')}
                                className="mt-1 space-y-3"
                            >
                                <label
                                    htmlFor="pick-default"
                                    className={`flex cursor-pointer items-start gap-3 rounded-lg border p-4 transition-colors ${pickerType === 'default' ? 'border-primary bg-primary/5' : 'border-border hover:bg-muted/40'}`}
                                >
                                    <RadioGroupItem value="default" id="pick-default" className="mt-0.5" />
                                    <div>
                                        <p className="text-sm font-medium">Default CSV</p>
                                        <p className="mt-0.5 text-xs text-muted-foreground">Upload your own CSV with column mapping. Use the sample template to get started.</p>
                                    </div>
                                </label>
                                <label
                                    htmlFor="pick-woocommerce"
                                    className={`flex cursor-pointer items-start gap-3 rounded-lg border p-4 transition-colors ${pickerType === 'woocommerce' ? 'border-primary bg-primary/5' : 'border-border hover:bg-muted/40'}`}
                                >
                                    <RadioGroupItem value="woocommerce" id="pick-woocommerce" className="mt-0.5" />
                                    <div>
                                        <p className="text-sm font-medium">WooCommerce Export</p>
                                        <p className="mt-0.5 text-xs text-muted-foreground">Upload a WooCommerce product export CSV directly. All 249 columns are mapped automatically.</p>
                                    </div>
                                </label>
                            </RadioGroup>
                        )}

                        {/* WooCommerce upload step */}
                        {pickerType === 'woocommerce' && wcStep === 'upload' && (
                            <div className={`mt-4 space-y-4 ${!woocommerceMode ? 'border-t pt-4' : ''}`}>
                                <div className="space-y-1.5">
                                    <Label htmlFor="wc-import-mode" className="text-xs font-medium">Import Mode</Label>
                                    <Select value={wcImportMode} onValueChange={(v) => setWcImportMode(v as any)}>
                                        <SelectTrigger id="wc-import-mode" className="h-9 text-sm">
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value="upsert">Upsert — create new, update existing</SelectItem>
                                            <SelectItem value="update">Update only — skip new products</SelectItem>
                                            <SelectItem value="skip">Skip — only import new products</SelectItem>
                                        </SelectContent>
                                    </Select>
                                </div>
                                <div className="space-y-1.5">
                                    <Label htmlFor="wc-file" className="text-xs font-medium">WooCommerce CSV File</Label>
                                    <div
                                        className="flex cursor-pointer items-center gap-3 rounded-lg border-2 border-dashed border-border bg-muted/30 px-4 py-3 transition-colors hover:border-primary/50 hover:bg-primary/5"
                                        onClick={() => document.getElementById('wc-file-input')?.click()}
                                    >
                                        <Upload className="h-4 w-4 shrink-0 text-muted-foreground" />
                                        <span className="truncate text-sm text-muted-foreground">
                                            {wcFile ? wcFile.name : 'Click to select a .csv file'}
                                        </span>
                                        <input
                                            id="wc-file-input"
                                            type="file"
                                            accept=".csv,text/csv"
                                            className="hidden"
                                            onChange={(e) => {
                                                const file = e.target.files?.[0] ?? null;
                                                setWcFile(file);
                                                setWcColumnCheck(null);
                                                if (!file) return;
                                                Papa.parse(file, {
                                                    preview: 2,
                                                    complete: (results: any) => {
                                                        const headers: string[] = [...(results.data[0] ?? [])];
                                                        if (headers[0]?.startsWith('\uFEFF')) headers[0] = headers[0].slice(1);
                                                        const missingRequired = WC_REQUIRED_COLUMNS.filter(c => !headers.includes(c));
                                                        const missingOptional = WC_RECOMMENDED_COLUMNS.filter(c => !headers.includes(c));
                                                        setWcColumnCheck({
                                                            state: missingRequired.length > 0 ? 'error' : missingOptional.length > 0 ? 'warn' : 'valid',
                                                            missingRequired,
                                                            missingOptional,
                                                        });
                                                    },
                                                });
                                            }}
                                        />
                                    </div>
                                    {wcColumnCheck && (
                                        <div className={`mt-2 rounded-md border px-3 py-2 text-xs ${
                                            wcColumnCheck.state === 'valid' ? 'border-green-200 bg-green-50 text-green-700' :
                                            wcColumnCheck.state === 'warn'  ? 'border-amber-200 bg-amber-50 text-amber-700' :
                                                                              'border-red-200 bg-red-50 text-red-700'
                                        }`}>
                                            {wcColumnCheck.state === 'valid' && <span>✓ All required WooCommerce columns found.</span>}
                                            {wcColumnCheck.state === 'warn' && <span>⚠ Required columns found. Optional columns missing: {wcColumnCheck.missingOptional.join(', ')}</span>}
                                            {wcColumnCheck.state === 'error' && <span>✗ Not a WooCommerce export. Missing required columns: <strong>{wcColumnCheck.missingRequired.join(', ')}</strong></span>}
                                        </div>
                                    )}
                                </div>
                            </div>
                        )}

                        {/* WooCommerce mapping step */}
                        {pickerType === 'woocommerce' && wcStep === 'mapping' && (
                            <div className="mt-2 space-y-4">
                                <Card>
                                    <CardHeader className="px-4 py-3">
                                        <CardTitle className="text-sm">Column Mapping</CardTitle>
                                        <p className="text-xs text-muted-foreground">WooCommerce columns are auto-mapped to system fields. All mappings are fixed.</p>
                                    </CardHeader>
                                    <CardContent className="max-h-72 overflow-y-auto px-4 py-2 space-y-2">
                                        {WC_COLUMN_MAP.map((mapRow) => {
                                            const foundInFile = wcColumnCheck
                                                ? mapRow.wcColumn.startsWith('Attribute')
                                                    ? true
                                                    : !wcColumnCheck.missingRequired.includes(mapRow.wcColumn) &&
                                                      !wcColumnCheck.missingOptional.includes(mapRow.wcColumn)
                                                : null;
                                            return (
                                                <div key={mapRow.systemField} className="flex items-center gap-3">
                                                    <div className="w-44 shrink-0">
                                                        <span className="text-sm font-medium">{mapRow.systemField}</span>
                                                        {mapRow.required && <span className="ml-1 text-[10px] text-red-500">*</span>}
                                                        {mapRow.note && <span className="ml-1 text-[10px] text-muted-foreground">({mapRow.note})</span>}
                                                    </div>
                                                    <div className="flex-1">
                                                        <span className="inline-block rounded border border-border bg-muted px-2 py-0.5 text-xs font-mono">{mapRow.wcColumn}</span>
                                                    </div>
                                                    {foundInFile !== null && (
                                                        <span className={`shrink-0 text-[10px] font-medium ${foundInFile ? 'text-green-600' : 'text-gray-400'}`}>
                                                            {foundInFile ? '✓ found' : '— not in file'}
                                                        </span>
                                                    )}
                                                </div>
                                            );
                                        })}
                                    </CardContent>
                                </Card>
                            </div>
                        )}

                        <div className="mt-4 flex justify-end gap-2">
                            <Button variant="outline" size="sm" onClick={() => { if (!wcUploading) { setPickerOpen(false); setWcColumnCheck(null); setWcStep('upload'); } }} disabled={wcUploading}>
                                Cancel
                            </Button>
                            {pickerType === 'default' ? (
                                <Button size="sm" onClick={handlePickerContinue}>
                                    Continue
                                </Button>
                            ) : wcStep === 'upload' ? (
                                <Button size="sm" onClick={() => setWcStep('mapping')} disabled={!wcFile || wcColumnCheck?.state === 'error'}>
                                    Next
                                </Button>
                            ) : (
                                <>
                                    <Button variant="outline" size="sm" onClick={() => setWcStep('upload')}>Back</Button>
                                    <Button size="sm" onClick={handleWcUpload} disabled={wcUploading}>
                                        {wcUploading ? 'Uploading…' : 'Start Import'}
                                    </Button>
                                </>
                            )}
                        </div>
                    </DialogContent>
                </Dialog>
            )}
        </>
    );
}

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) {
        return (
            <div className="mb-4 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
                {Array.from({ length: 4 }).map((_, i) => (
                    <Card key={i} className="animate-pulse rounded-2xl border border-gray-100 bg-white shadow-sm">
                        <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="rounded-2xl border border-gray-100 bg-white shadow-sm transition-all duration-300 hover:shadow-md">
                        <CardHeader className="pb-2">
                            <div className="flex items-center justify-between">
                                <CardTitle className="flex items-center gap-2 text-sm font-medium text-gray-500">
                                    <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-gray-400">{card.description}</CardDescription>
                        </CardHeader>
                        <CardContent className="pt-0">
                            <div className="mb-3 text-2xl font-bold text-gray-800">{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-gray-50 px-2 py-1">
                                            <span className="text-gray-500 capitalize">{k.replace(/_/g, ' ')}</span>
                                            <span className="font-semibold text-gray-800">{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?: string | string[];
    tableHeaders?: string[];
    tableRows?: string[][];
    sampleCsvFilename?: string;
    woocommerceMode?: boolean;
}

function QuickImportCard({ onImportClick, modelType, tableHeaders, tableRows, sampleCsvFilename, woocommerceMode }: QuickImportCardProps) {
    const SAMPLE_HEADERS = tableHeaders;
    const SAMPLE_ROWS = tableRows;

    const downloadSample = () => {
        const escapeCsvCell = (value: unknown) => {
            const s = String(value ?? '');
            if (/[",\n\r]/.test(s)) {
                return `"${s.replace(/"/g, '""')}"`;
            }

            return s;
        };

        const headerLine = SAMPLE_HEADERS.map((h) => escapeCsvCell(h)).join(',');
        const rows = SAMPLE_ROWS.map((r) => r.map((cell) => escapeCsvCell(cell)).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 = sampleCsvFilename ?? 'sample_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">
            <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">
                            {woocommerceMode
                                ? 'Upload a WooCommerce product export CSV. All 249 WooCommerce columns are mapped automatically — no column mapping required.'
                                : 'Start an import in seconds. Use the sample template or drag a compatible CSV. Extra columns are ignored.'}
                        </CardDescription>
                    </div>
                    <div className="hidden gap-2 sm:flex">
                        {!woocommerceMode && (
                            <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">
                {woocommerceMode ? (
                    <div className="grid gap-4 lg:grid-cols-2">
                        <div className="rounded-md border border-border bg-card p-4">
                            <p className="mb-2 text-xs font-semibold text-gray-700">How it works</p>
                            <ul className="list-disc space-y-1 pl-4 text-xs text-gray-500">
                                <li>Export products from WooCommerce → Products → Export.</li>
                                <li>Upload the exported CSV here — no column mapping needed.</li>
                                <li>Re-import is safe: existing products are updated (upsert).</li>
                                <li>Categories, brands, and images are resolved automatically.</li>
                                <li>Variable products and variations are fully supported.</li>
                            </ul>
                        </div>
                        <div className="rounded-md border border-border bg-card p-4">
                            <p className="mb-2 text-xs font-semibold text-gray-700">Import modes</p>
                            <ul className="list-disc space-y-1 pl-4 text-xs text-gray-500">
                                <li><strong>upsert</strong> (default) — create new, update existing.</li>
                                <li><strong>update</strong> — only update existing, skip new.</li>
                                <li><strong>skip</strong> — skip products already in the system.</li>
                            </ul>
                        </div>
                        <div className="col-span-full mt-1 flex gap-2 sm:hidden">
                            <Button size="sm" className="flex-1" onClick={onImportClick}>
                                <FileSpreadsheet className="mr-2 h-4 w-4" /> Import
                            </Button>
                        </div>
                    </div>
                ) : (
                    <div className="grid gap-8 lg:grid-cols-12">
                        <div className="flex flex-col gap-5 lg:col-span-5">
                            <div>
                                <p className="mb-2 text-xs font-medium tracking-wide text-gray-500 uppercase">Template Columns</p>
                                <div className="no-scrollbar flex max-h-32 flex-wrap gap-2 overflow-y-auto">
                                    {SAMPLE_HEADERS.map((h) => (
                                        <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>
                                            <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>
                        <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="no-scrollbar overflow-x-auto rounded-lg border bg-card shadow-sm">
                                    <table className="w-max min-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>
                            </div>
                        </div>
                    </div>
                )}
            </CardContent>
        </Card>
    );
}
