// Traction Forecasting . Supply & Demand cohort inputs

function TractionCohorts({ data, onChange }) {
  return (
    <>
      <CohortSection
        sectionNum="01"
        title="Supply cohorts."
        side="supply"
        sideKey="supply"
        data={data}
        onChange={onChange}
        leadCopy="Supply growth is the harder side. Most B2B and service marketplaces fail because supply churns silently . They never come back to list new inventory. Model retention honestly here."
        povHead="Marketplace POV"
        povBody={<>The most common modeling mistake is assuming a flat retention rate. Real marketplace retention is a curve: <strong>supply churns hardest in months 1–3</strong>, then stabilizes. If your m1 retention is below 70%, your onboarding is broken . Fix that before forecasting anything.</>}
        extraInputLabel="Listings per active supplier per month"
        extraInputKey="listingsPerActive"
        extraInputStep="0.1"
      />
      <CohortSection
        sectionNum="02"
        title="Demand cohorts."
        side="demand"
        sideKey="demand"
        data={data}
        onChange={onChange}
        leadCopy="Demand is loud . Sign-ups feel like progress. But sign-ups without first transactions are vanity. The activation rate is the number that matters, and frequency-of-use determines whether you build network effects or churn."
        povHead="Marketplace POV"
        povBody={<>For B2B marketplaces, expect <strong>1–3 transactions per active buyer per month</strong>. For consumer leisure marketplaces (Airbnb-style), expect 0.1–0.3. If your number is between those, you have a frequency problem to solve before scaling acquisition.</>}
        extraInputLabel="Transactions per active buyer per month"
        extraInputKey="transactionsPerActive"
        extraInputStep="0.1"
      />
    </>
  );
}

