// Growth — new-member sign-ups, month over month.
//
// Wired to /api/v2/analytics/signups-mom. Source is contacts.became_member_at,
// stamped on the is_member false->true transition during GHL sync (membership
// is tag-derived in GHL). It is FORWARD-LOOKING: GHL has no historical signup
// date, so months before tracking began read 0. We surface `tracking_since`
// and say so explicitly rather than implying a real zero.

function monthLabel(ym) {
  if (!ym) return '';
  const d = new Date(ym + '-01T00:00:00');
  return isNaN(d) ? ym : d.toLocaleString('en-US', { month: 'short', year: 'numeric' });
}

// Vertical MoM bar chart. Last bar is accented; zero/empty months render as a
// faint stub so the time axis stays honest about gaps.
function GrowthBars({ buckets, height = 280 }) {
  if (!buckets || buckets.length === 0) {
    return <div style={{ height, display: 'grid', placeItems: 'center', color: 'var(--muted-2)' }}>no data yet</div>;
  }
  const width = 820, padB = 30, padT = 26;
  const plotH = height - padB - padT;
  const n = buckets.length;
  const max = Math.max(1, ...buckets.map(b => b.count || 0));
  const slot = width / n;
  const barW = Math.min(46, slot * 0.62);
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}
      style={{ display: 'block', width: '100%', height: '100%' }}>
      <line x1="0" y1={height - padB} x2={width} y2={height - padB} stroke="var(--bone-2)" strokeWidth="1" />
      {buckets.map((b, i) => {
        const c = b.count || 0;
        const h = (c / max) * plotH;
        const x = i * slot + (slot - barW) / 2;
        const y = height - padB - h;
        const isLast = i === n - 1;
        return (
          <g key={b.ym}>
            <rect x={x} y={c > 0 ? y : height - padB - 2} width={barW} height={c > 0 ? h : 2} rx="3"
              fill={isLast ? 'var(--signal)' : 'var(--ink)'} opacity={c > 0 ? 1 : 0.15} />
            {c > 0 && (
              <text x={x + barW / 2} y={y - 6} fontSize="11" textAnchor="middle"
                fontFamily="var(--mono)" fill="var(--ink)">{c}</text>
            )}
            <text x={x + barW / 2} y={height - padB + 16} fontSize="10" textAnchor="middle"
              fontFamily="var(--mono)" fill="var(--muted-2)">{b.label}</text>
          </g>
        );
      })}
    </svg>
  );
}

