// export.jsx — print-optimized A4 document templates + preview overlay.
// Ported from the Alpha Dashboard prototype, adapted to the live backend shapes:
//  - condition mix handles 4 grades (A+/A/B/C) for the dashboard, 3 (A/B/C) for offers
//  - demand sparkline uses view.searchSeries (real Google Trends)
//  - model.tagline / model.released are optional (graceful fallback)
// Tax summary uses the VAT engine (vatInfo/vatNet/vatAmount/fmtRaw) from components.jsx.

const { useEffect: useEffectExp } = React;

function fmtDate(iso) {
  const d = iso ? new Date(iso) : new Date();
  return d.toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' });
}

// ── Reusable page chrome ──────────────────────────────────────────────────────
function Pg({ children, page, total, footer }) {
  return (
    <div className="pg">
      <div className="pg-inner">{children}</div>
      <div className="pg-footer">
        <span className="pg-foot-brand"><span className="pg-dot"></span> reuseit · index</span>
        <span className="pg-foot-mid">{footer}</span>
        <span>{page} / {total}</span>
      </div>
    </div>
  );
}

function DocHead({ eyebrow, title, sub }) {
  return (
    <header className="doc-head">
      <div className="doc-head-top">
        <div className="doc-brand"><span className="doc-brand-dot"></span>reuseit<span className="doc-brand-mark">/index</span></div>
        <div className="doc-eyebrow">{eyebrow}</div>
      </div>
      <h1 className="doc-title">{title}</h1>
      {sub && <div className="doc-sub">{sub}</div>}
    </header>
  );
}

// Condition mix bar. `g` may be {A+,A,B,C} (dashboard) or {A,B,C} (offers).
function condMix(g) {
  g = g || {};
  const hasAplus = g['A+'] != null;
  return (
    <div className="doc-cond">
      <div className="doc-cond-bar">
        {hasAplus && <span className="cm-seg cm-Aplus" style={{ width: (g['A+'] || 0) + '%' }}></span>}
        <span className="cm-seg cm-A" style={{ width: (g.A || 0) + '%' }}></span>
        <span className="cm-seg cm-B" style={{ width: (g.B || 0) + '%' }}></span>
        <span className="cm-seg cm-C" style={{ width: (g.C || 0) + '%' }}></span>
      </div>
      <div className="doc-cond-legend">
        {hasAplus && <span><i className="dot dot-Aplus"></i>Grade A+ {g['A+'] || 0}%</span>}
        <span><i className="dot dot-A"></i>Grade A {g.A || 0}%</span>
        <span><i className="dot dot-B"></i>Grade B {g.B || 0}%</span>
        <span><i className="dot dot-C"></i>Grade C {g.C || 0}%</span>
      </div>
    </div>
  );
}

function RangeBar({ low, high, median }) {
  const range = high - low || 1;
  const pct = Math.max(0, Math.min(100, ((median - low) / range) * 100));
  return (
    <div className="doc-range">
      <div className="doc-range-bar"><span className="doc-range-marker" style={{ left: pct + '%' }}></span></div>
      <div className="doc-range-row"><span>{fmtPrice(low)}</span><span className="doc-range-med">median {fmtPrice(median)}</span><span>{fmtPrice(high)}</span></div>
    </div>
  );
}

