/* Module demos: Operations, Workforce, Strategy, M&A, Portfolio shown on
   the fictional Meridian Outdoor Co. (and a fictional second company and
   fund). One frame, five renderers, all reading the deterministic payload
   from `demo/module`. Every page carries the demo disclaimer and a way to
   talk to the team about implementing the module. */

const MODULE_ICON = { operations: 'zap', workforce: 'shield', strategy: 'chart', mna: 'globe', portfolio: 'cart' };

function requestUrl(moduleId) { return '/app/?request=' + encodeURIComponent(moduleId || '1'); }

function statusLabel(s) { const t = String(s || '').replace(/[_-]/g, ' ').trim(); return t.charAt(0).toUpperCase() + t.slice(1); }

function DemoFrame({ m, data, children }) {
  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', gap: 14, alignItems: 'flex-end', flexWrap: 'wrap', marginBottom: 12 }}>
        <div>
          <div className="overline" style={{ marginBottom: 6 }}>Lojo {m.title} · demo on a fictional company</div>
          <h1 className="display" style={{ fontSize: 'clamp(24px,3.6vw,34px)', margin: 0 }}>{data.company}</h1>
        </div>
        <TalkToUs moduleId={m.id} compact />
      </div>
      <div className="flash warn" style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}><Icon name="eye" size={14} style={{ marginTop: 3, flex: '0 0 auto' }} /><span>{data.disclaimer} {m.status === 'preview' ? `${m.title} is not yet enabled for customer organizations; this is what it will do, computed on the demo data.` : ''}</span></div>
      {children}
      <div className="app-panel" style={{ marginTop: 22 }}>
        <h3>What {m.title} will do for your organization</h3>
        <ul style={{ margin: '0 0 12px', paddingLeft: 18, fontSize: 14.5, lineHeight: 1.7 }}>{(data.will || []).map((w) => <li key={w}>{w}</li>)}</ul>
        <TalkToUs moduleId={m.id} />
      </div>
    </div>);
}

