import React, { useState, useMemo, useRef, useCallback, useEffect } from 'react';
import { ExcelRow } from '../types';
import { useColumns } from '../contexts/ColumnsContext';
import {
  AlertTriangle,
  AlertCircle,
  CheckCircle2,
  DollarSign,
  Package,
  Save,
  X,
  ChevronDown,
  Edit2,
  Filter,
  Check,
  Search,
  MessageSquare,
} from 'lucide-react';
import { cn } from '../lib/utils';
import { ColumnFilterPopover } from './ColumnFilterPopover';

interface PricingViewProps {
  data: ExcelRow[];
  headers: string[];
  onSaveRow: (index: number, updatedRow: ExcelRow) => void;
  onCaptureState: (message: string) => void;
  onEdit: (index: number) => void;
  rowStatuses: Record<string, string>;
}

interface DetectedCol {
  index: number;
  name: string;
}

type FilterMode = 'all' | 'all_errors' | 'pricing_errors' | 'units_errors';

interface EditingCell {
  rowIndex: number;
  colIndex: number;
  value: string;
}

// Flexible multi-keyword column finder
function findCol(headers: string[], ...keywords: string[]): number {
  return headers.findIndex(h =>
    keywords.every(kw => (h || '').toLowerCase().includes(kw.toLowerCase()))
  );
}