// ── Dashboard report (1 page) ─────────────────────────────────────────────────
function dashboardPages(req) {
  const { model, view, matched, range } = req;
  const series = view.series[range] || view.series.monthly;
  const facts = [
    ['Brand', model.brand],
    ['Released', model.released || '—'],
    ['Variants matched', view.count],
    ['Sellers', view.sellers],
    ['Listings (30d)', (view.listings || 0).toLocaleString()],
  ];
  const top = matched.slice().sort((a, b) => b.stats.median - a.stats.median).slice(0, 8);
  const hasSearch = Array.isArray(view.searchSeries) && view.searchSeries.length > 1;
  return [
    <Pg key="d1" page={1} total={1} footer={`Market report · ${fmtDate()}`}>
      <DocHead eyebrow={`Market report · ${fmtDate()}`} title={model.name} sub={`Price index · ${view.label} · prices ${vatMode() === 'excl' ? 'excl.' : 'incl.'} VAT`} />

      <div className="doc-hero">
        <div className="doc-hero-vis"><ProductGlyph product={model} size={120} tone="warm" /></div>
        <div className="doc-facts">
          {facts.map(([k, v]) => (
            <div key={k} className="doc-fact"><span className="doc-fact-k">{k}</span><span className="doc-fact-v">{v}</span></div>
          ))}
        </div>
      </div>

      <div className="doc-stats">
        <div className="doc-stat"><span className="doc-stat-k">Median</span><span className="doc-stat-v">{fmtPrice(view.stats.median)}</span></div>
        <div className="doc-stat"><span className="doc-stat-k">Lowest</span><span className="doc-stat-v">{fmtPrice(view.stats.lowest)}</span></div>
        <div className="doc-stat"><span className="doc-stat-k">Highest</span><span className="doc-stat-v">{fmtPrice(view.stats.highest)}</span></div>
        <div className="doc-stat"><span className="doc-stat-k">12-mo trend</span><span className="doc-stat-v"><Trend value={view.stats.trend} /></span></div>
      </div>

      <section className="doc-sec">
        <div className="doc-sec-h">Price history · median across sellers</div>
        <PriceChart series={series} range={range} />
      </section>

      <div className="doc-cols">
        <section className="doc-sec">
          <div className="doc-sec-h">Condition mix</div>
          {condMix(view.grades)}
        </section>
        <section className="doc-sec">
          <div className="doc-sec-h">Demand · last 30 days</div>
          <div className="doc-demand">
            <Trend value={view.searchTrend} />
            {hasSearch ? <Sparkline data={view.searchSeries} w={210} h={36} /> : <span className="doc-mini">no search data yet</span>}
          </div>
          <div className="doc-mini">Availability {view.availability}% · {view.sellers} sellers</div>
        </section>
      </div>

      {top.length > 1 && (
        <section className="doc-sec">
          <div className="doc-sec-h">Matched variants ({matched.length})</div>
          <table className="doc-table">
            <thead><tr><th>Storage</th><th>Color</th><th>Cond.</th><th className="ta-r">Median</th><th className="ta-r">Range</th><th className="ta-r">Trend</th></tr></thead>
            <tbody>
              {top.map(v => (
                <tr key={v.id}>
                  <td><strong>{v.storage}</strong></td><td>{v.color}</td><td><span className={`doc-cond-badge cb-${v.condition}`}>{v.condition}</span></td>
                  <td className="ta-r">{fmtPrice(v.stats.median)}</td>
                  <td className="ta-r mut">{fmtPrice(v.stats.lowest)}–{fmtPrice(v.stats.highest)}</td>
                  <td className="ta-r"><Trend value={v.stats.trend} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </section>
      )}
    </Pg>,
  ];
}

// ── Offer document (multi-page) ───────────────────────────────────────────────
function offerPages(req) {
  const { name, id, createdAt, agg } = req;
  const lines = agg.lines;
  const FIRST = 12, REST = 24;
  const chunks = [];
  if (lines.length === 0) chunks.push([]);
  else {
    chunks.push(lines.slice(0, FIRST));
    let i = FIRST;
    while (i < lines.length) { chunks.push(lines.slice(i, i + REST)); i += REST; }
  }
  const total = chunks.length;
  const footer = `Offer ${id} · ${fmtDate(createdAt)}`;

  const lineRow = (l) => {
    const m = MODELS_BY_ID[l.modelId] || { name: l.modelId, brand: '' };
    const sub = l.stats.median * l.qty;
    return (
      <tr key={l.lid}>
        <td className="offer-td-prod"><strong>{m.name}</strong><span className="mut"> · {m.brand}</span></td>
        <td>{l.storage || 'Any'}</td>
        <td>{l.color || 'Any'}</td>
        <td>{l.condition || 'Any'}</td>
        <td className="ta-r">{l.qty}</td>
        <td className="ta-r">{l.stats.matched ? fmtPrice(l.stats.median) : '—'}</td>
        <td className="ta-r"><strong>{l.stats.matched ? fmtPrice(sub) : '—'}</strong></td>
      </tr>
    );
  };

  return chunks.map((chunk, ci) => (
    <Pg key={'o' + ci} page={ci + 1} total={total} footer={footer}>
      {ci === 0 && (
        <>
          <DocHead eyebrow={`Offer · ${id}`} title={name} sub={`Generated ${fmtDate(createdAt)} · ${agg.totalQty} items across ${lines.length} lines · prices ${vatMode() === 'excl' ? 'excl.' : 'incl.'} VAT`} />
          <div className="doc-offer-sum">
            <div className="doc-offer-sum-main">
              <span className="doc-fact-k">Total median value</span>
              <span className="doc-offer-total">{fmtPrice(agg.totalMedian)}</span>
              <span className="mut">{agg.totalQty} items · {lines.length} lines</span>
            </div>
            <div className="doc-offer-sum-col">
              <span className="doc-fact-k">Value range</span>
              <RangeBar low={agg.totalLow} high={agg.totalHigh} median={agg.totalMedian} />
            </div>
            <div className="doc-offer-sum-col">
              <span className="doc-fact-k">Condition mix</span>
              {condMix(agg.condPct)}
            </div>
          </div>
          <div className="doc-tax">
            <div className="doc-tax-h">Tax summary{vatInfo().noVat ? '' : ` · ${vatInfo().label}`}</div>
            {vatInfo().noVat ? (
              <div className="doc-tax-row doc-tax-total"><span>Total</span><span>{fmtRaw(agg.totalMedian)}</span></div>
            ) : (
              <>
                <div className="doc-tax-row"><span>Net total</span><span>{fmtRaw(vatNet(agg.totalMedian))}</span></div>
                <div className="doc-tax-row"><span>{vatInfo().vatLabel} ({Math.round(vatInfo().vatRate * 100)}%)</span><span>{fmtRaw(vatAmount(agg.totalMedian))}</span></div>
                <div className="doc-tax-row doc-tax-total"><span>Gross total</span><span>{fmtRaw(agg.totalMedian)}</span></div>
              </>
            )}
          </div>
        </>
      )}
      <section className="doc-sec">
        {ci === 0 && <div className="doc-sec-h">Line items</div>}
        <table className="doc-table doc-offer-table">
          <thead><tr><th>Product</th><th>Storage</th><th>Color</th><th>Cond.</th><th className="ta-r">Qty</th><th className="ta-r">Unit median</th><th className="ta-r">Subtotal</th></tr></thead>
          <tbody>{chunk.map(lineRow)}</tbody>
          {ci === total - 1 && (
            <tfoot>
              <tr className="doc-offer-foot">
                <td colSpan={4}>Total</td>
                <td className="ta-r"><strong>{agg.totalQty}</strong></td>
                <td className="ta-r mut">{fmtPrice(agg.totalLow)}–{fmtPrice(agg.totalHigh)}</td>
                <td className="ta-r"><strong>{fmtPrice(agg.totalMedian)}</strong></td>
              </tr>
            </tfoot>
          )}
        </table>
      </section>
    </Pg>
  ));
}

// ── Model spec sheet (1 page) ─────────────────────────────────────────────────
function modelPages(req) {
  const { model } = req;
  const specs = Object.entries(model.specs || {});
  const colors = model.colors || [];
  const storages = model.storages || [];
  const variants = model.variants || [];
  return [
    <Pg key="m1" page={1} total={1} footer={`Product specification · ${fmtDate()}`}>
      <DocHead eyebrow={`Product specification · ${model.brand}`} title={model.name} sub={model.tagline || ''} />

      <div className="doc-hero">
        <div className="doc-hero-vis"><ProductGlyph product={model} size={140} tone="warm" /></div>
        <div className="doc-facts">
          <div className="doc-fact"><span className="doc-fact-k">Brand</span><span className="doc-fact-v">{model.brand}</span></div>
          <div className="doc-fact"><span className="doc-fact-k">Released</span><span className="doc-fact-v">{model.released || '—'}</span></div>
          <div className="doc-fact"><span className="doc-fact-k">Storage options</span><span className="doc-fact-v">{storages.length}</span></div>
          <div className="doc-fact"><span className="doc-fact-k">Color options</span><span className="doc-fact-v">{colors.length}</span></div>
          <div className="doc-fact"><span className="doc-fact-k">Tracked variants</span><span className="doc-fact-v">{variants.length}</span></div>
        </div>
      </div>

      {specs.length > 0 && (
        <section className="doc-sec">
          <div className="doc-sec-h">Technical specifications</div>
          <div className="doc-specs">
            {specs.map(([k, v]) => (
              <div key={k} className="doc-spec"><span className="doc-spec-k">{k}</span><span className="doc-spec-v">{v}</span></div>
            ))}
          </div>
        </section>
      )}

      <div className="doc-cols">
        <section className="doc-sec">
          <div className="doc-sec-h">Available colors</div>
          <div className="doc-chips">{colors.map(c => <span key={c} className="doc-chip">{c}</span>)}</div>
        </section>
        <section className="doc-sec">
          <div className="doc-sec-h">Storage</div>
          <div className="doc-chips">{storages.map(s => <span key={s} className="doc-chip">{s}</span>)}</div>
        </section>
      </div>
    </Pg>,
  ];
}

// ── Overlay ───────────────────────────────────────────────────────────────────
function ExportOverlay({ req, onClose }) {
  useEffectExp(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [onClose]);

  let pages = [];
  let label = '';
  try {
    if (req.kind === 'dashboard') { pages = dashboardPages(req); label = 'Dashboard market report'; }
    else if (req.kind === 'offer') { pages = offerPages(req); label = 'Offer document'; }
    else if (req.kind === 'model') { pages = modelPages(req); label = 'Product specification'; }
  } catch (err) {
    console.error('Export render failed:', err);
    pages = [<Pg key="err" page={1} total={1} footer="Export error"><DocHead eyebrow="Export" title="Could not render this document" sub={String(err && err.message || err)} /></Pg>];
    label = 'Error';
  }

  return ReactDOM.createPortal(
    <div className="export-overlay">
      <div className="export-toolbar">
        <div className="export-toolbar-l">
          <strong>Export preview</strong>
          <span className="export-toolbar-label">{label} · {pages.length} page{pages.length === 1 ? '' : 's'}</span>
        </div>
        <div className="export-toolbar-r">
          <button className="ghost-btn export-close" onClick={onClose}>Close</button>
          <button className="primary-btn" onClick={() => window.print()}><Icon d={ICONS.download} size={14} /> Download PDF</button>
        </div>
      </div>
      <div className="export-scroll">
        <div className="export-pages">{pages}</div>
      </div>
    </div>,
    document.body
  );
}

Object.assign(window, { ExportOverlay });
