// compact per-row creative vitals — CTR + CVR (color-graded) + Sessions + Sales; full baseline lives in the expand
const ratePB = (v, kind) => v == null ? null : v < (kind === 'ctr' ? 0.30 : 15) ? 'poor' : v < (kind === 'ctr' ? 0.50 : 30) ? 'okay' : 'good';
const shortNum = (n) => n >= 1e6 ? (n / 1e6).toFixed(1).replace(/\.0$/, '') + 'M' : n >= 1000 ? (n / 1000).toFixed(n >= 1e5 ? 0 : 1).replace(/\.0$/, '') + 'k' : '' + n;
function Vitals({ m }) {
  const c = ratePB(m.adCtr, 'ctr'), v = ratePB(m.conv, 'conv');
  return (
    <div className="lvitals" title="Current creative · ad CTR + conversion (color-graded) · 90-day sessions + sales">
      <div className="lv"><span className="lv-l">CTR</span><span className={`lv-v ${c || ''}`}>{m.adCtr != null ? m.adCtr.toFixed(2) + '%' : '—'}</span></div>
      <div className="lv"><span className="lv-l">CVR</span><span className={`lv-v ${v || ''}`}>{m.conv != null ? m.conv.toFixed(1) + '%' : '—'}</span></div>
      <div className="lv"><span className="lv-l">SESS</span><span className="lv-v">{shortNum(m.sessions)}</span></div>
      <div className="lv"><span className="lv-l">SALES</span><span className="lv-v">{compactMoney(m.sales)}</span></div>
    </div>
  );
}

// ─── Catalog (full project scope, expandable rows) ───
function Listing({ L, open, onToggle, openLightbox, started, onStart, onCompare }) {
  const ref = useRef(null);

  const handle = () => {
    const wasOpen = open;
    onToggle(L.id);
    if (!wasOpen) {
      setTimeout(() => {
        const top = ref.current.getBoundingClientRect().top + window.scrollY - 84;
        if (window.scrollY > top || top - window.scrollY > 120) window.scrollTo({ top, behavior: 'smooth' });
      }, 80);
    }
  };

  const accent = L.makeover ? L.accent : (started ? '#E2902B' : 'var(--muted)');
  const flagClass = L.makeover ? 'ready' : (started ? 'prod' : 'pending');
  const flagLabel = L.makeover ? 'Creative ready' : (started ? 'In production' : 'Not started');
  const phLabel = L.makeover ? L.short : (started ? 'Rendering' : 'No creative yet');

  return (
    <div id={'L-' + L.id} className={`litem ${open ? 'open' : ''} ${L.makeover ? '' : 'pending'} ${started ? 'started' : ''}`} style={{ '--accent': accent }} ref={ref}>
      <div className="lrow" onClick={handle}>
        <div className="th">
          {L.hero ? <img src={L.hero} alt={L.fullName} loading="lazy"/>
            : <Placeholder label={phLabel} glyph="image"/>}
          {L.currentImage && <span className="cur-tag">Current</span>}
        </div>
        <div className="lmeta">
          <div className="ltitle">{L.short}
            <span className={`lflag ${flagClass}`}><span className="fdot"></span>{flagLabel}</span>
          </div>
          <div className="lsub">{L.brand} · {L.size} · {L.tag}</div>
          {L.designerWork && (
            <div className={`dw-chip ${L.designerWork.kind}`} title={`${L.designerWork.designer}'s ${L.designerWork.kind} (${L.designerWork.source}) — expand to compare`}>
              <span className="dw-av"><img src={`assets/designers/${L.designerWork.who}.png`} alt={L.designerWork.designer} loading="lazy"/></span>
              <span className="dw-lbl">{L.designerWork.designer}&rsquo;s {L.designerWork.kind}</span>
              <span className="dw-src">{L.designerWork.source}</span>
            </div>
          )}
        </div>
        <div className="rt">
          {L.metrics && <Vitals m={L.metrics}/>}
          {L.makeover ? (
            <>
              <Counts c={L.counts}/>
              <span className="price">{money(L.price)}</span>
            </>
          ) : (
            <span className="eta-pill"><Ico d="clock" size={12} sw={1.8}/>{started ? 'Ready in 24–48h' : '24–48h turnaround'}</span>
          )}
          <span className="chev"><Ico d="chevR" size={17}/></span>
        </div>
      </div>
      {open && (L.makeover
        ? <ExpandedContent L={L} openLightbox={openLightbox}/>
        : <PendingPanel L={L} started={started} onStart={onStart} onCompare={onCompare} openLightbox={openLightbox}/>)}
    </div>
  );
}

