/* global React, Icons, parseCCWorkbook, XLSX, JSZip */
/* CC Spreadsheet Import page — drag-and-drop Excel files, parse, store in localStorage */
const { useCallback, useRef } = React;

const STORAGE_KEY = 'aip_cc_import';
const DB_NAME     = 'aip_db';
const STORE_NAME  = 'cc_records';

/* Metadata (small) stays in localStorage; records live in IndexedDB */
function saveImport(meta) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(meta));
}

function clearImport() {
  localStorage.removeItem(STORAGE_KEY);
  try {
    const req = indexedDB.open(DB_NAME, 1);
    req.onsuccess = e => {
      try { e.target.result.transaction(STORE_NAME, 'readwrite').objectStore(STORE_NAME).clear(); }
      catch (_) {}
    };
  } catch (_) {}
}

function fmtPct(n) { return n != null ? n.toFixed(1) + '%' : '—'; }
function fmtDate(s) { return s || '—'; }

/* ── Drop Zone ────────────────────────────────────────────────────── */
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: 14,
        padding: '52px 32px',
        textAlign: 'center',
        cursor: disabled ? 'not-allowed' : 'pointer',
        background: over ? 'var(--accent-soft)' : 'var(--bg-1)',
        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)}
      />
      <div style={{
        width: 48, height: 48, borderRadius: 12,
        background: 'var(--accent-soft)', color: 'var(--accent)',
        display: 'grid', placeItems: 'center', margin: '0 auto 16px',
      }}>
        <Icons.download size={22}/>
      </div>
      <div style={{ fontWeight: 600, fontSize: 15 }}>Drop your CC export files here</div>
      <div style={{ color: 'var(--text-2)', fontSize: 13, marginTop: 6 }}>
        Accepts .xlsx or .zip — multiple files OK
      </div>
      <div style={{ marginTop: 16 }}>
        <span style={{
          display: 'inline-block', padding: '6px 16px',
          border: '1px solid var(--line-strong)', borderRadius: 8,
          fontSize: 12, color: 'var(--text-2)',
        }}>
          Or click to browse
        </span>
      </div>
    </div>
  );
}

