/* global React, Icons, Toggle, JSZip, XLSX */
/* Creator Connections page — import CC exports + browse/filter campaign database */
const { useState, useEffect, useRef, useCallback } = React;

// ── Constants ────────────────────────────────────────────────────────────────
const CC_STORAGE_KEY = 'aip_cc_import';
const DB_NAME        = 'aip_db';
const STORE_NAME     = 'cc_records';
const DB_VERSION     = 2;
const PAGE_SIZE      = 200;

// ── Column definitions ────────────────────────────────────────────────────────
const CC_COLS_KEY = 'aip_cc_cols';
const CC_COLUMNS = [
  { key: 'asin',            label: 'ASIN' },
  { key: 'brandName',       label: 'Brand' },
  { key: 'campaignName',    label: 'Campaign Name' },
  { key: 'commission',      label: 'Commission' },
  { key: 'budgetRemaining', label: 'Budget Remaining' },
  { key: 'budget',          label: 'Total Budget' },
  { key: 'totalSlot',       label: 'Total Slots' },
  { key: 'availableSlot',   label: 'Avail. Slots' },
  { key: 'recommended',     label: 'Recommended' },
  { key: 'startDate',       label: 'Start Date' },
  { key: 'endDate',         label: 'End Date' },
  { key: 'campaignId',      label: 'Campaign ID' },
];
const CC_DEFAULT_ORDER  = CC_COLUMNS.map(c => c.key);
const CC_DEFAULT_HIDDEN = new Set(['budget', 'startDate', 'campaignId']);

function loadCCCols() {
  try {
    const s = localStorage.getItem(CC_COLS_KEY);
    if (s) { const { order, hidden } = JSON.parse(s); return { order, hidden: new Set(hidden) }; }
  } catch (_) {}
  return { order: CC_DEFAULT_ORDER, hidden: new Set(CC_DEFAULT_HIDDEN) };
}

// ── IDB helpers ──────────────────────────────────────────────────────────────

function openCCDB() {
  return new Promise((resolve, reject) => {
    const req = indexedDB.open(DB_NAME, DB_VERSION);
    req.onupgradeneeded = e => {
      const db = e.target.result;
      let store;
      if (e.oldVersion < 1) {
        store = db.createObjectStore(STORE_NAME, { keyPath: 'asin' });
      } else {
        store = e.target.transaction.objectStore(STORE_NAME);
      }
      if (!store.indexNames.contains('commission')) {
        store.createIndex('commission', 'commission', { unique: false });
      }
    };
    req.onsuccess = e => resolve(e.target.result);
    req.onerror   = e => reject(e.target.error);
  });
}