function BrandSection({ brand, listings, statusFilter, openId, onToggle, openLightbox, startedSet, onStart, onCompare }) {
  const meta = window.CATALOG.brands[brand];
  const dwFirst = (a, b) => (b.designerWork ? 1 : 0) - (a.designerWork ? 1 : 0);   // designer alternate/proposal floats to the top of its group
  const ready = listings.filter(L => L.makeover).sort(dwFirst);
  const pending = listings.filter(L => !L.makeover).sort(dwFirst);
  const showReady = statusFilter !== 'pending';
  const showPending = statusFilter !== 'ready';
  if ((showReady ? ready.length : 0) + (showPending ? pending.length : 0) === 0) return null;
  const sum = ready.reduce((a, L) => a + L.price, 0);
  return (
    <section className="brand-sec">
      <div className="brand-head">
        <span className="bn"><span className="d" style={{ background: meta.accent }}></span>{meta.label}</span>
        <span className="meta">{meta.family} · {listings.length} SKUs{sum ? <span className="px-ready"> · {money(sum)} ready</span> : ''}</span>
        <span className="rule"></span>
      </div>
      <div className="lstack">
        {showReady && ready.map(L => (
          <Listing key={L.id} L={L} open={openId === L.id} onToggle={onToggle} openLightbox={openLightbox}
            started={startedSet.has(L.id)} onStart={onStart} onCompare={onCompare}/>
        ))}
        {showReady && showPending && ready.length > 0 && pending.length > 0 && (
          <div className="pend-div">Awaiting creative · {pending.length} · 24–48h turnaround</div>
        )}
        {showPending && pending.map(L => (
          <Listing key={L.id} L={L} open={openId === L.id} onToggle={onToggle} openLightbox={openLightbox}
            started={startedSet.has(L.id)} onStart={onStart} onCompare={onCompare}/>
        ))}
      </div>
    </section>
  );
}

function Catalog({ listings, filter, setFilter, statusFilter, setStatusFilter, openId, onToggle, openLightbox, startedSet, onStart, onCompare }) {
  const sc = window.CATALOG.scope;
  const tot = window.CATALOG.totals;
  const pct = Math.round((sc.ready / sc.total) * 100);
  const shown = listings.filter(L => filter === 'all' || L.brand === filter);
  let brands = filter === 'all' ? ['NOTTS', 'AXIV'] : [filter];
  if (statusFilter === 'pending') {   // in the Pending tab, surface the brand with proposals first
    const props = (b) => shown.filter(L => L.brand === b && !L.makeover && L.designerWork).length;
    brands = [...brands].sort((a, b) => props(b) - props(a));
  }
  const FILTERS = [['all', 'All', null], ['NOTTS', 'NOTTS', '#1D428A'], ['AXIV', 'AXIV', '#16A34A']];
  const STATUS = [['all', 'All work'], ['ready', 'Creative ready'], ['pending', 'Pending']];
  return (
    <main>
      <header className="cat-head">
        <div className="ch-title">
          <div className="eyebrow">Vivunt · Creative delivery program</div>
          <h1>Listing makeover — full catalog</h1>
        </div>
        <div className="kpis">
          <div className="kpi"><span className="kv num">{sc.total}</span><span className="kl">In scope</span></div>
          <div className="kpi"><span className="kv num">{sc.ready}</span><span className="kl">Ready</span></div>
          <div className="kpi"><span className="kv num">{tot.deliverables}</span><span className="kl">Deliverables</span></div>
          <div className="kpi prog">
            <div className="ptop"><span className="pv num">{sc.ready}/{sc.total}</span><span className="pp">{pct}%</span></div>
            <div className="pbar"><div className="pfill" style={{ width: pct + '%' }}></div></div>
          </div>
        </div>
      </header>

      <div className="toolbar">
        <div className="seg-group">
          <div className="seg">
            {FILTERS.map(([v, label, dot]) => (
              <button key={v} aria-pressed={filter === v} onClick={() => setFilter(v)}>
                {dot && <span className="d" style={{ background: dot }}></span>}{label}
              </button>
            ))}
          </div>
          <div className="seg">
            {STATUS.map(([v, label]) => (
              <button key={v} aria-pressed={statusFilter === v} onClick={() => setStatusFilter(v)}>{label}</button>
            ))}
          </div>
        </div>
      </div>

      {brands.map(b => (
        <BrandSection key={b} brand={b} listings={shown.filter(L => L.brand === b)} statusFilter={statusFilter}
          openId={openId} onToggle={onToggle} openLightbox={openLightbox} startedSet={startedSet} onStart={onStart} onCompare={onCompare}/>
      ))}
    </main>
  );
}

Object.assign(window, { Catalog, Listing });