function TalkToUs({ moduleId, compact }) {
  if (compact) return <a href={requestUrl(moduleId)} className="app-btn primary">Talk to us about {titleCase(moduleId === 'mna' ? 'M&A' : moduleId)} <Icon name="arrow-right" size={14} /></a>;
  return (
    <div style={{ display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap' }}>
      <a href={requestUrl(moduleId)} className="btn btn-primary" style={{ padding: '11px 18px', fontSize: 14 }}>Book a call or send a request <Icon name="arrow-right" size={16} /></a>
      <span style={{ fontSize: 13, color: 'var(--fg-muted)', maxWidth: 520, lineHeight: 1.5 }}>Beta pricing is active for this module and is confirmed on the call, based on complexity and the size of your organization. Sensitive material is shared only under a mutual NDA.</span>
    </div>);
}

function MiniTable({ head, rows, numeric }) {
  return <div className="app-table-wrap"><table className="app-table">
    <thead><tr>{head.map((h, i) => <th key={i} className={(numeric || []).includes(i) ? 'num' : ''}>{h}</th>)}</tr></thead>
    <tbody>{rows.map((r, i) => <tr key={i}>{r.map((c, j) => <td key={j} className={(numeric || []).includes(j) ? 'num' : ''}>{c}</td>)}</tr>)}</tbody>
  </table></div>;
}

/* ---------------------------------------------------------- operations */
function OperationsDemo({ m, data }) {
  const [open, setOpen] = React.useState(data.processes[0] && data.processes[0].id);
  const p = data.processes.find((x) => x.id === open) || data.processes[0];
  const s = data.summary;
  return (
    <DemoFrame m={m} data={data}>
      <div className="app-grid cols-4" style={{ marginBottom: 16 }}>
        <Stat label="Workflows mapped" value={s.workflows} note={`${s.handoffs} handoffs across ${s.systems.length} systems`} />
        <Stat label="Hours a month" value={s.hours_per_month.toLocaleString()} note="repetitive work captured in Stack" />
        <Stat label="Hours an agent could take" value={s.hours_to_agents.toLocaleString()} note={`${Math.round(s.share_to_agents * 100)}% of the total, people approve exceptions`} tone="accent" />
        <Stat label="Redesigns" value={data.redesigns.length} note="each becomes an opportunity in Execute" />
      </div>
      <div className="app-grid cols-2">
        <div className="app-panel">
          <h3>Process map</h3>
          <div className="section-nav">{data.processes.map((x) => <button key={x.id} className={x.id === p.id ? 'on' : ''} onClick={() => setOpen(x.id)}><span>{x.name}</span><span className="mono" style={{ fontSize: 10.5 }}>{x.hours_per_month} h</span></button>)}</div>
        </div>
        <div className="app-panel">
          <h3>{p.name}</h3>
          <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', marginBottom: 10 }}>{p.department} · {p.volume_per_month} items a month × {p.minutes_per_item} min · systems: {p.systems.join(', ') || 'none stated'}</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 12 }}>
            {p.steps.map((st) => <div key={st.n} style={{ display: 'grid', gridTemplateColumns: '28px 1fr 120px 110px', gap: 10, alignItems: 'center', fontSize: 13.5, padding: '7px 10px', borderRadius: 8, background: st.owner === 'agent' ? 'color-mix(in oklab, var(--accent) 10%, transparent)' : 'var(--navy)', border: '1px solid var(--line)' }}>
              <span className="mono" style={{ color: 'var(--fg-subtle)' }}>{st.n}</span><span>{st.name}</span><span className="mono" style={{ fontSize: 11, color: 'var(--fg-muted)' }}>{st.system}</span>
              <Pill tone={st.owner === 'agent' ? 'accent' : 'fg-subtle'}>{st.owner === 'agent' ? 'agent' : 'person decides'}</Pill></div>)}
          </div>
          <div className="app-grid cols-2">
            <Stat label="Taken by the agent" value={`${p.hours_to_agent} h/mo`} note={p.agent ? `${p.agent.name} (${p.agent.kind})` : 'stays with people'} tone={p.agent_share ? 'accent' : undefined} />
            <Stat label="Kept by people" value={`${p.hours_kept_by_people} h/mo`} note={p.approval} />
          </div>
          {p.pain_points.length > 0 && <div style={{ fontSize: 13, color: 'var(--fg-muted)', marginTop: 10 }}>Pain today: {p.pain_points.join(' · ')}</div>}
          {p.opportunity_status && <div style={{ fontSize: 12.5, color: 'var(--accent)', marginTop: 6 }}>In Execute as an opportunity · {statusLabel(p.opportunity_status)}</div>}
        </div>
      </div>
      <div className="app-panel" style={{ marginTop: 14 }}>
        <h3>Redesigns handed to Execute</h3>
        <MiniTable head={['Workflow', 'Agent', 'Hours before', 'Hours after (people)', 'Status']} numeric={[2, 3]}
          rows={data.redesigns.map((r) => [r.workflow, r.agent || '—', r.before_hours, r.after_hours, statusLabel(r.status)])} />
      </div>
    </DemoFrame>);
}

/* ------------------------------------------------------------ workforce */
function WorkforceDemo({ m, data }) {
  const s = data.summary;
  return (
    <DemoFrame m={m} data={data}>
      <div className="flash good" style={{ display: 'flex', gap: 8 }}><Icon name="shield" size={14} style={{ marginTop: 3, flex: '0 0 auto' }} /><span>{data.policy}</span></div>
      <div className="app-grid cols-4" style={{ marginBottom: 16 }}>
        <Stat label="Roles modelled" value={s.roles} note={`${s.headcount_modelled} people in the operational roles mapped, of ${s.company_headcount}`} />
        <Stat label="Repetitive hours a month" value={s.repetitive_hours_per_month.toLocaleString()} note="across the mapped roles" />
        <Stat label="Freed by month 12" value={`${s.hours_freed_month_12.toLocaleString()} h`} note={`about ${s.fte_equivalent_month_12} FTE of capacity, redeployed`} tone="accent" />
        <Stat label="New capabilities" value={s.new_capabilities} note="roles the business could not afford before" />
      </div>
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <h3>Organization scenarios</h3>
        <div className="app-grid cols-3">{data.scenarios.map((sc) => <div key={sc.horizon} style={{ padding: 14, borderRadius: 'var(--r-md)', background: 'var(--navy)', border: '1px solid var(--line)' }}>
          <div className="overline" style={{ marginBottom: 6 }}>{sc.horizon}</div>
          <div style={{ fontSize: 14, lineHeight: 1.7 }}>Headcount <b>{sc.headcount}</b><br />Repetitive hours <b>{sc.repetitive_hours.toLocaleString()}</b> / month<br />Capacity freed <b>{sc.hours_freed.toLocaleString()} h</b> ({sc.fte_equivalent_freed} FTE)</div>
          {sc.new_roles.length > 0 && <div style={{ marginTop: 8, display: 'flex', gap: 6, flexWrap: 'wrap' }}>{sc.new_roles.map((r) => <span key={r} className="chip">{r}</span>)}</div>}
          <div style={{ fontSize: 12.5, color: 'var(--fg-muted)', marginTop: 8, lineHeight: 1.5 }}>{sc.note}</div>
        </div>)}</div>
      </div>
      <div className="app-grid cols-2">
        <div className="app-panel"><h3>Roles and capabilities</h3>
          <MiniTable head={['Role', 'Dept', 'Head', 'Band', 'Repetitive share', 'Freed by M12']} numeric={[2, 4, 5]}
            rows={data.roles.map((r) => [r.role, r.department, r.headcount, r.band_range, `${Math.round(r.repetitive_share * 100)}%`, `${r.hours_freed_month_12} h`])} /></div>
        <div>
          <div className="app-panel" style={{ marginBottom: 14 }}><h3>Transition plan</h3>
            {data.transition.map((t) => <div key={t.month} style={{ display: 'grid', gridTemplateColumns: '70px 1fr 130px', gap: 10, padding: '8px 0', borderTop: '1px solid var(--line)', fontSize: 13.5 }}><span className="mono" style={{ color: 'var(--accent)' }}>M{t.month}</span><span>{t.step}</span><span style={{ color: 'var(--fg-muted)' }}>{t.owner}</span></div>)}</div>
          <div className="app-panel"><h3>Skills to develop</h3>
            {data.skills.map((k) => <div key={k.skill} style={{ padding: '8px 0', borderTop: '1px solid var(--line)', fontSize: 13.5 }}><b>{k.skill}</b> <span style={{ color: 'var(--fg-muted)' }}>· {k.roles.join(', ')} · {k.how}</span></div>)}</div>
        </div>
      </div>
      <div className="app-panel" style={{ marginTop: 14 }}><h3>Compensation bands (band level only)</h3>
        <MiniTable head={['Band', 'Range used in the demo', 'Hourly cost in the model']} numeric={[2]} rows={data.bands.map((b) => [titleCase(b.band), b.range, money(b.hourly_cost_used) + '/h'])} />
        <div style={{ fontSize: 12.5, color: 'var(--fg-subtle)', marginTop: 8 }}>In a customer organization, band data lives in the restricted store, visible only to members with the HR flag, and never reaches the model or the exports without it.</div></div>
    </DemoFrame>);
}

/* ------------------------------------------------------------- strategy */
function StrategyDemo({ m, data }) {
  return (
    <DemoFrame m={m} data={data}>
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <h3>The same ledger under three assumption sets</h3>
        <div className="app-grid cols-3">{data.scenarios.map((sc) => <div key={sc.id} style={{ padding: 14, borderRadius: 'var(--r-md)', background: sc.id === 'base' ? 'color-mix(in oklab, var(--accent) 8%, var(--navy))' : 'var(--navy)', border: '1px solid ' + (sc.id === 'base' ? 'var(--accent)' : 'var(--line)') }}>
          <div className="overline" style={{ marginBottom: 6 }}>{sc.label}</div>
          <div className="display" style={{ fontSize: 26 }}>{money(sc.totals.npv_usd, { compact: true })} <span style={{ fontSize: 13, fontFamily: 'var(--font-sans)', color: 'var(--fg-muted)' }}>NPV</span></div>
          <div style={{ fontSize: 13.5, lineHeight: 1.7, marginTop: 6 }}>Net benefit <b>{money(sc.totals.annual_net_benefit_usd)}</b>/yr<br />Implementation <b>{money(sc.totals.implementation_cost_usd)}</b><br />Median payback <b>{sc.totals.median_payback_month ? 'month ' + sc.totals.median_payback_month : '—'}</b></div>
          <div className="mono" style={{ fontSize: 10.5, color: 'var(--fg-subtle)', marginTop: 8, lineHeight: 1.6 }}>discount {Math.round(sc.values.discount_rate * 100)}% · day rate {money(sc.values.day_rate_usd)} · realisation {Math.round(sc.values.labour_realisation * 100)}% · haircut A/B/C {Object.values(sc.values.haircut).map((v) => Math.round(v * 100) + '%').join('/')} · ramp {sc.values.ramp_months} mo</div>
        </div>)}</div>
      </div>
      <div className="app-grid cols-2" style={{ marginBottom: 14 }}>
        <div className="app-panel"><h3>Operating-model scenarios</h3>
          {data.operating_models.map((om) => <div key={om.label} style={{ padding: '10px 0', borderTop: '1px solid var(--line)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, fontSize: 14.5 }}><b>{om.label}</b><span className="mono">{money(om.npv_usd, { compact: true })} NPV</span></div>
            <div style={{ fontSize: 13, color: 'var(--fg-muted)', lineHeight: 1.5 }}>{om.note} · {om.opportunities} opportunities · {money(om.annual_net_benefit_usd)}/yr · {money(om.implementation_cost_usd)} to implement</div></div>)}</div>
        <div className="app-panel"><h3>P&amp;L lines moved (base case)</h3>
          <MiniTable head={['Line', 'Today', 'Change', 'Basis']} numeric={[1, 2]} rows={data.pnl.map((l) => [l.line, l.today_usd === null ? '—' : money(l.today_usd), <span style={{ color: l.change_usd >= 0 ? 'var(--good)' : 'var(--crit)' }}>{money(l.change_usd)}</span>, l.note])} /></div>
      </div>
      <div className="app-panel"><h3>Every opportunity under every scenario</h3>
        <MiniTable head={['Opportunity', 'Status', 'Conservative NPV', 'Base NPV', 'Aggressive NPV']} numeric={[2, 3, 4]}
          rows={data.opportunities.map((o) => [o.title, statusLabel(o.status), money(o.by_scenario.conservative.npv_usd, { compact: true }), money(o.by_scenario.base.npv_usd, { compact: true }), money(o.by_scenario.aggressive.npv_usd, { compact: true })])} /></div>
    </DemoFrame>);
}

/* ------------------------------------------------------------------ M&A */
function MnaDemo({ m, data }) {
  const s = data.summary;
  return (
    <DemoFrame m={m} data={data}>
      <div className="app-grid cols-2" style={{ marginBottom: 14 }}>{data.companies.map((c) => <div key={c.name} className="app-panel"><h3>{c.name}</h3><div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.7 }}>{c.profile || 'The demo organization.'}<br />{c.headcount} people · {c.subscriptions} subscriptions · {money(c.software_spend_usd)} software a year</div></div>)}</div>
      <div className="app-grid cols-4" style={{ marginBottom: 16 }}>
        <Stat label="Combined software spend" value={money(s.combined_spend_usd)} note={`${s.capabilities_overlapping} capabilities overlap`} />
        <Stat label="Annual synergy" value={money(s.annual_synergy_usd)} note="retired licences net of added seats" tone="good" />
        <Stat label="One-time integration" value={money(s.one_time_cost_usd)} note={`${s.migration_days} migration days plus fixed costs`} />
        <Stat label="Payback / NPV" value={s.payback_month ? `month ${s.payback_month}` : '—'} note={`${money(s.npv_usd, { compact: true })} over 3 years`} tone="accent" />
      </div>
      <div className="app-panel" style={{ marginBottom: 14 }}><h3>Technology reconciliation</h3>
        <MiniTable head={['Capability', 'Decision', 'Keep', 'Retire', 'Net saving / yr', 'Migration']} numeric={[4, 5]}
          rows={data.reconciliation.map((r) => [r.capability, <Pill tone={r.decision === 'consolidate' ? 'accent' : 'fg-subtle'}>{r.decision}</Pill>, `${r.keep.product} (${r.keep.company})`, r.retire.map((x) => `${x.product} (${x.company})`).join(', ') || '—', money(r.net_saving_usd), r.migration_days ? `${r.migration_days} d` : '—'])} /></div>
      <div className="app-grid cols-2" style={{ marginBottom: 14 }}>
        <div className="app-panel"><h3>Integration timeline</h3>{data.timeline.map((t) => <div key={t.months} style={{ display: 'grid', gridTemplateColumns: '60px 1fr 140px', gap: 10, padding: '8px 0', borderTop: '1px solid var(--line)', fontSize: 13.5 }}><span className="mono" style={{ color: 'var(--accent)' }}>M{t.months}</span><span>{t.step}</span><span style={{ color: 'var(--fg-muted)' }}>{t.owner}</span></div>)}</div>
        <div>
          <div className="app-panel" style={{ marginBottom: 14 }}><h3>People, at the function level</h3>
            <MiniTable head={['Function', 'Meridian', 'Harbor Trail', 'Note']} numeric={[1, 2]} rows={data.people.map((p) => [p.function, p.meridian, p.harbor, p.note])} />
            <div style={{ fontSize: 12, color: 'var(--fg-subtle)', marginTop: 6 }}>Functions and counts only. Individual roles, pay and decisions are never modelled.</div></div>
          <div className="app-panel"><h3>Cultural and operating considerations</h3><ul style={{ margin: 0, paddingLeft: 18, fontSize: 13.5, lineHeight: 1.7 }}>{data.culture.map((c) => <li key={c}>{c}</li>)}</ul></div>
        </div>
      </div>
      <div className="app-panel"><h3>How the synergy money is computed</h3><Lines lines={data.economics.lines} /></div>
    </DemoFrame>);
}

/* ------------------------------------------------------------ portfolio */
function PortfolioDemo({ m, data }) {
  const s = data.summary;
  return (
    <DemoFrame m={m} data={data}>
      <div className="app-grid cols-4" style={{ marginBottom: 16 }}>
        <Stat label="Portfolio companies" value={s.companies} note={`${s.sharing} sharing data with the fund`} />
        <Stat label="Software spend (shared)" value={money(s.software_spend_usd, { compact: true })} note={`${money(s.idle_seat_cost_usd, { compact: true })} in idle seats`} />
        <Stat label="Opportunities" value={s.opportunities} note="across sharing companies" />
        <Stat label="Opportunity NPV" value={money(s.npv_usd, { compact: true })} note="EBITDA levers, modelled" tone="accent" />
      </div>
      <div className="app-panel" style={{ marginBottom: 14 }}><h3>Companies</h3>
        <MiniTable head={['Company', 'Sector', 'Head', 'Software spend', 'Per head', 'Idle seats', 'Opps', 'NPV', 'EBITDA lever', 'Sharing']} numeric={[2, 3, 4, 5, 6, 7]}
          rows={data.companies.map((c) => [c.name, c.sector, c.headcount, c.software_spend_usd === null ? '—' : money(c.software_spend_usd), c.spend_per_head_usd === null ? '—' : money(c.spend_per_head_usd), c.idle_seat_cost_usd === null ? '—' : money(c.idle_seat_cost_usd), c.opportunities === null ? '—' : c.opportunities, c.npv_usd === null ? '—' : money(c.npv_usd, { compact: true }), c.ebitda_lever, <Pill tone={c.consent === 'shared' ? 'good' : 'warn'}>{c.consent}</Pill>])} /></div>
      <div className="app-grid cols-2">
        <div className="app-panel"><h3>Benchmarks across sharing companies</h3>{data.benchmarks.map((b) => <div key={b.metric} style={{ marginBottom: 12 }}><div className="overline" style={{ marginBottom: 6 }}>{b.metric}</div>{b.values.map((v) => <div key={v.company} style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13.5, padding: '4px 0', borderBottom: '1px solid var(--line)' }}><span>{v.company}</span><span className="mono">{v.value === null || v.value === undefined ? '—' : (b.metric.includes('share') ? Math.round(v.value * 100) + '%' : money(v.value))}</span></div>)}</div>)}</div>
        <div className="app-panel"><h3>Consent</h3><div style={{ fontSize: 14, color: 'var(--fg-muted)', lineHeight: 1.65 }}>{data.consent}</div></div>
      </div>
    </DemoFrame>);
}

const DEMO_RENDERERS = { operations: OperationsDemo, workforce: WorkforceDemo, strategy: StrategyDemo, mna: MnaDemo, portfolio: PortfolioDemo };

function ModuleDemo({ m }) {
  const [data, setData] = React.useState(null);
  const [error, setError] = React.useState('');
  React.useEffect(() => { lojo('', { module: 'demo', action: 'module', module_id: m.id }).then((d) => { if (d.ok) setData(d); else setError(d.message || 'Could not load the demo.'); }); }, [m.id]);
  if (error) return <div className="empty">{error}</div>;
  if (!data) return <div style={{ color: 'var(--fg-subtle)' }}>Building the demo…</div>;
  const R = DEMO_RENDERERS[m.id];
  return R ? <R m={m} data={data} /> : <div className="empty">No demo for this module yet.</div>;
}

Object.assign(window, { ModuleDemo, TalkToUs, requestUrl });