function CohortSection({ sectionNum, title, sideKey, data, onChange, leadCopy, povHead, povBody, extraInputLabel, extraInputKey, extraInputStep }) {
  const side = data[sideKey];
  return (
    <section className="lm-page">
      <div className="lm-section-num">Section {sectionNum}</div>
      <h2 className="lm-h2">{title}</h2>
      <p className="lm-body" style={{maxWidth:680, marginBottom:8}}>{leadCopy}</p>

      <div className="lm-page-section">
        <h4 className="lm-h4">Acquisition</h4>
        <div className="lm-input-grid cols-3">
          <div className="lm-input">
            <label className="lm-input-label">Side label <span className="lm-input-hint">how you describe this side</span></label>
            <input type="text" value={side.label} onChange={(e) => onChange([sideKey,'label'], e.target.value)}/>
          </div>
          <div className="lm-input">
            <label className="lm-input-label">New {sideKey} per month (start)</label>
            <input type="number" min="0" step="1" value={side.startSize} onChange={(e) => onChange([sideKey,'startSize'], parseFloat(e.target.value)||0)}/>
          </div>
          <div className="lm-input">
            <label className="lm-input-label">Acquisition growth <span className="lm-input-hint">% month-over-month</span></label>
            <div className="lm-input-suffix">
              <input type="number" min="-50" max="200" step="0.5" value={side.growthMoM} onChange={(e) => onChange([sideKey,'growthMoM'], parseFloat(e.target.value)||0)}/>
              <span className="lm-input-suffix-tag">%</span>
            </div>
          </div>
        </div>
      </div>

      <div className="lm-page-section">
        <h4 className="lm-h4">Activation &amp; retention</h4>
        <div className="lm-input-grid cols-4">
          <div className="lm-input">
            <label className="lm-input-label">Activation rate <span className="lm-input-hint">% who reach first action</span></label>
            <div className="lm-input-suffix">
              <input type="number" min="0" max="100" step="1" value={side.activationRate} onChange={(e) => onChange([sideKey,'activationRate'], parseFloat(e.target.value)||0)}/>
              <span className="lm-input-suffix-tag">%</span>
            </div>
          </div>
          <div className="lm-input">
            <label className="lm-input-label">Month-1 retention <span className="lm-input-hint">% still active</span></label>
            <div className="lm-input-suffix">
              <input type="number" min="0" max="100" step="1" value={side.retention.m1} onChange={(e) => onChange([sideKey,'retention','m1'], parseFloat(e.target.value)||0)}/>
              <span className="lm-input-suffix-tag">%</span>
            </div>
          </div>
          <div className="lm-input">
            <label className="lm-input-label">Month-6 retention</label>
            <div className="lm-input-suffix">
              <input type="number" min="0" max="100" step="1" value={side.retention.m6} onChange={(e) => onChange([sideKey,'retention','m6'], parseFloat(e.target.value)||0)}/>
              <span className="lm-input-suffix-tag">%</span>
            </div>
          </div>
          <div className="lm-input">
            <label className="lm-input-label">Month-12 retention</label>
            <div className="lm-input-suffix">
              <input type="number" min="0" max="100" step="1" value={side.retention.m12} onChange={(e) => onChange([sideKey,'retention','m12'], parseFloat(e.target.value)||0)}/>
              <span className="lm-input-suffix-tag">%</span>
            </div>
          </div>
        </div>
      </div>

      <div className="lm-page-section">
        <h4 className="lm-h4">Frequency &amp; CAC</h4>
        <div className="lm-input-grid cols-3">
          <div className="lm-input">
            <label className="lm-input-label">{extraInputLabel}</label>
            <input type="number" min="0" step={extraInputStep} value={side[extraInputKey]} onChange={(e) => onChange([sideKey, extraInputKey], parseFloat(e.target.value)||0)}/>
          </div>
          <div className="lm-input">
            <label className="lm-input-label">Blended CAC <span className="lm-input-hint">$ per acquired {sideKey}</span></label>
            <div className="lm-input-suffix">
              <input type="number" min="0" step="1" value={side.cac} onChange={(e) => onChange([sideKey,'cac'], parseFloat(e.target.value)||0)}/>
              <span className="lm-input-suffix-tag">$</span>
            </div>
          </div>
        </div>
      </div>

      <RetentionPreview side={side} sideKey={sideKey}/>

      <div className="lm-callout">
        <div className="lm-callout-head">{povHead}</div>
        <p>{povBody}</p>
      </div>
    </section>
  );
}

function RetentionPreview({ side, sideKey }) {
  // sample retention curve at months 1, 3, 6, 9, 12, 18, 24
  const sample = [1,3,6,9,12,18,24].map(m => {
    const r = retentionCurve(side.retention.m1/100, side.retention.m6/100, side.retention.m12/100, m);
    return { m, pct: r * 100 };
  });
  const max = 100;
  return (
    <div className="lm-page-section">
      <h4 className="lm-h4">Retention curve preview</h4>
      <div style={{display:'flex', gap: '4px', alignItems:'flex-end', height: '120px', padding: '8px 0', borderBottom: '1px solid var(--ms-line)'}}>
        {sample.map(s => (
          <div key={s.m} style={{flex:1, display:'flex', flexDirection:'column', alignItems:'center', gap:'4px'}}>
            <div style={{
              width:'100%',
              height: `${(s.pct/max) * 100}%`,
              background: sideKey === 'supply' ? 'var(--ms-primary)' : 'var(--ms-ink-1)',
              borderRadius:'4px 4px 0 0',
              opacity: 0.3 + (s.pct/100) * 0.7,
              minHeight: '4px',
            }}/>
            <span style={{fontFamily:'var(--ms-font-mono)', fontSize:'10px', color:'var(--ms-ink-3)'}}>M{s.m}</span>
            <span style={{fontFamily:'var(--ms-font-mono)', fontSize:'11px', fontWeight:600}}>{s.pct.toFixed(0)}%</span>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { TractionCohorts, CohortSection, RetentionPreview });
