/**
 * AdminGoals.jsx — SA Dashboard Goals + Metrics Module
 * Repo: wpsitebeam-app / design/AdminGoals.jsx
 * Version: v1.0.0 — 2026-05-26
 *
 * Phase B of _SA-DASHBOARD-METRICS-SPEC.md (~12h spec, delivered as component)
 *
 * Shows Year 1 progress vs forecast for base/aggressive/stretch scenarios.
 * Data from: GET /sa/metrics/goals (Railway endpoint — Phase A)
 * Until Phase A ships: falls back to seeded forecast from _BUSINESS-ANALYSIS-2026-05-26.md
 *
 * Exports: window.AdminGoals
 * Auth: requireSAJWT — SA only
 * WCAG 2.1 AA: semantic table, aria-live progress updates, keyboard nav
 */

(function () {
  'use strict';
  const VERSION = '1.0.0';
  console.log('[AdminGoals] v' + VERSION + ' loaded');

  function apiBase() { return (window.WPSBD && window.WPSBD.apiBase) || 'https://api.wpsitebeam.io'; }
  function getToken() { return window.WPSBD && window.WPSBD.getToken ? window.WPSBD.getToken() : ''; }
  async function apiFetch(path) {
    const r = await fetch(apiBase() + path, { headers: { Authorization: 'Bearer ' + getToken() } });
    if (!r.ok) throw new Error('HTTP ' + r.status);
    return r.json();
  }

  /* ─── Locked forecast (seeded from _BUSINESS-ANALYSIS-2026-05-26.md §6+§7) ── */
  const FORECAST = {
    base: {
      label: 'Base case',
      y1: { customers: 500, arr: 1480000, mrr: 123333, gm_target: 86 },
      monthly: [
        { m: 1,  ct: 10,  mrr: 2316  }, { m: 2,  ct: 22,  mrr: 5095  },
        { m: 3,  ct: 38,  mrr: 8801  }, { m: 4,  ct: 60,  mrr: 13896  },
        { m: 5,  ct: 88,  mrr: 20385  }, { m: 6,  ct: 120, mrr: 27796  },
        { m: 7,  ct: 158, mrr: 36607  }, { m: 8,  ct: 202, mrr: 46791  },
        { m: 9,  ct: 252, mrr: 58371  }, { m: 10, ct: 308, mrr: 71334  },
        { m: 11, ct: 372, mrr: 86164  }, { m: 12, ct: 500, mrr: 115850 },
      ],
      tiers: [
        { name: 'Solo',       target_ct: 150, target_mrr: 7350  },
        { name: 'Starter',    target_ct: 150, target_mrr: 14850 },
        { name: 'Pro',        target_ct: 100, target_mrr: 19900 },
        { name: 'Agency',     target_ct: 75,  target_mrr: 44925 },
        { name: 'Enterprise', target_ct: 25,  target_mrr: 24975 },
      ],
    },
    aggressive: {
      label: 'Aggressive (WP.org lever)',
      y1: { customers: 1500, arr: 4320000, mrr: 360000, gm_target: 88 },
      monthly: [
        { m: 1,  ct: 30,  mrr: 6948  }, { m: 2,  ct: 70,  mrr: 16212  },
        { m: 3,  ct: 130, mrr: 30108  }, { m: 4,  ct: 210, mrr: 48636  },
        { m: 5,  ct: 310, mrr: 71820  }, { m: 6,  ct: 430, mrr: 99604  },
        { m: 7,  ct: 570, mrr: 132060 }, { m: 8,  ct: 730, mrr: 169040 },
        { m: 9,  ct: 910, mrr: 210760 }, { m: 10, ct: 1110, mrr: 257160 },
        { m: 11, ct: 1320, mrr: 305760 }, { m: 12, ct: 1500, mrr: 347500 },
      ],
      tiers: [
        { name: 'Solo',       target_ct: 450, target_mrr: 22050  },
        { name: 'Starter',    target_ct: 450, target_mrr: 44550  },
        { name: 'Pro',        target_ct: 300, target_mrr: 59700  },
        { name: 'Agency',     target_ct: 225, target_mrr: 134775 },
        { name: 'Enterprise', target_ct: 75,  target_mrr: 74925  },
      ],
    },
    stretch: {
      label: 'Stretch',
      y1: { customers: 3000, arr: 8640000, mrr: 720000, gm_target: 89 },
      monthly: Array.from({length: 12}, (_,i) => ({ m: i+1, ct: Math.round(3000*(i+1)/12), mrr: Math.round(720000*(i+1)/12) })),
      tiers: [
        { name: 'Solo',       target_ct: 900,  target_mrr: 44100  },
        { name: 'Starter',    target_ct: 900,  target_mrr: 89100  },
        { name: 'Pro',        target_ct: 600,  target_mrr: 119400 },
        { name: 'Agency',     target_ct: 450,  target_mrr: 269550 },
        { name: 'Enterprise', target_ct: 150,  target_mrr: 149850 },
      ],
    },
  };

  const fmt = n => '$' + Math.round(n).toLocaleString('en-US');
  const fmtK = n => n >= 1e6 ? '$' + (n/1e6).toFixed(2) + 'M' : n >= 1e3 ? '$' + Math.round(n/1e3) + 'K' : '$' + n;
  const pct = (a, b) => b > 0 ? Math.round(100 * a / b) : 0;
  const delta = (a, b) => { const d = a - b; return (d >= 0 ? '+' : '') + d.toLocaleString('en-US'); };
  const deltaCss = (a, b, thr=0.05) => {
    if (b === 0) return '';
    const r = (a - b) / b;
    return r >= -thr ? 'ag-green' : r >= -0.15 ? 'ag-yellow' : 'ag-red';
  };

  /* ─── CSS ─────────────────────────────────────────────────── */
  const CSS = `
.ag-root { display:flex;flex-direction:column;gap:20px;padding:0 0 32px; }
.ag-header { display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px; }
.ag-title { font-size:18px;font-weight:700; }
.ag-scenario-select { padding:6px 12px;font-size:13px;border:1px solid var(--border);border-radius:7px;background:var(--panel);color:var(--text);cursor:pointer; }
.ag-card { background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:18px 20px; }
.ag-card-title { font-size:13px;font-weight:600;color:var(--dim);text-transform:uppercase;letter-spacing:.05em;margin-bottom:16px; }
.ag-progress-grid { display:flex;flex-direction:column;gap:12px; }
.ag-progress-row { display:flex;flex-direction:column;gap:5px; }
.ag-progress-labels { display:flex;justify-content:space-between;font-size:13px; }
.ag-progress-label { font-weight:500; }
.ag-progress-value { color:var(--dim); }
.ag-bar-track { height:8px;background:rgba(0,0,0,.08);border-radius:4px;overflow:hidden; }
.ag-bar-fill { height:100%;background:var(--cyan,#06b6d4);border-radius:4px;transition:width .5s ease; }
.ag-bar-fill.ahead { background:var(--green,#10b981); }
.ag-bar-fill.behind { background:var(--warn,#f59e0b); }
.ag-vs-label { font-size:11px;color:var(--dim); }
.ag-table { width:100%;border-collapse:collapse;font-size:13px; }
.ag-table th { text-align:left;padding:7px 10px;background:rgba(0,0,0,.04);font-size:11px;font-weight:600;color:var(--dim);text-transform:uppercase;letter-spacing:.04em;border-bottom:2px solid var(--border); }
.ag-table td { padding:8px 10px;border-bottom:1px solid rgba(0,0,0,.05); }
.ag-table tr:last-child td { border-bottom:none; }
.ag-green { color:var(--green,#10b981);font-weight:600; }
.ag-yellow { color:var(--warn,#f59e0b);font-weight:600; }
.ag-red { color:var(--red,#ef4444);font-weight:600; }
.ag-chart-wrap { height:180px;display:flex;align-items:flex-end;gap:4px;padding:0 0 24px;position:relative; }
.ag-chart-bar-group { flex:1;display:flex;flex-direction:column;align-items:center;gap:2px; }
.ag-chart-bar { width:100%;border-radius:3px 3px 0 0;background:var(--cyan,#06b6d4);opacity:.7;min-height:3px;transition:height .3s; }
.ag-chart-bar.forecast { background:rgba(148,163,184,.3);border:1px dashed rgba(148,163,184,.5); }
.ag-chart-label { font-size:9px;color:var(--dim);text-align:center;white-space:nowrap; }
.ag-chart-legend { display:flex;gap:16px;justify-content:flex-end;font-size:11px;color:var(--dim);margin-top:6px; }
.ag-chart-legend-dot { display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:4px; }
.ag-empty { text-align:center;color:var(--dim);font-size:13px;padding:20px; }
.ag-loading { display:flex;align-items:center;justify-content:center;padding:24px;gap:10px;color:var(--dim);font-size:13px; }
.ag-spinner { width:18px;height:18px;border:2px solid var(--border);border-top-color:var(--cyan,#06b6d4);border-radius:50%;animation:ag-spin .7s linear infinite; }
@keyframes ag-spin { to{transform:rotate(360deg)} }
.ag-actual-tag { font-size:10px;padding:1px 6px;border-radius:8px;margin-left:5px; }
.ag-actual-tag.live { background:rgba(16,185,129,.15);color:var(--green,#10b981); }
.ag-actual-tag.seeded { background:rgba(148,163,184,.15);color:var(--dim); }
@media(max-width:480px) {
  .ag-table th:nth-child(3),.ag-table td:nth-child(3),
  .ag-table th:nth-child(5),.ag-table td:nth-child(5) { display:none; }
}
`;

  /* ─── Progress bar component ──────────────────────────────── */
  function ProgressRow({ label, actual, target, formatter, unit }) {
    const p = Math.min(100, pct(actual, target));
    const isAhead = actual >= target;
    const isBehind = actual < target * 0.85;
    return React.createElement('div', { className: 'ag-progress-row' },
      React.createElement('div', { className: 'ag-progress-labels' },
        React.createElement('span', { className: 'ag-progress-label' }, label),
        React.createElement('span', { className: 'ag-progress-value' },
          (formatter || String)(actual) + ' / ' + (formatter || String)(target) +
          ' (' + p + '%' + (unit || '') + ')'
        )
      ),
      React.createElement('div', { className: 'ag-bar-track', role: 'progressbar', 'aria-valuenow': p, 'aria-valuemin': 0, 'aria-valuemax': 100, 'aria-label': label },
        React.createElement('div', { className: 'ag-bar-fill ' + (isAhead ? 'ahead' : isBehind ? 'behind' : ''), style: { width: p + '%' } })
      )
    );
  }

  /* ─── Simple bar chart (customers per month) ─────────────── */
  function TrendChart({ monthly, actualMonthly }) {
    const maxVal = Math.max(...monthly.map(m => m.ct), ...(actualMonthly || []).map(m => m.ct || 0), 1);
    return React.createElement('div', null,
      React.createElement('div', { className: 'ag-chart-wrap', 'aria-label': 'Monthly customer trend' },
        monthly.map((m, i) => {
          const actual = actualMonthly && actualMonthly[i];
          const forecastH = Math.round(160 * m.ct / maxVal);
          const actualH = actual ? Math.round(160 * (actual.ct || 0) / maxVal) : 0;
          return React.createElement('div', { key: m.m, className: 'ag-chart-bar-group' },
            actual && React.createElement('div', { className: 'ag-chart-bar', style: { height: actualH + 'px' }, title: 'Actual M' + m.m + ': ' + (actual.ct || 0) + ' customers' }),
            React.createElement('div', { className: 'ag-chart-bar forecast', style: { height: forecastH + 'px' }, title: 'Forecast M' + m.m + ': ' + m.ct + ' customers' }),
            React.createElement('div', { className: 'ag-chart-label' }, 'M' + m.m)
          );
        })
      ),
      React.createElement('div', { className: 'ag-chart-legend' },
        actualMonthly && React.createElement('span', null, React.createElement('span', { className: 'ag-chart-legend-dot', style: { background: 'var(--cyan,#06b6d4)' } }), 'Actual'),
        React.createElement('span', null, React.createElement('span', { className: 'ag-chart-legend-dot', style: { background: 'rgba(148,163,184,.3)', border: '1px dashed rgba(148,163,184,.5)' } }), 'Forecast')
      )
    );
  }

  /* ─── Main component ─────────────────────────────────────── */
  function AdminGoals() {
    const [scenario, setScenario] = React.useState('base');
    const [liveData, setLiveData] = React.useState(null);
    const [loading, setLoading] = React.useState(true);
    const [isLive, setIsLive] = React.useState(false);

    React.useEffect(() => {
      apiFetch('/sa/metrics/goals')
        .then(d => { setLiveData(d); setIsLive(true); })
        .catch(() => { /* Phase A not yet deployed — use seeded forecast only */ })
        .finally(() => setLoading(false));
    }, []);

    const fc = FORECAST[scenario];
    const actual = liveData || {};
    const actualCt = actual.customers || 0;
    const actualMrr = actual.mrr || 0;
    const actualArr = actual.arr || 0;
    const actualGm = actual.gm_pct || 0;

    // Which forecast month are we in? (based on actual customer count interpolation)
    const currentFcMonth = fc.monthly.find(m => m.ct >= actualCt) || fc.monthly[fc.monthly.length - 1];
    const expectedMrr = currentFcMonth ? currentFcMonth.mrr : fc.y1.mrr;

    return React.createElement('div', { className: 'ag-root' },
      React.createElement('style', null, CSS),

      /* Header */
      React.createElement('div', { className: 'ag-header' },
        React.createElement('h2', { className: 'ag-title' },
          'Year 1 Goals',
          React.createElement('span', { className: 'ag-actual-tag ' + (isLive ? 'live' : 'seeded') },
            isLive ? 'Live' : 'Seeded forecast'
          )
        ),
        React.createElement('select', {
          className: 'ag-scenario-select',
          value: scenario,
          onChange: e => setScenario(e.target.value),
          'aria-label': 'Select scenario',
        },
          Object.entries(FORECAST).map(([k, v]) =>
            React.createElement('option', { key: k, value: k }, v.label)
          )
        )
      ),

      /* Headline progress */
      React.createElement('div', { className: 'ag-card' },
        React.createElement('div', { className: 'ag-card-title' }, 'Headline progress — ' + fc.label),
        loading
          ? React.createElement('div', { className: 'ag-loading' },
              React.createElement('div', { className: 'ag-spinner' }), 'Loading live data\u2026'
            )
          : React.createElement('div', { className: 'ag-progress-grid', 'aria-live': 'polite' },
              React.createElement(ProgressRow, { label: 'Customers', actual: actualCt, target: fc.y1.customers, formatter: n => n.toLocaleString('en-US') }),
              React.createElement(ProgressRow, { label: 'MRR', actual: actualMrr, target: fc.y1.mrr, formatter: fmt }),
              React.createElement(ProgressRow, { label: 'ARR (run rate)', actual: actualArr || actualMrr * 12, target: fc.y1.arr, formatter: fmtK }),
              actualGm > 0 && React.createElement(ProgressRow, { label: 'Gross Margin', actual: actualGm, target: fc.y1.gm_target, formatter: n => n.toFixed(1) + '%', unit: ' vs ' + fc.y1.gm_target + '% target' })
            ),
        !loading && isLive && React.createElement('p', { className: 'ag-vs-label', style: { marginTop: 12 } },
          'vs forecast: ',
          React.createElement('span', { className: deltaCss(actualCt, currentFcMonth?.ct || 0) },
            delta(actualCt, currentFcMonth?.ct || 0) + ' customers'
          ),
          ', ',
          React.createElement('span', { className: deltaCss(actualMrr, expectedMrr) },
            fmtK(Math.abs(actualMrr - expectedMrr)) + ' MRR ' + (actualMrr >= expectedMrr ? 'ahead' : 'behind')
          )
        )
      ),

      /* Tier breakdown table */
      React.createElement('div', { className: 'ag-card' },
        React.createElement('div', { className: 'ag-card-title' }, 'Tier breakdown'),
        React.createElement('table', { className: 'ag-table', role: 'table' },
          React.createElement('thead', null,
            React.createElement('tr', null,
              ['Tier', 'Target ct', 'Actual ct', 'Target MRR', 'Actual MRR', '\u0394 ct'].map(h =>
                React.createElement('th', { key: h, scope: 'col' }, h)
              )
            )
          ),
          React.createElement('tbody', null,
            fc.tiers.map(t => {
              const act = (actual.by_tier || {})[t.name.toLowerCase()] || {};
              const aCt = act.customers || 0;
              const aMrr = act.mrr || 0;
              return React.createElement('tr', { key: t.name },
                React.createElement('td', null, React.createElement('strong', null, t.name)),
                React.createElement('td', null, t.target_ct),
                React.createElement('td', null, aCt || '\u2014'),
                React.createElement('td', null, fmtK(t.target_mrr)),
                React.createElement('td', null, aMrr ? fmtK(aMrr) : '\u2014'),
                React.createElement('td', { className: aCt ? deltaCss(aCt, t.target_ct) : '' }, aCt ? delta(aCt, t.target_ct) : '\u2014')
              );
            })
          )
        )
      ),

      /* Trend chart */
      React.createElement('div', { className: 'ag-card' },
        React.createElement('div', { className: 'ag-card-title' }, '12-month customer ramp — ' + fc.label),
        React.createElement(TrendChart, {
          monthly: fc.monthly,
          actualMonthly: isLive ? actual.monthly_series : null,
        })
      )
    );
  }

  window.AdminGoals = AdminGoals;

})();