export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, rowStatuses }: PricingViewProps) {
  const COLUMNS = useColumns();
  const [filterMode, setFilterMode] = useState<FilterMode>('all_errors');
  const [search, setSearch] = useState('');
  const [searchMode, setSearchMode] = useState<'all' | 'selected'>('all');
  const [currentPage, setCurrentPage] = useState(1);
  const pageSize = 100;
  const [columnWidths, setColumnWidths] = useState<Record<string, number>>({
    articleNo: 100,
    articleName: 220,
    line: 100,
    classification: 130,
    productType: 140,
    unitsOuter: 100,
    outerW: 80,
    outerL: 80,
    outerH: 80,
    check: 100,
    actions: 60,
  });
  const [resizingColumn, setResizingColumn] = useState<string | null>(null);
  const [resizeStartX, setResizeStartX] = useState<number | null>(null);
  const [resizeStartWidth, setResizeStartWidth] = useState<number | null>(null);
  const tableRef = useRef<HTMLTableElement>(null);
  const [editingCell, setEditingCell] = useState<EditingCell | null>(null);
  const [savingCell, setSavingCell] = useState<{ rowIndex: number; colIndex: number } | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const [lineMultiFilter, setLineMultiFilter] = useState<string[]>([]);
  const [classificationFilter, setClassificationFilter] = useState<string[]>([]);
  const [nameColFilter, setNameColFilter] = useState('');
  const [openFilter, setOpenFilter] = useState<string | null>(null);
  const [unitsOuterFilter, setUnitsOuterFilter] = useState<string[]>([]);
  const [outerWFilter, setOuterWFilter] = useState<string[]>([]);
  const [outerLFilter, setOuterLFilter] = useState<string[]>([]);
  const [outerHFilter, setOuterHFilter] = useState<string[]>([]);
  const [dynamicColFilters, setDynamicColFilters] = useState<Record<number, string[]>>({});
  const [weightIssueFilter, setWeightIssueFilter] = useState<'all' | 'with' | 'without'>('all');
  const [editingType, setEditingType] = useState<{ rowIndex: number; value: string } | null>(null);
  const [typeSuggestions, setTypeSuggestions] = useState<string[]>([]);
  const typeInputRef = useRef<HTMLInputElement>(null);
  const [sortConfig, setSortConfig] = useState<{ key: string | number; direction: 'asc' | 'desc' | null }>({ key: null, direction: null });

  const [isSearchOpen, setIsSearchOpen] = useState(false);
  const [selectedSearchItems, setSelectedSearchItems] = useState<Set<number>>(new Set());
  const searchDropdownRef = useRef<HTMLDivElement>(null);

  // Close search dropdown on click outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (searchDropdownRef.current && !searchDropdownRef.current.contains(event.target as Node)) {
        setIsSearchOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const searchSuggestions = useMemo(() => {
    if (!search && selectedSearchItems.size === 0) return data.slice(0, 50);
    if (!search) return [];
    const s = search.toLowerCase();
    return data.filter(r => 
      String(r[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
      String(r[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
    ).slice(0, 50);
  }, [data, search, selectedSearchItems]);

  const handleSearchItemClick = (index: number) => {
    const newSelected = new Set(selectedSearchItems);
    if (newSelected.has(index)) {
      newSelected.delete(index);
    } else {
      newSelected.add(index);
    }
    setSelectedSearchItems(newSelected);
  };

  const handleApplySearch = () => {
    if (selectedSearchItems.size > 0) {
      setSearchMode('selected');
    }
    setIsSearchOpen(false);
  };

  const handleClearSearch = () => {
    setSelectedSearchItems(new Set());
    setSearchMode('all');
  };

  const handleResizeStart = (e: React.MouseEvent, colKey: string, currentWidth: number) => {
    console.log('Resize started for:', colKey, 'at x:', e.clientX);
    e.preventDefault();
    e.stopPropagation();
    setResizingColumn(colKey);
    setResizeStartX(e.clientX);
    setResizeStartWidth(currentWidth);
  };

  React.useEffect(() => {
    if (!resizingColumn || resizeStartX === null || resizeStartWidth === null) return;

    const handleMouseMove = (e: MouseEvent) => {
      const delta = e.clientX - resizeStartX;
      const newWidth = Math.max(40, Math.min(800, resizeStartWidth + delta));
      setColumnWidths(prev => ({ ...prev, [resizingColumn]: newWidth }));
    };

    const handleMouseUp = () => {
      setResizingColumn(null);
      setResizeStartX(null);
      setResizeStartWidth(null);
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [resizingColumn, resizeStartX, resizeStartWidth]);

  // ── Dynamic column detection ──────────────────────────────────────────────
  const { uvpIdx, srpCols, containerCols, nwIdx, gwIdx, unitsOuterIdx } = useMemo(() => {
    const uvpIdx = findCol(headers, 'uvp');

    // All SRP columns, sorted: INT first, UK second, then alphabetically
    const srp: DetectedCol[] = headers
      .map((h, i) => ({ index: i, name: h || '' }))
      .filter(({ name }) => /srp/i.test(name))
      .sort((a, b) => {
        const order = (n: string) => {
          if (/int/i.test(n)) return 0;
          if (/uk/i.test(n)) return 1;
          return 2;
        };
        return order(a.name) - order(b.name);
      });

    // All 40' container columns (HC, HQ, etc.)
    const container: DetectedCol[] = headers
      .map((h, i) => ({ index: i, name: h || '' }))
      .filter(({ name }) => /40/i.test(name) && /h[cq]/i.test(name));

    // Net weight / Gross weight columns
    const nwIdx = findCol(headers, 'nw');
    const gwIdx = findCol(headers, 'gw');

    const unitsOuterIdx = COLUMNS.UNITS_OUTER;

    return { uvpIdx, srpCols: srp, containerCols: container, nwIdx, gwIdx, unitsOuterIdx };
  }, [headers, COLUMNS]);

  // ── Error analysis per row ────────────────────────────────────────────────
  const analyzedRows = useMemo(() => {
    return data.map((row, dataIndex) => {
      const pricingErrors: string[] = [];
      const unitErrors: string[] = [];

      // UVP check
      if (uvpIdx >= 0) {
        const v = row[uvpIdx];
        if (v === undefined || v === null || v === '' || Number(v) === 0) {
          pricingErrors.push('UVP missing');
        }
      }

      // SRP checks
      srpCols.forEach(({ index, name }) => {
        const v = row[index];
        if (v === undefined || v === null || v === '' || Number(v) === 0) {
          pricingErrors.push(`${name} missing`);
        }
      });

      // Units per Outer check
      const unitsOuter = Number(row[unitsOuterIdx]);
      if (!unitsOuter || unitsOuter === 0) {
        unitErrors.push('Units/Outer: missing');
      }

      // 40' container checks
      containerCols.forEach(({ index, name }) => {
        const v = Number(row[index]);
        if (!v || v === 0) unitErrors.push(`${name}: empty`);
        else if (v === 1) unitErrors.push(`${name}: value is 1`);
      });

      // NW > GW check
      if (nwIdx >= 0 && gwIdx >= 0) {
        const nw = parseFloat(String(row[nwIdx] ?? '').replace(',', '.'));
        const gw = parseFloat(String(row[gwIdx] ?? '').replace(',', '.'));
        if (!isNaN(nw) && !isNaN(gw) && nw > gw) {
          unitErrors.push(`NW (${nw}) > GW (${gw})`);
        }
      }

      return {
        row,
        dataIndex,
        pricingErrors,
        unitErrors,
        hasErrors: pricingErrors.length > 0 || unitErrors.length > 0,
        isCritical: unitErrors.length > 0,
      };
    });
  }, [data, uvpIdx, srpCols, containerCols]);

  // ── Stats ─────────────────────────────────────────────────────────────────
  const stats = useMemo(() => {
    const withPricing = analyzedRows.filter(r => r.pricingErrors.length > 0).length;
    const withUnits = analyzedRows.filter(r => r.unitErrors.length > 0).length;
    const withAny = analyzedRows.filter(r => r.hasErrors).length;
    const allOk = analyzedRows.length - withAny;
    return { total: analyzedRows.length, withPricing, withUnits, withAny, allOk };
  }, [analyzedRows]);

  // ── Unique values for column filters ─────────────────────────────────────
  const uniqueLines = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[COLUMNS.LINE] || '')))).sort(),
  [data]);

  const uniqueClassifications = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[COLUMNS.CLASSIFICATION] || '')))).sort(),
  [data]);

  const uniqueUnitsOuter = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[unitsOuterIdx] || '')))).filter(v => v).sort(),
  [data, unitsOuterIdx]);

  const uniqueOuterW = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[COLUMNS.OUTER_W] || '')))).filter(v => v).sort((a, b) => Number(a) - Number(b)),
  [data]);

  const uniqueOuterL = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[COLUMNS.OUTER_L] || '')))).filter(v => v).sort((a, b) => Number(a) - Number(b)),
  [data]);

  const uniqueOuterH = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[COLUMNS.OUTER_H] || '')))).filter(v => v).sort((a, b) => Number(a) - Number(b)),
  [data]);

  // ── Filtered rows ─────────────────────────────────────────────────────────
  const filteredRows = useMemo(() => {
    let result = analyzedRows;

    // Mode filter
    switch (filterMode) {
      case 'all_errors':   result = analyzedRows.filter(r => r.hasErrors); break;
      case 'pricing_errors': result = analyzedRows.filter(r => r.pricingErrors.length > 0); break;
      case 'units_errors': result = analyzedRows.filter(r => r.unitErrors.length > 0); break;
    }

    // Global search (SKU + Name)
    if (search) {
      const s = search.toLowerCase();
      result = result.filter(r =>
        String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) ||
        String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s)
      );
    }

    // Selected items from search dropdown
    if (searchMode === 'selected' && selectedSearchItems.size > 0) {
      result = result.filter(r => {
        const articleNo = String(r.row[COLUMNS.ARTICLE_NO] || '');
        return selectedSearchItems.has(articleNo);
      });
    }

    // Column filters
    if (nameColFilter) {
      const s = nameColFilter.toLowerCase();
      result = result.filter(r => String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s));
    }
    if (lineMultiFilter.length > 0) {
      result = result.filter(r => lineMultiFilter.includes(String(r.row[COLUMNS.LINE] || '')));
    }
    if (classificationFilter.length > 0) {
      result = result.filter(r => classificationFilter.includes(String(r.row[COLUMNS.CLASSIFICATION] || '')));
    }
    if (unitsOuterFilter.length > 0) {
      result = result.filter(r => unitsOuterFilter.includes(String(r.row[unitsOuterIdx] || '')));
    }
    if (outerWFilter.length > 0) {
      result = result.filter(r => outerWFilter.includes(String(r.row[COLUMNS.OUTER_W] || '')));
    }
    if (outerLFilter.length > 0) {
      result = result.filter(r => outerLFilter.includes(String(r.row[COLUMNS.OUTER_L] || '')));
    }
    if (outerHFilter.length > 0) {
      result = result.filter(r => outerHFilter.includes(String(r.row[COLUMNS.OUTER_H] || '')));
    }

    // Dynamic column filters (SRP, container)
    (Object.keys(dynamicColFilters) as string[]).forEach(colIdx => {
      const filterVals = dynamicColFilters[Number(colIdx)];
      if (filterVals && filterVals.length > 0) {
        const col = Number(colIdx);
        result = result.filter(r => filterVals.includes(String(r.row[col] || '')));
      }
    });

    // Weight issue filter
    if (weightIssueFilter === 'with') {
      result = result.filter(r => r.unitErrors.some(e => e.startsWith('NW')));
    } else if (weightIssueFilter === 'without') {
      result = result.filter(r => !r.unitErrors.some(e => e.startsWith('NW')));
    }

    return result;
  }, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters, weightIssueFilter]);

  // ── Sorted rows ──────────────────────────────────────────────────────────
  const sortedRows = useMemo(() => {
    if (sortConfig.key === null || sortConfig.direction === null) return filteredRows;

    const { key, direction } = sortConfig;
    let colIndex: number;
    
    if (typeof key === 'number') {
      colIndex = key;
    } else {
      // Map string keys to COLUMNS indices
      switch (key) {
        case 'articleNo': colIndex = COLUMNS.ARTICLE_NO; break;
        case 'articleName': colIndex = COLUMNS.ARTICLE_NAME; break;
        case 'line': colIndex = COLUMNS.LINE; break;
        case 'classification': colIndex = COLUMNS.CLASSIFICATION; break;
        case 'productType': colIndex = COLUMNS.PRODUCT_TYPE; break;
        case 'unitsOuter': colIndex = unitsOuterIdx; break;
        case 'outerW': colIndex = COLUMNS.OUTER_W; break;
        case 'outerL': colIndex = COLUMNS.OUTER_L; break;
        case 'outerH': colIndex = COLUMNS.OUTER_H; break;
        default: return filteredRows;
      }
    }

    const sorted = [...filteredRows].sort((a, b) => {
      const valA = a.row[colIndex];
      const valB = b.row[colIndex];

      // Handle null/undefined
      if (valA === valB) return 0;
      if (valA === null || valA === undefined || valA === '') return 1;
      if (valB === null || valB === undefined || valB === '') return -1;

      // Handle numeric comparison
      const numA = typeof valA === 'number' ? valA : parseFloat(String(valA).replace(',', '.'));
      const numB = typeof valB === 'number' ? valB : parseFloat(String(valB).replace(',', '.'));

      if (!isNaN(numA) && !isNaN(numB)) {
        return direction === 'asc' ? numA - numB : numB - numA;
      }

      // Handle string comparison
      const strA = String(valA).toLowerCase();
      const strB = String(valB).toLowerCase();
      
      if (strA < strB) return direction === 'asc' ? -1 : 1;
      if (strA > strB) return direction === 'asc' ? 1 : -1;
      return 0;
    });

    return sorted;
  }, [filteredRows, sortConfig]);

  // ── Pagination ─────────────────────────────────────────────────────────
  const paginatedRows = useMemo(() => {
    const start = (currentPage - 1) * pageSize;
    return sortedRows.slice(start, start + pageSize);
  }, [sortedRows, currentPage]);

  const totalPages = Math.ceil(sortedRows.length / pageSize);

  const handleSort = (key: string | number) => {
    setSortConfig(prev => {
      if (prev.key === key) {
        if (prev.direction === 'asc') return { key, direction: 'desc' };
        return { key: null, direction: null };
      }
      return { key, direction: 'asc' };
    });
  };

  // ── Inline edit helpers ───────────────────────────────────────────────────
  const startEdit = (rowIndex: number, colIndex: number, currentValue: string) => {
    setEditingCell({ rowIndex, colIndex, value: currentValue });
    setTimeout(() => inputRef.current?.focus(), 0);
  };

  const commitEdit = useCallback(async () => {
    if (!editingCell) return;
    const { rowIndex, colIndex, value } = editingCell;
    const original = data[rowIndex];
    const newRow = [...original];
    newRow[colIndex] = value;
    setSavingCell({ rowIndex, colIndex });
    setEditingCell(null);
    onCaptureState(`Updated pricing for ${original[COLUMNS.ARTICLE_NO]}`);
    await onSaveRow(rowIndex, newRow);
    setSavingCell(null);
  }, [editingCell, data, onSaveRow, onCaptureState]);

  const cancelEdit = () => setEditingCell(null);

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') commitEdit();
    if (e.key === 'Escape') cancelEdit();
  };

  // ── All unique product types (for autocomplete) ───────────────────────────
  const allProductTypes = useMemo(() =>
    Array.from(new Set(data.map(r => String(r[COLUMNS.PRODUCT_TYPE] || '')).filter(Boolean))).sort()
  , [data]);

  const startEditType = (rowIndex: number, currentValue: string) => {
    setEditingType({ rowIndex, value: currentValue });
    setTypeSuggestions(allProductTypes);
    setTimeout(() => typeInputRef.current?.focus(), 0);
  };

  const commitTypeEdit = useCallback(async (rowIndex: number, value: string) => {
    setEditingType(null);
    setTypeSuggestions([]);
    const original = data[rowIndex];
    const newRow = [...original];
    newRow[COLUMNS.PRODUCT_TYPE] = value;
    onCaptureState(`Updated type for ${original[COLUMNS.ARTICLE_NO]}`);
    await onSaveRow(rowIndex, newRow);
  }, [data, onSaveRow, onCaptureState]);

  const handleTypeInputChange = (value: string) => {
    setEditingType(prev => prev ? { ...prev, value } : null);
    const lower = value.toLowerCase();
    setTypeSuggestions(
      lower ? allProductTypes.filter(t => t.toLowerCase().includes(lower)) : allProductTypes
    );
  };

  // ── Column helpers ────────────────────────────────────────────────────────
  const pricingEditableCols: DetectedCol[] = [
    ...(uvpIdx >= 0 ? [{ index: uvpIdx, name: headers[uvpIdx] || 'UVP' }] : []),
    ...srpCols,
  ];

  // ═ Unique values for dynamic pricing columns ═════════════════════════════
  const dynamicColUniqueValues = useMemo(() => {
    const result: Record<number, string[]> = {};
    pricingEditableCols.forEach(col => {
      result[col.index] = Array.from(new Set(data.map(r => String(r[col.index] || '')))).filter(v => v).sort();
    });
    containerCols.forEach(col => {
      result[col.index] = Array.from(new Set(data.map(r => String(r[col.index] || '')))).filter(v => v).sort();
    });
    return result;
  }, [data, uvpIdx, srpCols, containerCols, headers]);

  const formatPrice = (val: any) => {
    if (val === undefined || val === null || val === '') return '';
    const n = parseFloat(String(val).replace(',', '.'));
    return isNaN(n) ? String(val) : n.toFixed(2);
  };

  const formatUnits = (val: any) => {
    if (val === undefined || val === null || val === '') return '—';
    return String(val);
  };

  const unitBadge = (val: any, label: string) => {
    const n = Number(val);
    if (!val || n === 0) return (
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-bold bg-red-500/20 text-red-400 border border-red-500/40">
        <AlertCircle className="w-3 h-3" /> 0
      </span>
    );
    if (n === 1) return (
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-bold bg-amber-500/20 text-amber-400 border border-amber-500/40">
        <AlertTriangle className="w-3 h-3" /> 1
      </span>
    );
    return (
      <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold bg-emerald-500/10 text-emerald-400 border border-emerald-500/30">
        {n.toLocaleString()}
      </span>
    );
  };

  const unitOuterBadge = (val: any) => {
    const n = Number(val);
    if (!val || n === 0) return (
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-bold bg-red-500/20 text-red-400 border border-red-500/40">
        <AlertCircle className="w-3 h-3" /> Missing
      </span>
    );
    return (
      <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold bg-slate-500/20 text-slate-300 border border-slate-600/50">
        {n}
      </span>
    );
  };

  // ── Matrix columns (the rest) ─────────────────────────────────────────────
  const displayedIndices = useMemo(() => {
    const set = new Set<number>([
      COLUMNS.ARTICLE_NO,
      COLUMNS.ARTICLE_NAME,
      COLUMNS.LINE,
      COLUMNS.CLASSIFICATION,
      unitsOuterIdx,
      COLUMNS.OUTER_W,
      COLUMNS.OUTER_L,
      COLUMNS.OUTER_H,
    ]);
    if (uvpIdx >= 0) set.add(uvpIdx);
    srpCols.forEach(c => set.add(c.index));
    containerCols.forEach(c => set.add(c.index));
    return set;
  }, [uvpIdx, srpCols, containerCols]);

  const matrixCols = useMemo(() => {
    return headers
      .map((h, i) => ({ index: i, name: h || '' }))
      .filter(({ index }) => !displayedIndices.has(index))
      .filter(({ name }) => name.trim() !== ''); // Skip empty headers
  }, [headers, displayedIndices]);

  const [noteEditor, setNoteEditor] = useState<{ rowIndex: number; text: string } | null>(null);

  const handleToggleCheck = async (rowIndex: number, checked: boolean) => {
    const original = data[rowIndex];
    const newRow = [...original];
    newRow[COLUMNS.VALIDATED_CHECK] = checked;
    onCaptureState(`${checked ? 'Checked' : 'Unchecked'} ${original[COLUMNS.ARTICLE_NO]}`);
    await onSaveRow(rowIndex, newRow);
  };

  const saveNote = async () => {
    if (!noteEditor) return;
    const { rowIndex, text } = noteEditor;
    const original = data[rowIndex];
    const newRow = [...original];
    newRow[COLUMNS.VALIDATED_NOTE] = text;
    setNoteEditor(null);
    onCaptureState(`Updated note for ${original[COLUMNS.ARTICLE_NO]}`);
    await onSaveRow(rowIndex, newRow);
  };

  // ── Column detection notice ───────────────────────────────────────────────
  const missingCols: string[] = [];
  if (uvpIdx < 0) missingCols.push('UVP');
  if (srpCols.length === 0) missingCols.push('SRP');
  if (containerCols.length === 0) missingCols.push('Units/40\'');

  const FILTERS: { id: FilterMode; label: string; count: number; color: string }[] = [
    { id: 'all',          label: 'All Products',    count: stats.total,      color: 'text-slate-300' },
    { id: 'all_errors',   label: 'All Issues',      count: stats.withAny,    color: 'text-red-400' },
    { id: 'pricing_errors', label: 'Pricing Issues', count: stats.withPricing, color: 'text-amber-400' },
    { id: 'units_errors', label: 'Units Issues',    count: stats.withUnits,  color: 'text-orange-400' },
  ];

  return (
    <div className="flex flex-col h-full gap-4 relative">
      {/* ── Note Editor Modal ── */}
      {noteEditor && (
        <div className="fixed inset-0 bg-slate-950/50 backdrop-blur-sm z-[100] flex items-center justify-center p-4">
          <div className="bg-slate-800 border border-slate-700 rounded-xl shadow-2xl w-full max-w-md animate-in zoom-in-95 duration-200">
            <div className="p-4 border-b border-slate-700 flex items-center justify-between">
              <h3 className="font-semibold text-white flex items-center gap-2">
                <MessageSquare className="w-4 h-4 text-blue-400" />
                Validation Note
              </h3>
              <p className="text-[10px] text-slate-500 font-mono">{data[noteEditor.rowIndex][COLUMNS.ARTICLE_NO]}</p>
            </div>
            <div className="p-4">
              <textarea
                value={noteEditor.text}
                onChange={e => setNoteEditor(prev => prev ? { ...prev, text: e.target.value } : null)}
                placeholder="Write a note about this product..."
                className="w-full h-32 bg-slate-900 border border-slate-700 rounded-lg p-3 text-sm text-white focus:outline-none focus:border-blue-500 resize-none"
                autoFocus
              />
            </div>
            <div className="p-4 bg-slate-900/50 rounded-b-xl flex justify-end gap-3">
              <button onClick={() => setNoteEditor(null)} className="px-4 py-2 text-sm text-slate-400 hover:text-white transition-colors">Cancel</button>
              <button 
                onClick={saveNote}
                className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-bold rounded-lg shadow-lg active:scale-95 transition-all"
              >
                Save Note
              </button>
            </div>
          </div>
        </div>
      )}

      <div className="flex items-center justify-between gap-4">
        {/* ── Search bar with Dropdown ── */}
        <div className="flex-1 max-w-md relative" ref={searchDropdownRef}>
          <div className="relative">
            <input
              type="text"
              placeholder="Search SKU or Name..."
              value={search}
              onChange={e => {
                setSearch(e.target.value);
                setIsSearchOpen(true);
              }}
              onFocus={() => setIsSearchOpen(true)}
              className="w-full pl-4 pr-10 py-2 bg-slate-800 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all"
            />
            {selectedSearchItems.size > 0 ? (
              <button
                onClick={handleClearSearch}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-blue-400 hover:text-white flex items-center gap-1"
              >
                <span className="text-xs bg-blue-600 text-white rounded-full w-5 h-5 flex items-center justify-center">
                  {selectedSearchItems.size}
                </span>
              </button>
            ) : search ? (
              <button
                onClick={() => { setSearch(''); setSearchMode('all'); }}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-white"
              >
                <X className="w-4 h-4" />
              </button>
            ) : (
              <div className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-500">
                <Package className="w-4 h-4" />
              </div>
            )}
          </div>

          {/* Search Dropdown Panel */}
          {isSearchOpen && searchSuggestions.length > 0 && (
            <div className="absolute top-full left-0 right-0 mt-1 bg-slate-800 border border-slate-700 rounded-lg shadow-2xl z-[150] overflow-hidden animate-in fade-in slide-in-from-top-2 duration-200">
              <div className="max-h-64 overflow-y-auto">
                {searchSuggestions.map((row, idx) => {
                  return (
                    <button
                      key={`${row[COLUMNS.ARTICLE_NO]}-${idx}`}
                      onClick={() => {
                        const key = String(row[COLUMNS.ARTICLE_NO]);
                        setSelectedSearchItems(prev => {
                          const next = new Set(prev);
                          if (next.has(key)) next.delete(key);
                          else next.add(key);
                          return next;
                        });
                      }}
                      className="w-full text-left px-4 py-2.5 hover:bg-slate-700/50 flex items-center gap-3 border-b border-slate-700/30 last:border-0 transition-colors"
                    >
                      <div className={cn(
                        "w-4 h-4 rounded border flex items-center justify-center shrink-0",
                        selectedSearchItems.has(String(row[COLUMNS.ARTICLE_NO])) 
                          ? "bg-blue-600 border-blue-600" 
                          : "border-slate-600"
                      )}>
                        {selectedSearchItems.has(String(row[COLUMNS.ARTICLE_NO])) && (
                          <svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
                          </svg>
                        )}
                      </div>
                      <div className="flex flex-col gap-0.5">
                        <span className="text-xs font-mono font-bold text-blue-400">{row[COLUMNS.ARTICLE_NO]}</span>
                        <span className="text-xs text-slate-300 truncate">{row[COLUMNS.ARTICLE_NAME]}</span>
                      </div>
                    </button>
                  );
                })}
              </div>
              <div className="flex items-center justify-between px-4 py-2 bg-slate-900/50 border-t border-slate-700">
                <button
                  onClick={handleClearSearch}
                  className="text-xs text-slate-400 hover:text-white"
                >
                  Clear ({selectedSearchItems.size})
                </button>
                <button
                  onClick={handleApplySearch}
                  className="px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white text-xs rounded"
                >
                  Apply
                </button>
              </div>
              {searchSuggestions.length === 50 && (
                <div className="px-4 py-1.5 bg-slate-900/50 text-[10px] text-slate-500 border-t border-slate-700 italic">
                  Showing first 50 results...
                </div>
              )}
            </div>
          )}
        </div>

        {/* ── Filter tabs ── */}
        <div className="flex items-center gap-1 bg-slate-800/60 rounded-lg p-1 border border-slate-700/50 w-fit">
          {FILTERS.map(f => (
            <button
              key={f.id}
              onClick={() => { setFilterMode(f.id); setCurrentPage(1); }}
              className={cn(
                'flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-colors',
                filterMode === f.id
                  ? 'bg-slate-700 text-white shadow-sm'
                  : 'text-slate-400 hover:text-slate-200 hover:bg-slate-700/40'
              )}
            >
              {f.label}
              <span className={cn(
                'text-xs font-bold px-1.5 py-0.5 rounded-full min-w-[22px] text-center',
                filterMode === f.id
                  ? 'bg-slate-600 text-white'
                  : f.count > 0 ? `${f.color} bg-current/10` : 'text-slate-500'
              )}>
                {f.count}
              </span>
            </button>
          ))}
        </div>
      </div>

      {/* ── Column detection warning ── */}
      {missingCols.length > 0 && (
        <div className="flex items-center gap-3 px-4 py-2.5 bg-amber-500/10 border border-amber-500/30 rounded-lg text-amber-300 text-sm">
          <AlertTriangle className="w-4 h-4 shrink-0" />
          <span>
            Could not auto-detect columns for: <strong>{missingCols.join(', ')}</strong>.
            Check that the Excel headers contain "UVP", "SRP", or "40HC"/"40HQ".
          </span>
        </div>
      )}

      {/* ── Stat cards ── */}
      <div className="grid grid-cols-4 gap-3">
        <StatCard label="Total Products" value={stats.total} icon={<Package className="w-4 h-4" />} color="slate" />
        <StatCard label="Pricing Issues" value={stats.withPricing} icon={<DollarSign className="w-4 h-4" />} color="amber" />
        <StatCard label="Units Issues" value={stats.withUnits} icon={<AlertCircle className="w-4 h-4" />} color="red" />
        <StatCard label="All OK" value={stats.allOk} icon={<CheckCircle2 className="w-4 h-4" />} color="emerald" />
      </div>

      {/* ── Table ── */}
      <div className="flex-1 overflow-auto bg-slate-800 rounded-xl border border-slate-700 shadow-xl">
        {sortedRows.length === 0 ? (
          <div className="flex flex-col items-center justify-center h-64 text-slate-400">
            <CheckCircle2 className="w-12 h-12 text-emerald-500 mb-3" />
            <p className="text-lg font-medium text-emerald-400">No issues found</p>
            <p className="text-sm mt-1">All products are correctly configured.</p>
          </div>
        ) : (
          <table ref={tableRef} className="w-full text-sm border-collapse table-fixed">
            <thead className="sticky top-0 z-10 bg-slate-900 border-b border-slate-700">
              <tr>
                <th style={{ width: columnWidths.articleNo }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap relative group cursor-pointer hover:bg-slate-800/50 transition-colors" onClick={() => handleSort('articleNo')}>
                  <div className="flex items-center justify-between gap-1">
                    <span className="flex items-center gap-1">Art. No. <SortIcon current={sortConfig.key === 'articleNo' ? sortConfig.direction : null} /></span>
                  </div>
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'articleNo', columnWidths.articleNo); }} />
                </th>
                <th style={{ width: columnWidths.articleName }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('articleName')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Article Name <SortIcon current={sortConfig.key === 'articleName' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'name' ? null : 'name'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        nameColFilter ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'name' && (
                    <TextFilterPopover
                      value={nameColFilter}
                      onChange={setNameColFilter}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'articleName', columnWidths.articleName); }} />
                </th>
                <th style={{ width: columnWidths.line }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('line')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Line <SortIcon current={sortConfig.key === 'line' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'line' ? null : 'line'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        lineMultiFilter.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'line' && (
                    <ColumnFilterPopover
                      uniqueValues={uniqueLines}
                      selectedValues={lineMultiFilter}
                      onToggle={val => setLineMultiFilter(prev => prev.includes(val) ? prev.filter(v => v !== val) : [...prev, val])}
                      onSelectAll={vals => setLineMultiFilter(vals)}
                      onClear={() => { setLineMultiFilter([]); setOpenFilter(null); }}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'line', columnWidths.line); }} />
                </th>
                <th style={{ width: columnWidths.classification }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('classification')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Classification <SortIcon current={sortConfig.key === 'classification' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'classification' ? null : 'classification'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        classificationFilter.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'classification' && (
                    <ColumnFilterPopover
                      uniqueValues={uniqueClassifications}
                      selectedValues={classificationFilter}
                      onToggle={val => setClassificationFilter(prev => prev.includes(val) ? prev.filter(v => v !== val) : [...prev, val])}
                      onSelectAll={vals => setClassificationFilter(vals)}
                      onClear={() => { setClassificationFilter([]); setOpenFilter(null); }}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'classification', columnWidths.classification); }} />
                </th>

                <th style={{ width: columnWidths.productType }} className="text-left px-3 py-3 text-xs font-semibold text-purple-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('productType')}>
                  <span className="flex items-center gap-1">Type <SortIcon current={sortConfig.key === 'productType' ? sortConfig.direction : null} /></span>
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'productType', columnWidths.productType); }} />
                </th>

                {pricingEditableCols.map(col => {
                  const colKey = `prc_${col.index}`;
                  const width = columnWidths[colKey] ?? 100;
                  return (
                    <th key={col.index} style={{ width }} className="text-left px-3 py-3 text-xs font-semibold text-blue-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort(col.index)}>
                      <div className="flex items-center gap-1">
                        <span className="truncate flex items-center gap-1">{col.name} <SortIcon current={sortConfig.key === col.index ? sortConfig.direction : null} /></span>
                        <button
                          onClick={(e) => {
                            e.stopPropagation();
                            setOpenFilter(openFilter === `prc_${col.index}` ? null : `prc_${col.index}`);
                          }}
                          className={cn(
                            'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                            dynamicColFilters[col.index]?.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                          )}
                        >
                          <Filter className="w-3 h-3" />
                        </button>
                      </div>
                      {openFilter === `prc_${col.index}` && (
                        <ColumnFilterPopover
                          uniqueValues={dynamicColUniqueValues[col.index] || []}
                          selectedValues={dynamicColFilters[col.index] || []}
                          onToggle={val => setDynamicColFilters(prev => {
                            const current = prev[col.index] || [];
                            return current.includes(val) 
                              ? { ...prev, [col.index]: current.filter(v => v !== val) }
                              : { ...prev, [col.index]: [...current, val] };
                          })}
                          onSelectAll={vals => setDynamicColFilters(prev => ({ ...prev, [col.index]: vals }))}
                          onClear={() => { setDynamicColFilters(prev => { const next = { ...prev }; delete next[col.index]; return next; }); setOpenFilter(null); }}
                          onClose={() => setOpenFilter(null)}
                        />
                      )}
                      <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, colKey, width); }} />
                    </th>
                  );
                })}

                <th style={{ width: columnWidths.unitsOuter }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('unitsOuter')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Units/Outer <SortIcon current={sortConfig.key === 'unitsOuter' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'unitsOuter' ? null : 'unitsOuter'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        unitsOuterFilter.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'unitsOuter' && (
                    <ColumnFilterPopover
                      uniqueValues={uniqueUnitsOuter}
                      selectedValues={unitsOuterFilter}
                      onToggle={val => setUnitsOuterFilter(prev => prev.includes(val) ? prev.filter(v => v !== val) : [...prev, val])}
                      onSelectAll={vals => setUnitsOuterFilter(vals)}
                      onClear={() => { setUnitsOuterFilter([]); setOpenFilter(null); }}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'unitsOuter', columnWidths.unitsOuter); }} />
                </th>

                <th style={{ width: columnWidths.outerW }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('outerW')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Outer W <SortIcon current={sortConfig.key === 'outerW' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'outerW' ? null : 'outerW'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        outerWFilter.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'outerW' && (
                    <ColumnFilterPopover
                      uniqueValues={uniqueOuterW}
                      selectedValues={outerWFilter}
                      onToggle={val => setOuterWFilter(prev => prev.includes(val) ? prev.filter(v => v !== val) : [...prev, val])}
                      onSelectAll={vals => setOuterWFilter(vals)}
                      onClear={() => { setOuterWFilter([]); setOpenFilter(null); }}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'outerW', columnWidths.outerW); }} />
                </th>

                <th style={{ width: columnWidths.outerL }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('outerL')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Outer L <SortIcon current={sortConfig.key === 'outerL' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'outerL' ? null : 'outerL'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        outerLFilter.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'outerL' && (
                    <ColumnFilterPopover
                      uniqueValues={uniqueOuterL}
                      selectedValues={outerLFilter}
                      onToggle={val => setOuterLFilter(prev => prev.includes(val) ? prev.filter(v => v !== val) : [...prev, val])}
                      onSelectAll={vals => setOuterLFilter(vals)}
                      onClear={() => { setOuterLFilter([]); setOpenFilter(null); }}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'outerL', columnWidths.outerL); }} />
                </th>

                <th style={{ width: columnWidths.outerH }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort('outerH')}>
                  <div className="flex items-center gap-1">
                    <span className="truncate flex items-center gap-1">Outer H <SortIcon current={sortConfig.key === 'outerH' ? sortConfig.direction : null} /></span>
                    <button
                      onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === 'outerH' ? null : 'outerH'); }}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        outerHFilter.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'outerH' && (
                    <ColumnFilterPopover
                      uniqueValues={uniqueOuterH}
                      selectedValues={outerHFilter}
                      onToggle={val => setOuterHFilter(prev => prev.includes(val) ? prev.filter(v => v !== val) : [...prev, val])}
                      onSelectAll={vals => setOuterHFilter(vals)}
                      onClear={() => { setOuterHFilter([]); setOpenFilter(null); }}
                      onClose={() => setOpenFilter(null)}
                    />
                  )}
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'outerH', columnWidths.outerH); }} />
                </th>

                {containerCols.map(col => {
                  const colKey = `con_${col.index}`;
                  const width = columnWidths[colKey] ?? 110;
                  return (
                    <th key={col.index} style={{ width }} className="text-left px-3 py-3 text-xs font-semibold text-orange-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort(col.index)}>
                      <div className="flex items-center gap-1">
                        <span className="truncate flex items-center gap-1">{col.name} <SortIcon current={sortConfig.key === col.index ? sortConfig.direction : null} /></span>
                        <button
                          onClick={(e) => {
                            e.stopPropagation();
                            setOpenFilter(openFilter === `con_${col.index}` ? null : `con_${col.index}`);
                          }}
                          className={cn(
                            'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                            dynamicColFilters[col.index]?.length > 0 ? 'text-blue-400 bg-blue-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                          )}
                        >
                          <Filter className="w-3 h-3" />
                        </button>
                      </div>
                      {openFilter === `con_${col.index}` && (
                        <ColumnFilterPopover
                          uniqueValues={dynamicColUniqueValues[col.index] || []}
                          selectedValues={dynamicColFilters[col.index] || []}
                          onToggle={val => setDynamicColFilters(prev => {
                            const current = prev[col.index] || [];
                            return current.includes(val) 
                              ? { ...prev, [col.index]: current.filter(v => v !== val) }
                              : { ...prev, [col.index]: [...current, val] };
                          })}
                          onSelectAll={vals => setDynamicColFilters(prev => ({ ...prev, [col.index]: vals }))}
                          onClear={() => { setDynamicColFilters(prev => { const next = { ...prev }; delete next[col.index]; return next; }); setOpenFilter(null); }}
                          onClose={() => setOpenFilter(null)}
                        />
                      )}
                      <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, colKey, width); }} />
                    </th>
                  );
                })}

                <th style={{ width: 180 }} className="text-left px-3 py-3 text-xs font-semibold text-red-400 uppercase tracking-wider border-b border-slate-700 whitespace-nowrap group relative">
                  <div className="flex items-center gap-1">
                    <span>Issues</span>
                    <button
                      onClick={() => setOpenFilter(openFilter === 'weightIssue' ? null : 'weightIssue')}
                      className={cn(
                        'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
                        weightIssueFilter !== 'all' ? 'text-red-400 bg-red-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
                      )}
                    >
                      <Filter className="w-3 h-3" />
                    </button>
                  </div>
                  {openFilter === 'weightIssue' && (
                    <div className="absolute top-full left-0 mt-1 w-44 bg-slate-800 border border-slate-700 rounded-lg shadow-2xl z-50 p-1 flex flex-col gap-0.5 animate-in fade-in zoom-in-95 duration-100">
                      {(['all', 'with', 'without'] as const).map(opt => (
                        <button
                          key={opt}
                          onClick={() => { setWeightIssueFilter(opt); setOpenFilter(null); }}
                          className={cn(
                            'w-full text-left px-3 py-1.5 rounded text-xs transition-colors',
                            weightIssueFilter === opt ? 'bg-red-500/20 text-red-400' : 'text-slate-300 hover:bg-slate-700'
                          )}
                        >
                          {opt === 'all' ? 'All' : opt === 'with' ? 'With weight issue' : 'No weight issue'}
                        </button>
                      ))}
                    </div>
                  )}
                </th>

                <th style={{ width: columnWidths.check }} className="text-left px-3 py-3 text-xs font-semibold text-blue-400 uppercase tracking-wider group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort(COLUMNS.VALIDATED_CHECK)}>
                  <span className="flex items-center gap-1">Check <SortIcon current={sortConfig.key === COLUMNS.VALIDATED_CHECK ? sortConfig.direction : null} /></span>
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'check', columnWidths.check); }} />
                </th>

                {matrixCols.map(col => {
                  const colKey = `mat_${col.index}`;
                  const width = columnWidths[colKey] ?? 120;
                  return (
                    <th key={col.index} style={{ width }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider whitespace-nowrap group cursor-pointer hover:bg-slate-800/50 transition-colors relative" title={col.name} onClick={() => handleSort(col.index)}>
                      <span className="truncate flex items-center gap-1">{col.name} <SortIcon current={sortConfig.key === col.index ? sortConfig.direction : null} /></span>
                      <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, colKey, width); }} />
                    </th>
                  );
                })}

                <th style={{ width: columnWidths.actions }} className="px-3 py-3 border-b border-slate-700 sticky right-0 bg-slate-900 shadow-[-4px_0_8px_rgba(0,0,0,0.2)]">
                  <ResizeHandle onMouseDown={e => { e.stopPropagation(); handleResizeStart(e, 'actions', columnWidths.actions); }} />
                </th>
              </tr>
            </thead>
            <tbody>
              {paginatedRows.map(({ row, dataIndex, pricingErrors, unitErrors, isCritical }) => {
                const saveStatus = rowStatuses[String(row[COLUMNS.ARTICLE_NO])];
                const isValidated = !!row[COLUMNS.VALIDATED_CHECK];
                const note = String(row[COLUMNS.VALIDATED_NOTE] || '');

                return (
                  <tr
                    key={dataIndex}
                    className={cn(
                      'border-b border-slate-700/50 transition-colors',
                      isValidated 
                        ? 'bg-green-400/30 border-l-4 border-l-green-400' // Vibrant high-visibility green
                        : saveStatus === 'error'
                          ? 'bg-red-400/20 border-l-4 border-l-red-500'
                          : saveStatus === 'pending'
                            ? 'bg-amber-400/20 border-l-4 border-l-amber-400'
                            : isCritical
                              ? 'bg-red-950/20'
                              : pricingErrors.length > 0
                                ? 'bg-amber-950/10'
                                : ''
                    )}
                  >
                    {/* Art. No. */}
                    <td className="px-3 py-2.5 font-mono text-xs text-slate-300 whitespace-nowrap overflow-hidden truncate">
                      {row[COLUMNS.ARTICLE_NO]}
                    </td>

                    {/* Article Name */}
                    <td className="px-3 py-2.5 text-slate-200 max-w-[200px]">
                      <span className="line-clamp-1" title={row[COLUMNS.ARTICLE_NAME]}>
                        {row[COLUMNS.ARTICLE_NAME] || '—'}
                      </span>
                    </td>

                    {/* Line */}
                    <td className="px-3 py-2.5 text-slate-400 whitespace-nowrap text-xs overflow-hidden truncate">
                      {row[COLUMNS.LINE] || '—'}
                    </td>

                    {/* Classification */}
                    <td className="px-3 py-2.5 overflow-hidden">
                      <span className={cn(
                        'px-2 py-0.5 rounded text-[10px] font-bold border whitespace-nowrap inline-block max-w-full truncate',
                        String(row[COLUMNS.CLASSIFICATION] || '').toUpperCase().includes('CORE')
                          ? 'bg-blue-500/10 text-blue-400 border-blue-500/20'
                          : String(row[COLUMNS.CLASSIFICATION] || '').toUpperCase().includes('OOC')
                            ? 'bg-amber-500/10 text-amber-500 border-amber-500/20'
                            : 'bg-slate-700/50 text-slate-400 border-slate-600/50'
                      )}>
                        {row[COLUMNS.CLASSIFICATION] || '—'}
                      </span>
                    </td>

                    {/* TYPE cell */}
                    <td className="px-3 py-2 overflow-visible relative">
                      {editingType?.rowIndex === dataIndex ? (
                        <div className="relative">
                          <input
                            ref={typeInputRef}
                            type="text"
                            value={editingType.value}
                            onChange={e => handleTypeInputChange(e.target.value)}
                            onKeyDown={e => {
                              if (e.key === 'Enter') commitTypeEdit(dataIndex, editingType.value);
                              if (e.key === 'Escape') { setEditingType(null); setTypeSuggestions([]); }
                            }}
                            onBlur={() => setTimeout(() => { commitTypeEdit(dataIndex, editingType?.value ?? ''); }, 150)}
                            className="w-full bg-slate-900 border border-purple-500 rounded px-2 py-1 text-sm text-white focus:outline-none focus:ring-1 focus:ring-purple-500"
                          />
                          {typeSuggestions.length > 0 && (
                            <ul className="absolute top-full left-0 mt-1 w-full min-w-[160px] bg-slate-800 border border-slate-600 rounded-lg shadow-2xl z-50 max-h-48 overflow-y-auto">
                              {typeSuggestions.map(t => (
                                <li
                                  key={t}
                                  onMouseDown={e => { e.preventDefault(); commitTypeEdit(dataIndex, t); }}
                                  className="px-3 py-1.5 text-xs text-slate-200 hover:bg-purple-500/20 cursor-pointer truncate"
                                >
                                  {t}
                                </li>
                              ))}
                            </ul>
                          )}
                        </div>
                      ) : (
                        <button
                          onClick={() => startEditType(dataIndex, String(row[COLUMNS.PRODUCT_TYPE] || ''))}
                          className={cn(
                            'group flex items-center gap-1.5 px-2 py-1 rounded text-xs transition-colors hover:bg-slate-700/60 w-full overflow-hidden',
                            row[COLUMNS.PRODUCT_TYPE]
                              ? 'text-purple-300 border border-transparent hover:border-slate-600'
                              : 'text-slate-500 border border-dashed border-slate-600 hover:border-purple-500/50'
                          )}
                        >
                          <span className="truncate">{row[COLUMNS.PRODUCT_TYPE] || 'Add type…'}</span>
                          <Edit2 className="w-2.5 h-2.5 opacity-0 group-hover:opacity-50 shrink-0" />
                        </button>
                      )}
                    </td>

                    {/* Pricing editable cells */}
                    {pricingEditableCols.map(col => {
                      const isEditing = editingCell?.rowIndex === dataIndex && editingCell?.colIndex === col.index;
                      const isSaving = savingCell?.rowIndex === dataIndex && savingCell?.colIndex === col.index;
                      const val = formatPrice(row[col.index]);
                      const isEmpty = !row[col.index] || row[col.index] === '' || Number(row[col.index]) === 0;

                      return (
                        <td key={col.index} className="px-3 py-2 overflow-hidden">
                          {isEditing ? (
                            <div className="flex items-center gap-1">
                              <input
                                ref={inputRef}
                                type="text"
                                value={editingCell.value}
                                onChange={e => setEditingCell(prev => prev ? { ...prev, value: e.target.value } : null)}
                                onKeyDown={handleKeyDown}
                                onBlur={commitEdit}
                                className="w-full bg-slate-900 border border-blue-500 rounded px-2 py-1 text-sm text-white focus:outline-none focus:ring-1 focus:ring-blue-500"
                              />
                            </div>
                          ) : (
                            <button
                              onClick={() => startEdit(dataIndex, col.index, val)}
                              className={cn(
                                'group flex items-center gap-1.5 px-2 py-1 rounded text-xs font-mono transition-colors hover:bg-slate-700/60 w-full overflow-hidden',
                                isEmpty
                                  ? 'text-amber-400 border border-amber-500/40 bg-amber-500/5'
                                  : 'text-slate-200 border border-transparent hover:border-slate-600'
                              )}
                              title={isSaving ? 'Saving…' : `Click to edit ${col.name}`}
                            >
                              {isSaving ? (
                                <span className="text-slate-500 italic truncate">saving…</span>
                              ) : isEmpty ? (
                                <div className="flex items-center gap-1 truncate"><AlertTriangle className="w-3 h-3 shrink-0" /><span>Missing</span></div>
                              ) : (
                                <div className="flex items-center justify-between w-full truncate">
                                  <span>{val}</span>
                                  <Edit2 className="w-2.5 h-2.5 opacity-0 group-hover:opacity-50 shrink-0" />
                                </div>
                              )}
                            </button>
                          )}
                        </td>
                      );
                    })}

                    {/* Units columns */}
                    <td className="px-3 py-2.5">{unitOuterBadge(row[unitsOuterIdx])}</td>
                     <td className="px-3 py-2.5 text-slate-400 font-mono text-xs overflow-hidden truncate">{row[COLUMNS.OUTER_W] ?? '-'}</td>
                     <td className="px-3 py-2.5 text-slate-400 font-mono text-xs overflow-hidden truncate">{row[COLUMNS.OUTER_L] ?? '-'}</td>
                     <td className="px-3 py-2.5 text-slate-400 font-mono text-xs overflow-hidden truncate">{row[COLUMNS.OUTER_H] ?? '-'}</td>

                    {/* Container units columns */}
                    {containerCols.map(col => (
                      <td key={col.index} className="px-3 py-2.5 overflow-hidden truncate">
                        {unitBadge(row[col.index], col.name)}
                      </td>
                    ))}

                    {/* Issues column (weight only) */}
                    <td className="px-3 py-2 overflow-hidden">
                      {(() => {
                        const weightError = unitErrors.find(e => e.startsWith('NW'));
                        return weightError ? (
                          <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold bg-red-500/15 text-red-400 border border-red-500/30 whitespace-nowrap">
                            <AlertCircle className="w-3 h-3 shrink-0" />{weightError}
                          </span>
                        ) : (
                          <span className="text-slate-600 text-xs">—</span>
                        );
                      })()}
                    </td>

                    {/* Check Column (Validated + Note) */}
                    <td className="px-3 py-2.5">
                      <div className="flex items-center gap-2">
                        <input
                          type="checkbox"
                          checked={isValidated}
                          onChange={(e) => handleToggleCheck(dataIndex, e.target.checked)}
                          className="w-4 h-4 rounded border-slate-600 bg-slate-900 text-blue-600 focus:ring-blue-500 focus:ring-offset-slate-800 cursor-pointer"
                        />
                        <div className="relative group">
                          <button
                            onClick={() => setNoteEditor({ rowIndex: dataIndex, text: note })}
                            className={cn(
                              "p-1.5 rounded-md transition-all shrink-0",
                              note 
                                ? "bg-amber-500/10 text-amber-400 border border-amber-500/20 hover:bg-amber-500/20" 
                                : "text-slate-500 hover:text-slate-300 hover:bg-slate-700/50"
                            )}
                          >
                            <MessageSquare className={cn("w-3.5 h-3.5", note && "fill-amber-400/20")} />
                          </button>
                          {note && (
                            <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-48 p-2 bg-amber-900/90 border border-amber-500/50 rounded text-xs text-white shadow-lg z-50 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none">
                              {note}
                            </div>
                          )}
                        </div>
                      </div>
                    </td>

                    {/* Matrix columns cells */}
                    {matrixCols.map(col => (
                      <td key={col.index} className="px-3 py-2.5 text-slate-500 text-xs max-w-[150px] truncate" title={String(row[col.index] || '')}>
                        {row[col.index] ?? '—'}
                      </td>
                    ))}

                    <td className={cn(
                      "px-2 py-2.5 sticky right-0 shadow-[-4px_0_8px_rgba(0,0,0,0.1)] transition-colors",
                      isValidated ? "bg-[#1b4d24]" : "bg-slate-800",
                      "group-hover:bg-slate-700/40"
                    )}>
                      <button
                        onClick={() => onEdit(dataIndex)}
                        className="p-1.5 text-slate-500 hover:text-slate-200 hover:bg-slate-700 rounded transition-colors"
                      >
                        <Edit2 className="w-3.5 h-3.5" />
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>

      {/* ── Footer count & Pagination ── */}
      <div className="flex items-center justify-between">
        <p className="text-xs text-slate-500 pb-1">
          Showing {paginatedRows.length} of {sortedRows.length} products {totalPages > 1 && `(${currentPage}/${totalPages})`}
          {pricingEditableCols.length > 0 && (
            <> · Click any <span className="text-blue-400">price cell</span> to edit inline</>
          )}
        </p>
        {totalPages > 1 && (
          <div className="flex items-center gap-1">
            <button
              onClick={() => setCurrentPage(1)}
              disabled={currentPage === 1}
              className="px-2 py-1 text-xs bg-slate-800 hover:bg-slate-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
            >
              ««
            </button>
            <button
              onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
              disabled={currentPage === 1}
              className="px-2 py-1 text-xs bg-slate-800 hover:bg-slate-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
            >
              «
            </button>
            <span className="text-xs text-slate-400 px-2">
              {currentPage} / {totalPages}
            </span>
            <button
              onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
              disabled={currentPage === totalPages}
              className="px-2 py-1 text-xs bg-slate-800 hover:bg-slate-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
            >
              »
            </button>
            <button
              onClick={() => setCurrentPage(totalPages)}
              disabled={currentPage === totalPages}
              className="px-2 py-1 text-xs bg-slate-800 hover:bg-slate-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
            >
              »»
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

// ── Text filter popover ───────────────────────────────────────────────────────
function TextFilterPopover({ value, onChange, onClose }: {
  value: string;
  onChange: (v: string) => void;
  onClose: () => void;
}) {
  return (
    <div className="absolute top-full left-0 mt-1 w-56 bg-slate-800 border border-slate-700 rounded-lg shadow-2xl z-50 p-3 flex flex-col gap-3 animate-in fade-in zoom-in-95 duration-100">
      <div className="relative">
        <Search className="absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-slate-500" />
        <input
          type="text"
          placeholder="Search article name…"
          value={value}
          onChange={e => onChange(e.target.value)}
          autoFocus
          className="w-full bg-slate-900 border border-slate-700 rounded p-1.5 pl-8 text-xs text-white focus:outline-none focus:border-blue-500"
        />
      </div>
      <div className="flex items-center justify-between pt-1 border-t border-slate-700">
        <button onClick={() => { onChange(''); onClose(); }} className="text-[10px] font-medium text-slate-400 hover:text-white transition-colors">Clear</button>
        <button onClick={onClose} className="px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white text-[10px] font-bold rounded transition-colors">OK</button>
      </div>
    </div>
  );
}

// ── Sort Icon Helper ───────────────────────────────────────────────────
function SortIcon({ current }: { current: 'asc' | 'desc' | null }) {
  return (
    <span className="inline-flex flex-col ml-1">
      <ChevronDown className={cn(
        "w-2.5 h-2.5 -mb-0.5 transition-colors",
        current === 'asc' ? "text-blue-400 rotate-180" : "text-slate-600 group-hover:text-slate-400"
      )} />
      <ChevronDown className={cn(
        "w-2.5 h-2.5 transition-colors",
        current === 'desc' ? "text-blue-400" : "text-slate-600 group-hover:text-slate-400"
      )} />
    </span>
  );
}

// ── Resize Handle Component ─────────────────────────────────────────────
function ResizeHandle({ onMouseDown }: { onMouseDown: (e: React.MouseEvent) => void }) {
  return (
    <div 
      onMouseDown={onMouseDown}
      onClick={e => e.stopPropagation()}
      className="absolute right-0 top-0 bottom-0 w-1.5 hover:bg-blue-500/50 cursor-col-resize group/resizer flex items-center justify-center z-20"
      title="Drag to resize"
    >
      <div className="w-[1px] h-4 bg-slate-700 group-hover/resizer:bg-blue-400 transition-colors" />
    </div>
  );
}

// ── Stat card ─────────────────────────────────────────────────────────────────
function StatCard({
  label,
  value,
  icon,
  color,
}: {
  label: string;
  value: number;
  icon: React.ReactNode;
  color: 'slate' | 'amber' | 'red' | 'emerald';
}) {
  const colors = {
    slate:   { bg: 'bg-slate-800',   border: 'border-slate-700',   text: 'text-slate-200',   icon: 'text-slate-400' },
    amber:   { bg: 'bg-amber-950/30', border: 'border-amber-700/40', text: 'text-amber-300',  icon: 'text-amber-500' },
    red:     { bg: 'bg-red-950/30',   border: 'border-red-700/40',   text: 'text-red-300',    icon: 'text-red-500' },
    emerald: { bg: 'bg-emerald-950/20', border: 'border-emerald-700/30', text: 'text-emerald-300', icon: 'text-emerald-500' },
  };
  const c = colors[color];
  return (
    <div className={cn('rounded-xl border p-4 flex items-center gap-4', c.bg, c.border)}>
      <span className={c.icon}>{icon}</span>
      <div>
        <p className={cn('text-2xl font-bold', c.text)}>{value}</p>
        <p className="text-xs text-slate-400">{label}</p>
      </div>
    </div>
  );
}