/* ── Stat Card ────────────────────────────────────────────────────── */
function StatCard({ label, value, sub }) {
  return (
    <div className="card" style={{ padding: '20px 24px' }}>
      <div style={{ fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>{label}</div>
      <div className="num" style={{ fontSize: 26, fontWeight: 700 }}>{value}</div>
      {sub && <div style={{ fontSize: 12, color: 'var(--text-2)', marginTop: 2 }}>{sub}</div>}
    </div>
  );
}

/* ── Main Page ────────────────────────────────────────────────────── */
const ImportPage = ({ stored, setStored, status, setStatus }) => {
  const processing = status && status.phase !== 'error' && status.phase !== 'done';

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

    // Read all files as ArrayBuffers on the main thread, then hand off to worker
    Promise.all(files.map(f => f.arrayBuffer().then(buffer => ({ name: f.name, buffer }))))
      .then(fileData => {
        const worker = new Worker('/lib/import-worker.js');

        worker.onmessage = function(e) {
          const msg = e.data;

          if (msg.type === 'progress') {
            // Worker sends phase:'saving' when writing IDB; otherwise treat as parsing
            if (msg.phase === 'saving') {
              setStatus({ phase: 'saving', saved: msg.saved, totalAsins: msg.totalAsins });
            } else {
              setStatus(s => ({ ...s, phase: 'parsing', ...msg }));
            }

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

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

        worker.onerror = function(e) {
          worker.terminate();
          setStatus({ phase: 'error', error: e.message || 'Worker crashed — check browser console for details' });
        };

        // Transfer buffers (zero-copy) to the worker
        const transfers = fileData.map(f => f.buffer);
        worker.postMessage({ files: fileData }, transfers);
      })
      .catch(err => setStatus({ phase: 'error', error: err.message || 'Failed to read files' }));
  }

  function handleClear() {
    clearImport();
    setStored(null);
    setStatus(null);
  }

  const statusMsg = status
    ? status.error ? '⚠ ' + status.error
    : status.phase === 'parsing' ? `File ${status.current} of ${status.total} — ${status.fileLabel || ''}${status.sheet ? ' · sheet: ' + status.sheet : ''}`
    : status.phase === 'saving' ? `Saving to database…`
    : null
    : null;

  const progressDetail = status && status.phase === 'parsing' ? (
    `${(status.rowsProcessed || 0).toLocaleString()} rows read · ${(status.uniqueAsins || 0).toLocaleString()} unique ASINs`
  ) : status && status.phase === 'saving' ? (
    `${(status.saved || 0).toLocaleString()} of ${(status.totalAsins || 0).toLocaleString()} ASINs written`
  ) : null;

  const savePct = status?.phase === 'saving' && status.totalAsins > 0
    ? Math.round((status.saved / status.totalAsins) * 100)
    : null;

  return (
    <div className="page">
      <div className="page-header">
        <div className="page-title-block">
          <h1>Import CC Data</h1>
          <div className="subtitle">Upload your Creator Connections export files to power the Search page.</div>
        </div>
        {stored && !processing && (
          <div className="page-actions">
            <button className="btn btn-ghost" onClick={handleClear}>Clear data</button>
            <button className="btn btn-primary" onClick={() => setStatus(null)}>
              <Icons.download size={13}/> Re-import
            </button>
          </div>
        )}
      </div>

      {/* Stats — shown when data is loaded */}
      {stored && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16, marginBottom: 24 }}>
          <StatCard
            label="Unique ASINs"
            value={stored.totalAsins.toLocaleString()}
            sub={`from ${stored.fileCount} file${stored.fileCount !== 1 ? 's' : ''}`}
          />
          <StatCard
            label="Brands"
            value={stored.totalBrands.toLocaleString()}
          />
          <StatCard
            label="Avg Commission"
            value={fmtPct(stored.avgCommission)}
            sub={`Max ${fmtPct(stored.maxCommission)}`}
          />
          <StatCard
            label="Last Imported"
            value={new Date(stored.importedAt).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}
            sub={new Date(stored.importedAt).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })}
          />
        </div>
      )}

      {/* Drop zone — shown when no data or re-importing */}
      {(!stored || status?.phase === 'done' === false) && !processing && (
        <div className="card" style={{ padding: 32 }}>
          <DropZone onFiles={processFiles} disabled={processing} />
          <div style={{ marginTop: 20, padding: '14px 18px', background: 'var(--bg-1)', borderRadius: 10, fontSize: 12, color: 'var(--text-2)', lineHeight: 1.7 }}>
            <strong style={{ color: 'var(--text-1)' }}>How to export from Amazon:</strong>
            &nbsp;Go to Creator Connections → any campaign view → click <em>Download</em> in the top right. You can upload multiple files at once.
          </div>
        </div>
      )}

      {/* Progress */}
      {processing && (
        <div className="card" style={{ padding: 48, textAlign: 'center' }}>
          <div style={{
            width: 48, height: 48, borderRadius: 12,
            background: 'var(--accent-soft)', color: 'var(--accent)',
            display: 'grid', placeItems: 'center', margin: '0 auto 16px',
            animation: 'spin 1s linear infinite',
          }}>
            <Icons.bolt size={22}/>
          </div>
          <div style={{ fontWeight: 600, fontSize: 15 }}>{statusMsg}</div>
          {progressDetail && (
            <div style={{ color: 'var(--accent)', fontSize: 13, fontFamily: 'var(--font-mono)', marginTop: 8, fontWeight: 600 }}>{progressDetail}</div>
          )}
          {savePct !== null && (
            <div style={{ margin: '14px auto 0', width: '100%', maxWidth: 360 }}>
              <div style={{ height: 6, borderRadius: 3, background: 'var(--line-strong)', overflow: 'hidden' }}>
                <div style={{
                  height: '100%', borderRadius: 3,
                  background: 'var(--accent)',
                  width: savePct + '%',
                  transition: 'width 0.4s ease',
                }}/>
              </div>
              <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 6, fontFamily: 'var(--font-mono)' }}>{savePct}%</div>
            </div>
          )}
          <div style={{ color: 'var(--text-3)', fontSize: 12, marginTop: 10 }}>Large files take a minute — stay on this page or navigate freely, import runs in the background.</div>
        </div>
      )}

      {/* Error */}
      {status?.phase === 'error' && (
        <div className="card" style={{ padding: 24, borderColor: 'var(--danger)', background: 'color-mix(in srgb, var(--danger) 8%, var(--bg-1))' }}>
          <div style={{ fontWeight: 600, color: 'var(--danger)' }}>Import failed</div>
          <div style={{ fontSize: 13, color: 'var(--text-2)', marginTop: 4 }}>{status.error || 'An unknown error occurred. Check the browser console for details.'}</div>
          <button className="btn btn-ghost" style={{ marginTop: 12 }} onClick={() => setStatus(null)}>Try again</button>
        </div>
      )}

      {/* Preview table */}
      {stored && !processing && (
        <div className="card" style={{ overflow: 'hidden' }}>
          <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div style={{ fontWeight: 600, fontSize: 13 }}>Preview — top ASINs by commission</div>
            <div style={{ fontSize: 12, color: 'var(--text-3)' }}>Showing 25 of {stored.totalAsins.toLocaleString()}</div>
          </div>
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
              <thead>
                <tr style={{ borderBottom: '1px solid var(--line)' }}>
                  {['ASIN','Brand','Commission','Budget Remaining','Campaign End','Available Slots'].map(h => (
                    <th key={h} style={{ padding: '10px 16px', textAlign: 'left', fontWeight: 600, color: 'var(--text-2)', whiteSpace: 'nowrap' }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {(stored.topRecords || []).map((r, i) => (
                    <tr key={r.asin} style={{ borderBottom: '1px solid var(--line)', background: i % 2 === 0 ? 'transparent' : 'var(--bg-0)' }}>
                      <td style={{ padding: '10px 16px', fontFamily: 'var(--font-mono)', color: 'var(--accent)' }}>{r.asin}</td>
                      <td style={{ padding: '10px 16px', color: 'var(--text-1)' }}>{r.brandName || '—'}</td>
                      <td style={{ padding: '10px 16px', fontWeight: 600 }}>{fmtPct(r.commission)}</td>
                      <td style={{ padding: '10px 16px', color: 'var(--text-2)' }}>{r.budgetRemaining ? '$' + r.budgetRemaining.toLocaleString() : '—'}</td>
                      <td style={{ padding: '10px 16px', color: 'var(--text-2)' }}>{fmtDate(r.endDate)}</td>
                      <td style={{ padding: '10px 16px', color: 'var(--text-2)' }}>{r.availableSlot || '—'}</td>
                    </tr>
                  ))
                }
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
};