// ── Inline query worker (avoids file-serving / caching issues) ───────────────
const _CC_WORKER_SRC = `
const DB_NAME    = 'aip_db';
const STORE_NAME = 'cc_records';
const DB_VERSION = 2;
const PAGE_SIZE  = 200;

self.onmessage = function ({ data: msg }) {
  if (msg.type !== 'query') return;
  var filters = msg.filters;
  var openReq = indexedDB.open(DB_NAME, DB_VERSION);

  openReq.onupgradeneeded = function (e) {
    var db = e.target.result;
    var store;
    if (e.oldVersion < 1) {
      store = db.createObjectStore(STORE_NAME, { keyPath: 'asin' });
    } else {
      store = e.target.transaction.objectStore(STORE_NAME);
    }
    if (!store.indexNames.contains('commission')) {
      store.createIndex('commission', 'commission', { unique: false });
    }
  };

  openReq.onerror = function (e) {
    self.postMessage({ type: 'error', message: 'DB open failed: ' + e.target.error });
  };

  openReq.onsuccess = function (e) {
    var db      = e.target.result;
    var minComm = (parseFloat(filters.minCommission) || 0) / 100;
    var brandQ  = (filters.brand || '').toLowerCase().trim();
    var results = [];
    var tx, store, cursorReq;

    try {
      tx    = db.transaction(STORE_NAME, 'readonly');
      store = tx.objectStore(STORE_NAME);
    } catch (err) {
      self.postMessage({ type: 'error', message: 'Transaction failed: ' + err });
      return;
    }

    try {
      var idx   = store.index('commission');
      var range = minComm > 0 ? IDBKeyRange.lowerBound(minComm) : null;
      cursorReq = idx.openCursor(range, 'prev');
    } catch (_) {
      cursorReq = store.openCursor();
    }

    cursorReq.onerror = function () {
      self.postMessage({ type: 'error', message: 'Cursor failed' });
    };

    cursorReq.onsuccess = function (e) {
      var cursor = e.target.result;
      if (!cursor || results.length >= PAGE_SIZE) {
        self.postMessage({ type: 'results', results: results, hitLimit: results.length >= PAGE_SIZE });
        return;
      }
      var r  = cursor.value;
      var ok =
        (!brandQ || (r.brandName || '').toLowerCase().indexOf(brandQ) !== -1) &&
        (!filters.minBudget || (r.budgetRemaining || 0) >= +filters.minBudget) &&
        (filters.recommended === '' ||
          (filters.recommended === 'true'  && r.recommended === true) ||
          (filters.recommended === 'false' && r.recommended !== true)) &&
        (!filters.endDateFrom || (r.endDate || '') >= filters.endDateFrom) &&
        (!filters.endDateTo   || (r.endDate || '') <= filters.endDateTo);
      if (ok) results.push(r);
      cursor.continue();
    };
  };
};
`;
const _CC_WORKER_URL = URL.createObjectURL(new Blob([_CC_WORKER_SRC], { type: 'application/javascript' }));

// ── Import helpers ────────────────────────────────────────────────────────────

function saveCCMeta(meta) { localStorage.setItem(CC_STORAGE_KEY, JSON.stringify(meta)); }

function clearCCData() {
  localStorage.removeItem(CC_STORAGE_KEY);
  openCCDB().then(db => {
    db.transaction(STORE_NAME, 'readwrite').objectStore(STORE_NAME).clear();
  }).catch(() => {});
}

// ── Formatters ────────────────────────────────────────────────────────────────

const fmtPct  = n  => n != null ? (n * 100).toFixed(1) + '%' : '—';
const fmtUSD  = n  => n > 0 ? '$' + Number(n).toLocaleString() : '—';
const fmtDate = s  => s || '—';
const fmtNum  = n  => n > 0 ? Number(n).toLocaleString() : '—';

// ── Shared input styles ───────────────────────────────────────────────────────

const labelSt = {
  fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase',
  letterSpacing: '0.06em', marginBottom: 4, display: 'block',
};
const inputSt = {
  width: '100%', padding: '7px 10px',
  background: 'var(--bg-1)', border: '1px solid var(--line-strong)',
  borderRadius: 8, color: 'var(--text-1)', fontSize: 13, boxSizing: 'border-box',
};

// ── DropZone ──────────────────────────────────────────────────────────────────

function DropZone({ onFiles, disabled }) {
  const [over, setOver] = useState(false);
  const inputRef = useRef();
  const handle = useCallback(files => {
    if (!files.length || disabled) return;
    onFiles(Array.from(files));
  }, [onFiles, disabled]);

  return (
    <div
      onClick={() => !disabled && inputRef.current?.click()}
      onDragOver={e => { e.preventDefault(); setOver(true); }}
      onDragLeave={() => setOver(false)}
      onDrop={e => { e.preventDefault(); setOver(false); handle(e.dataTransfer.files); }}
      style={{
        border: `2px dashed ${over ? 'var(--accent)' : 'var(--line-strong)'}`,
        borderRadius: 12, padding: '36px 24px', textAlign: 'center',
        cursor: disabled ? 'not-allowed' : 'pointer',
        background: over ? 'var(--accent-soft)' : 'transparent',
        transition: 'all 0.15s', opacity: disabled ? 0.5 : 1,
      }}
    >
      <input
        ref={inputRef} type="file" accept=".xlsx,.zip,.csv"
        multiple style={{ display: 'none' }}
        onChange={e => handle(e.target.files)}
      />
      <Icons.download size={22} style={{ color: 'var(--accent)', marginBottom: 10 }}/>
      <div style={{ fontWeight: 600, fontSize: 14 }}>Drop CC export files here</div>
      <div style={{ color: 'var(--text-2)', fontSize: 12, marginTop: 4 }}>
        Accepts .xlsx or .zip — multiple files OK
      </div>
      <div style={{ marginTop: 14 }}>
        <span style={{ padding: '5px 14px', border: '1px solid var(--line-strong)', borderRadius: 8, fontSize: 12, color: 'var(--text-2)' }}>
          Browse files
        </span>
      </div>
    </div>
  );
}