function GrowthView() {
  const [months, setMonths] = React.useState(12);
  const res = useAsync(() => api.get('/api/v2/analytics/signups-mom?source=gymmaster&months=' + months), [months]);
  const d = res.data || {};
  const buckets = d.buckets || [];
  const latest = d.latest;
  const tracked = d.total_tracked ?? 0;

  const deltaPct = latest?.delta_pct;
  const deltaAbs = latest?.delta_abs;
  const deltaColor = deltaPct == null ? 'var(--muted-2)'
    : deltaPct >= 0 ? 'var(--signal)' : 'var(--muted)';

  return (
    <div className="app-main">
      <div className="page-hd">
        <div>
          <div className="kicker" style={{ marginBottom: 8 }}>— New members · month over month</div>
          <h1>Growth</h1>
          <div className="sub">New member sign-ups per month, so you can see change and growth.</div>
        </div>
        <div className="actions">
          {/* Inline-style the active state (not .btn.primary — that class is
              reserved for primary CTAs and goes full-width on mobile). */}
          {[6, 12, 24].map(m => (
            <button key={m} className="btn"
              style={{ background: m === months ? 'var(--ink)' : 'transparent', color: m === months ? 'var(--bone)' : 'var(--ink)' }}
              onClick={() => setMonths(m)}>{m}m</button>
          ))}
        </div>
      </div>

      {res.error && <div className="empty" style={{ marginBottom: 16 }}>Sign-ups data unavailable.</div>}

      <div className="kpi-grid" style={{ marginBottom: 16 }}>
        <div className="kpi">
          <div className="kpi-label">This month · new members</div>
          <div className="kpi-value">{latest ? latest.count : '—'}</div>
          <div className="kpi-foot">
            {latest && deltaPct != null ? (
              <span style={{ fontSize: 12, color: deltaColor }}>
                {deltaPct >= 0 ? '+' : ''}{deltaPct}% vs last month
                <span style={{ color: 'var(--muted-2)' }}> ({deltaAbs >= 0 ? '+' : ''}{deltaAbs})</span>
              </span>
            ) : (
              <span style={{ fontSize: 12, color: 'var(--muted-2)' }}>no prior month to compare</span>
            )}
          </div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Last {months} months</div>
          <div className="kpi-value">{d.window_total ?? '—'}</div>
          <div className="kpi-foot"><span style={{ fontSize: 12, color: 'var(--muted)' }}>sign-ups in window</span></div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Tracked all-time</div>
          <div className="kpi-value">{tracked}</div>
          <div className="kpi-foot"><span style={{ fontSize: 12, color: 'var(--muted)' }}>since tracking began</span></div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Tracking since</div>
          <div className="kpi-value" style={{ fontSize: 22 }}>{d.tracking_since ? monthLabel(d.tracking_since) : '—'}</div>
          <div className="kpi-foot"><span style={{ fontSize: 12, color: 'var(--muted)' }}>first recorded sign-up</span></div>
        </div>
      </div>

      <div className="card" style={{ marginBottom: 16 }}>
        <div className="hd">
          <div className="title">— <b>Sign-ups</b> · new members per month</div>
          <div className="aside" style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--muted)' }}>
            last {months} months · America/New_York
          </div>
        </div>
        <div className="bd" style={{ height: 300 }}>
          <GrowthBars buckets={buckets} height={300} />
        </div>
      </div>

      {/* Honesty banner: this metric only exists going forward. Shown loudly
          while there's little/no history so nobody reads an empty chart as
          "zero new members". */}
      {!res.loading && tracked === 0 && (
        <div className="card" style={{ marginBottom: 16, borderColor: 'var(--warn, #c98a00)' }}>
          <div className="bd" style={{ fontSize: 13, lineHeight: 1.5, color: 'var(--muted)' }}>
            <b style={{ color: 'var(--ink)' }}>No data yet.</b> New member sign-ups come from the
            GymMaster roster (Revive Gym) — members who joined in a month with a real membership.
            If this is empty, the GymMaster sync hasn't completed yet; it refreshes a few times a
            day. The chart fills in once the sync runs.
          </div>
        </div>
      )}

      {buckets.length > 0 && (
        <div className="card">
          <div className="hd"><div className="title">— <b>By month</b></div></div>
          <div className="bd">
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 90px 110px', gap: 12, padding: '6px 0', fontSize: 11, color: 'var(--muted-2)', fontFamily: 'var(--mono)', borderBottom: '1px solid var(--bone-2)' }}>
              <span>Month</span><span style={{ textAlign: 'right' }}>New members</span><span style={{ textAlign: 'right' }}>vs prev</span>
            </div>
            {buckets.map((b, i) => {
              const prev = i > 0 ? buckets[i - 1].count : null;
              const da = prev == null ? null : b.count - prev;
              const dp = prev && prev > 0 ? Math.round((da / prev) * 100) : null;
              const col = da == null || da === 0 ? 'var(--muted-2)' : da > 0 ? 'var(--signal)' : 'var(--muted)';
              return (
                <div key={b.ym} style={{ display: 'grid', gridTemplateColumns: '1fr 90px 110px', gap: 12, padding: '8px 0', alignItems: 'center', fontSize: 13, borderBottom: '1px solid var(--bone-2)' }}>
                  <span>{monthLabel(b.ym)}</span>
                  <span style={{ textAlign: 'right', fontFamily: 'var(--mono)' }}>{b.count}</span>
                  <span style={{ textAlign: 'right', fontFamily: 'var(--mono)', fontSize: 12, color: col }}>
                    {da == null ? '—' : dp == null ? `${da >= 0 ? '+' : ''}${da}` : `${dp >= 0 ? '+' : ''}${dp}%`}
                  </span>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { GrowthView });