// ── Column drawer ─────────────────────────────────────────────────────────────

function CCColumnsDrawer({ order, setOrder, hidden, setHidden, onClose }) {
  const toggle = (key) => setHidden(prev => {
    const n = new Set(prev);
    if (n.has(key)) n.delete(key); else n.add(key);
    return n;
  });

  const reorder = (from, to) => {
    setOrder(prev => {
      const next = [...prev];
      const [m] = next.splice(from, 1);
      next.splice(to, 0, m);
      return next;
    });
  };

  const reset = () => { setOrder(CC_DEFAULT_ORDER); setHidden(new Set(CC_DEFAULT_HIDDEN)); };

  const items = order.map(key => ({ key, label: CC_COLUMNS.find(c => c.key === key)?.label || key }));

  return (
    <>
      <div className="drawer-backdrop" onClick={onClose}/>
      <div className="drawer">
        <div style={{ padding: 20, borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 16, fontWeight: 700, letterSpacing: '-0.3px' }}>Manage columns</div>
            <div style={{ fontSize: 12, color: 'var(--text-2)', marginTop: 2 }}>Drag to reorder · toggle visibility</div>
          </div>
          <button className="icon-btn" onClick={onClose}><Icons.close size={14}/></button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: 16 }}>
          <ReorderableList
            items={items}
            onReorder={reorder}
            renderItem={(it) => (
              <div style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '9px 12px', borderRadius: 8,
                background: 'var(--bg-2)', marginBottom: 4,
                border: '1px solid var(--line)', cursor: 'grab',
              }}>
                <Icons.drag size={14} style={{ color: 'var(--text-3)', flexShrink: 0 }}/>
                <span style={{ flex: 1, fontSize: 13 }}>{it.label}</span>
                <Toggle on={!hidden.has(it.key)} onChange={() => toggle(it.key)} />
              </div>
            )}
          />
        </div>
        <div style={{ padding: 16, borderTop: '1px solid var(--line)', display: 'flex', gap: 10 }}>
          <button className="btn" style={{ flex: 1, justifyContent: 'center' }} onClick={reset}>Reset</button>
          <button className="btn btn-primary" style={{ flex: 1, justifyContent: 'center' }} onClick={onClose}>Done</button>
        </div>
      </div>
    </>
  );
}

// ── Cell renderer ─────────────────────────────────────────────────────────────

function renderCCCell(key, r) {
  switch (key) {
    case 'asin':         return <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--accent)', whiteSpace: 'nowrap' }}>{r.asin}</span>;
    case 'brandName':    return <span style={{ whiteSpace: 'nowrap' }}>{r.brandName || '—'}</span>;
    case 'campaignName': return <span style={{ color: 'var(--text-2)', maxWidth: 220, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', display: 'block' }} title={r.campaignName}>{r.campaignName || '—'}</span>;
    case 'commission':   return <span style={{ fontWeight: 600 }}>{fmtPct(r.commission)}</span>;
    case 'budgetRemaining': return <span style={{ color: 'var(--text-2)' }}>{fmtUSD(r.budgetRemaining)}</span>;
    case 'budget':       return <span style={{ color: 'var(--text-2)' }}>{fmtUSD(r.budget)}</span>;
    case 'totalSlot':    return <span style={{ color: 'var(--text-2)' }}>{fmtNum(r.totalSlot)}</span>;
    case 'availableSlot':return <span style={{ color: 'var(--text-2)' }}>{fmtNum(r.availableSlot)}</span>;
    case 'recommended':  return r.recommended === true
      ? <span className="badge badge-success" style={{ fontSize: 11 }}>Yes</span>
      : <span style={{ color: 'var(--text-3)' }}>No</span>;
    case 'startDate':    return <span style={{ color: 'var(--text-2)', whiteSpace: 'nowrap' }}>{fmtDate(r.startDate)}</span>;
    case 'endDate':      return <span style={{ color: 'var(--text-2)', whiteSpace: 'nowrap' }}>{fmtDate(r.endDate)}</span>;
    case 'campaignId':   return <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text-3)', fontSize: 11 }}>{r.campaignId || '—'}</span>;
    default:             return null;
  }
}

// ── Main Page ─────────────────────────────────────────────────────────────────

const ConnectionsPage = ({ stored, setStored, status, setStatus }) => {
  const processing = status && status.phase !== 'error' && status.phase !== 'done';
  const [showDrop, setShowDrop] = useState(false);

  // Filter state
  const [filters, setFilters] = useState({
    brand: '', minCommission: 0, minBudget: 0,
    recommended: '', endDateFrom: '', endDateTo: '',
  });
  const filtersRef = useRef(filters);
  filtersRef.current = filters;

  // Results state
  const [results,  setResults]  = useState([]);
  const [loading,  setLoading]  = useState(false);
  const [hitLimit, setHitLimit] = useState(false);

  const workerRef = useRef(null);

  // Column visibility + order state
  const _initCols = loadCCCols();
  const [colOrder,  setColOrder]  = useState(_initCols.order);
  const [colHidden, setColHidden] = useState(_initCols.hidden);
  const [showColDrawer, setShowColDrawer] = useState(false);
  const visibleCols = colOrder.filter(k => !colHidden.has(k));

  useEffect(() => {
    try { localStorage.setItem(CC_COLS_KEY, JSON.stringify({ order: colOrder, hidden: [...colHidden] })); } catch (_) {}
  }, [colOrder, colHidden]);

  // Terminate worker on unmount
  useEffect(() => () => { workerRef.current?.terminate(); }, []);

  // Query on mount if data already exists
  useEffect(() => {
    if (stored) doQuery();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  // Re-query on filter change (debounced)
  useEffect(() => {
    if (!stored) return;
    const t = setTimeout(doQuery, 300);
    return () => clearTimeout(t);
  }, [filters]); // eslint-disable-line react-hooks/exhaustive-deps

  // Re-query when import completes (stored flips from null → object)
  useEffect(() => {
    if (!stored) { setResults([]); return; }
    setTimeout(doQuery, 200);
  }, [stored]); // eslint-disable-line react-hooks/exhaustive-deps

  function doQuery() {
    // Terminate any in-flight worker before starting a fresh one
    if (workerRef.current) {
      workerRef.current.terminate();
      workerRef.current = null;
    }

    const worker = new Worker(_CC_WORKER_URL);
    workerRef.current = worker;
    setLoading(true);

    worker.onmessage = ({ data: msg }) => {
      console.log('[CC worker] message received:', msg.type, msg.type === 'results' ? msg.results.length + ' results' : msg.message);
      // Free the worker as soon as we have results
      worker.terminate();
      if (workerRef.current === worker) workerRef.current = null;

      if (msg.type === 'results') {
        setResults(msg.results);
        setHitLimit(msg.hitLimit);
      }
      setLoading(false);
    };

    worker.onerror = (err) => {
      console.error('[CC worker] onerror:', err.message, err);
      worker.terminate();
      if (workerRef.current === worker) workerRef.current = null;
      setLoading(false);
    };

    worker.postMessage({ type: 'query', filters: filtersRef.current });
  }

  // ── File import ────────────────────────────────────────────────────────────

  function processFiles(files) {
    setStatus({
      phase: 'parsing', current: 0, total: files.length,
      rowsProcessed: 0, uniqueAsins: 0, fileLabel: '',
    });

    Promise.all(files.map(f => f.arrayBuffer().then(buf => ({ name: f.name, buffer: buf }))))
      .then(fileData => {
        const worker = new Worker('/lib/import-worker.js');

        worker.onmessage = ({ data: msg }) => {
          if (msg.type === 'progress') {
            setStatus(s => msg.phase === 'saving'
              ? { phase: 'saving', saved: msg.saved, totalAsins: msg.totalAsins }
              : { ...s, phase: 'parsing', ...msg });

          } else if (msg.type === 'done') {
            worker.terminate();
            const meta = { ...msg.metadata, importedAt: Date.now(), fileCount: files.length };
            saveCCMeta(meta);
            setStored(meta);
            setStatus({ phase: 'done' });
            setShowDrop(false);
            window.dispatchEvent(new CustomEvent('aip:importDone'));

          } else if (msg.type === 'error') {
            worker.terminate();
            setStatus({ phase: 'error', error: msg.message || 'Worker error' });
          }
        };

        worker.onerror = err => {
          worker.terminate();
          setStatus({ phase: 'error', error: err.message || 'Worker crashed' });
        };

        worker.postMessage({ files: fileData }, fileData.map(f => f.buffer));
      })
      .catch(err => setStatus({ phase: 'error', error: err.message }));
  }

  function handleClear() {
    clearCCData();
    setStored(null);
    setStatus(null);
    setResults([]);
  }

  const sf = (k, v) => setFilters(f => ({ ...f, [k]: v }));

  const resetFilters = () => setFilters({
    brand: '', minCommission: 0, minBudget: 0,
    recommended: '', endDateFrom: '', endDateTo: '',
  });

  // ── Render ─────────────────────────────────────────────────────────────────

  return (
    <div className="page">

      {/* Header */}
      <div className="page-header">
        <div className="page-title-block">
          <h1>Creator Connections</h1>
          <div className="subtitle">
            {stored
              ? `${stored.totalAsins.toLocaleString()} ASINs · ${stored.totalBrands.toLocaleString()} brands`
              : 'Import your CC export to browse campaigns.'}
          </div>
        </div>
        {stored && !processing && (
          <div className="page-actions">
            <button className="btn btn-ghost" onClick={handleClear}>Clear data</button>
            <button className="btn btn-ghost" onClick={() => setShowDrop(v => !v)}>
              <Icons.upload size={13}/> Re-import
            </button>
          </div>
        )}
      </div>

      {/* ── Import: no data yet ── */}
      {!stored && !processing && (
        <div className="card" style={{ padding: 28, marginBottom: 20 }}>
          <DropZone onFiles={processFiles} disabled={false} />
          <div style={{ marginTop: 16, padding: '12px 16px', background: 'var(--bg-1)', borderRadius: 10, fontSize: 12, color: 'var(--text-2)', lineHeight: 1.7 }}>
            <strong style={{ color: 'var(--text-1)' }}>How to export:</strong> Go to Creator Connections on Amazon → any campaign view → click <em>Download</em>. Upload multiple .xlsx files at once.
          </div>
        </div>
      )}

      {/* ── Import: re-import drop zone ── */}
      {stored && showDrop && !processing && (
        <div className="card" style={{ padding: 24, marginBottom: 20 }}>
          <DropZone onFiles={processFiles} disabled={false} />
        </div>
      )}

      {/* ── Import: compact stats bar ── */}
      {stored && !showDrop && !processing && (
        <div className="card" style={{ padding: '14px 22px', marginBottom: 20, display: 'flex', gap: 28, alignItems: 'center', flexWrap: 'wrap' }}>
          {[
            { label: 'Unique ASINs',   value: stored.totalAsins.toLocaleString() },
            { label: 'Brands',         value: stored.totalBrands.toLocaleString() },
            { label: 'Avg Commission', value: stored.avgCommission ? (stored.avgCommission * 100).toFixed(1) + '%' : '—' },
            { label: 'Max Commission', value: stored.maxCommission ? (stored.maxCommission * 100).toFixed(1) + '%' : '—' },
          ].map(({ label, value }) => (
            <div key={label}>
              <div style={{ fontSize: 10, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 2 }}>{label}</div>
              <div className="num" style={{ fontWeight: 700, fontSize: 17 }}>{value}</div>
            </div>
          ))}
          <div style={{ marginLeft: 'auto', fontSize: 12, color: 'var(--text-3)', textAlign: 'right' }}>
            <div>Imported {new Date(stored.importedAt).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}</div>
            <div>{new Date(stored.importedAt).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })}</div>
          </div>
        </div>
      )}

      {/* ── Import: progress ── */}
      {processing && (
        <div className="card" style={{ padding: 40, textAlign: 'center', marginBottom: 20 }}>
          <div style={{
            width: 44, height: 44, borderRadius: 11,
            background: 'var(--accent-soft)', color: 'var(--accent)',
            display: 'grid', placeItems: 'center', margin: '0 auto 14px',
            animation: 'spin 1s linear infinite',
          }}>
            <Icons.bolt size={20}/>
          </div>
          <div style={{ fontWeight: 600 }}>
            {status.phase === 'saving'
              ? 'Saving to database…'
              : `Parsing file ${status.current} of ${status.total}${status.fileLabel ? ' — ' + status.fileLabel : ''}`}
          </div>
          {status.phase === 'parsing' && (
            <div style={{ color: 'var(--accent)', fontSize: 13, fontFamily: 'var(--font-mono)', marginTop: 6 }}>
              {(status.rowsProcessed || 0).toLocaleString()} rows · {(status.uniqueAsins || 0).toLocaleString()} unique ASINs
            </div>
          )}
          {status.phase === 'saving' && status.totalAsins > 0 && (() => {
            const pct = Math.round((status.saved / status.totalAsins) * 100);
            return (
              <div style={{ margin: '14px auto 0', width: '100%', maxWidth: 320 }}>
                <div style={{ height: 5, borderRadius: 3, background: 'var(--line-strong)', overflow: 'hidden' }}>
                  <div style={{ height: '100%', borderRadius: 3, background: 'var(--accent)', width: pct + '%', transition: 'width 0.3s' }}/>
                </div>
                <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 4, fontFamily: 'var(--font-mono)' }}>{pct}%</div>
              </div>
            );
          })()}
          <div style={{ color: 'var(--text-3)', fontSize: 12, marginTop: 10 }}>
            Large files take a minute — you can navigate away, the import continues in the background.
          </div>
        </div>
      )}

      {/* ── Import: error ── */}
      {status?.phase === 'error' && (
        <div className="card" style={{ padding: 20, borderColor: 'var(--danger)', background: 'color-mix(in srgb, var(--danger) 8%, var(--bg-1))', marginBottom: 20 }}>
          <div style={{ fontWeight: 600, color: 'var(--danger)' }}>Import failed</div>
          <div style={{ fontSize: 13, color: 'var(--text-2)', marginTop: 4 }}>{status.error}</div>
          <button className="btn btn-ghost" style={{ marginTop: 10 }} onClick={() => setStatus(null)}>Try again</button>
        </div>
      )}

      {/* ── Filters ── */}
      {stored && !processing && (
        <div className="card" style={{ padding: '14px 18px', marginBottom: 16 }}>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'flex-end' }}>

            <div style={{ flex: '1 1 160px', minWidth: 130 }}>
              <label style={labelSt}>Brand</label>
              <input
                type="text" placeholder="Search brand…" value={filters.brand}
                onChange={e => sf('brand', e.target.value)} style={inputSt}
              />
            </div>

            <div style={{ flex: '0 0 140px' }}>
              <label style={labelSt}>Min Commission %</label>
              <input
                type="number" min="0" max="100" step="0.5"
                value={filters.minCommission}
                onChange={e => sf('minCommission', e.target.value)} style={inputSt}
              />
            </div>

            <div style={{ flex: '0 0 160px' }}>
              <label style={labelSt}>Min Budget Remaining</label>
              <input
                type="number" min="0" step="100"
                value={filters.minBudget}
                onChange={e => sf('minBudget', e.target.value)} style={inputSt}
              />
            </div>

            <div style={{ flex: '0 0 130px' }}>
              <label style={labelSt}>Recommended</label>
              <select value={filters.recommended} onChange={e => sf('recommended', e.target.value)} style={inputSt}>
                <option value="">All</option>
                <option value="true">Yes</option>
                <option value="false">No</option>
              </select>
            </div>

            <div style={{ flex: '0 0 145px' }}>
              <label style={labelSt}>End Date From</label>
              <input
                type="date" value={filters.endDateFrom}
                onChange={e => sf('endDateFrom', e.target.value)} style={inputSt}
              />
            </div>

            <div style={{ flex: '0 0 145px' }}>
              <label style={labelSt}>End Date To</label>
              <input
                type="date" value={filters.endDateTo}
                onChange={e => sf('endDateTo', e.target.value)} style={inputSt}
              />
            </div>

            <button className="btn btn-ghost" onClick={resetFilters} title="Reset filters">
              <Icons.reset size={13}/> Reset
            </button>
          </div>
        </div>
      )}

      {/* ── Results table ── */}
      {stored && !processing && (
        <div className="card" style={{ overflow: 'hidden' }}>

          {/* Table header bar */}
          <div style={{ padding: '12px 18px', borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center', gap: 10 }}>
            <div style={{ fontWeight: 600, fontSize: 13 }}>Campaigns</div>
            <div style={{ fontSize: 12, color: 'var(--text-3)' }}>
              {loading
                ? 'Searching…'
                : hitLimit
                  ? `Top ${PAGE_SIZE} by commission`
                  : `${results.length.toLocaleString()} result${results.length !== 1 ? 's' : ''}`}
            </div>
            {loading && (
              <div style={{
                width: 13, height: 13, borderRadius: '50%',
                border: '2px solid var(--accent)', borderTopColor: 'transparent',
                animation: 'spin 0.7s linear infinite', flexShrink: 0,
              }}/>
            )}
            <div style={{ marginLeft: 'auto' }}>
              <button className="btn btn-ghost btn-sm" onClick={() => setShowColDrawer(true)}>
                <Icons.columns size={13}/> Manage columns
              </button>
            </div>
          </div>

          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--line)' }}>
                  {visibleCols.map(key => {
                    const col = CC_COLUMNS.find(c => c.key === key);
                    return (
                      <th key={key} style={{ padding: '9px 14px', textAlign: 'left', fontWeight: 600, color: 'var(--text-2)', whiteSpace: 'nowrap', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.05em' }}>
                        {col?.label}
                      </th>
                    );
                  })}
                </tr>
              </thead>
              <tbody>
                {results.map((r, i) => (
                  <tr key={r.asin} style={{ borderBottom: '1px solid var(--line)', background: i % 2 === 0 ? 'transparent' : 'var(--bg-0)' }}>
                    {visibleCols.map(key => (
                      <td key={key} style={{ padding: '8px 14px' }}>
                        {renderCCCell(key, r)}
                      </td>
                    ))}
                  </tr>
                ))}
                {!loading && results.length === 0 && (
                  <tr>
                    <td colSpan={visibleCols.length} style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)' }}>
                      No results match your filters.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>

          {hitLimit && (
            <div style={{ padding: '10px 18px', borderTop: '1px solid var(--line)', fontSize: 12, color: 'var(--text-3)' }}>
              Showing top {PAGE_SIZE} by commission. Narrow your filters to see more specific results.
            </div>
          )}
        </div>
      )}

      {showColDrawer && (
        <CCColumnsDrawer
          order={colOrder} setOrder={setColOrder}
          hidden={colHidden} setHidden={setColHidden}
          onClose={() => setShowColDrawer(false)}
        />
      )}
    </div>
  );
};
