// EXECUTIVE STRATEGY / WAR ROOM v2 — mutable state, pub/sub, APIs
(function () {
  const clone = (x) => JSON.parse(JSON.stringify(x));
  const seed = window.EXEC_STRATEGY_DATA || {};

  const state = {
    lateralProposals:     clone(seed.lateralProposals || []),
    maTargets:            clone(seed.maTargets || []),
    strategicInitiatives: clone(seed.strategicInitiatives || []),
    stressScenarios:      clone(seed.stressScenarios || []),
    partners:             clone(seed.partners || []),
    retirements:          clone(seed.retirements || []),
    associates:           clone(seed.associates || []),
    promotionPipeline:    clone(seed.promotionPipeline || {}),
    clients:              clone(seed.clients || []),
    practices:            clone(seed.practices || []),
    clientPracticeMatrix: clone(seed.clientPracticeMatrix || {}),
    panelEvents:          clone(seed.panelEvents || []),
    gcSignals:            clone(seed.gcSignals || []),
    concentration:        clone(seed.concentration || {}),
    peerRates:            clone(seed.peerRates || []),
    lateralMoves:         clone(seed.lateralMoves || []),
    lateralMarketSummary: clone(seed.lateralMarketSummary || {}),
    aiTools:              clone(seed.aiTools || []),
    aiRoiSummary:         clone(seed.aiRoiSummary || {}),
    conflictsDeclined:    clone(seed.conflictsDeclined || []),
    auditLog:             [],
  };

  const bus = {
    _subs: {},
    on(topic, fn) {
      (this._subs[topic] = this._subs[topic] || []).push(fn);
      return () => { this._subs[topic] = (this._subs[topic] || []).filter(f => f !== fn); };
    },
    emit(topic, data) {
      (this._subs[topic] || []).forEach(fn => { try { fn(data); } catch (e) { console.error(e); } });
      (this._subs['*'] || []).forEach(fn => { try { fn({ topic, data }); } catch (e) { console.error(e); } });
      try { window.dispatchEvent(new CustomEvent('arbiter:wr.' + topic, { detail: data })); } catch {}
    },
  };

  const audit = (action, user, detail, ref) => {
    const entry = { ts: new Date().toISOString(), user: user || 'Exec Cmte', action, detail: detail || '', ref: ref || null };
    state.auditLog.unshift(entry);
    bus.emit('audit.logged', entry);
    return entry;
  };

  // ── WR1. Lateral decisions ──
  const advanceLateral = (id, nextStatus, user) => {
    const p = state.lateralProposals.find(x => x.id === id);
    if (!p) return null;
    const prev = p.status;
    p.status = nextStatus;
    audit('lateral.status', user, `${p.teamName}: ${prev} → ${nextStatus}`, id);
    bus.emit('lateral.status', p);
    return p;
  };
  const runLateralSensitivity = (id, portability, retention, user) => {
    const p = state.lateralProposals.find(x => x.id === id);
    if (!p) return null;
    const portAdj = 1 + (portability - p.portabilityPct) / 100;
    const retAdj = retention / 100;
    const adjusted = Math.round(p.fiveYrNPV * portAdj * retAdj);
    p.sensitivityResult = { portability, retention, adjustedNpv: adjusted };
    audit('lateral.sensitivity', user, `${p.teamName} @ port=${portability}% ret=${retention}%`, id);
    bus.emit('lateral.sensitivity', p);
    return p;
  };

  // ── WR2. M&A decisions ──
  const advanceMaTarget = (id, nextStatus, user) => {
    const t = state.maTargets.find(x => x.id === id);
    if (!t) return null;
    const prev = t.status;
    t.status = nextStatus;
    audit('ma.status', user, `${t.target}: ${prev} → ${nextStatus}`, id);
    bus.emit('ma.status', t);
    return t;
  };

  // ── WR3. Strategic plan ──
  const updateInitiative = (id, patch, user) => {
    const i = state.strategicInitiatives.find(x => x.id === id);
    if (!i) return null;
    Object.assign(i, patch);
    audit('plan.update', user, `${i.initiative} updated`, id);
    bus.emit('plan.update', i);
    return i;
  };

  // ── WR4. Stress test ──
  const activateScenario = (id, user) => {
    const s = state.stressScenarios.find(x => x.id === id);
    if (!s) return null;
    audit('stress.activated', user, `Scenario modeled: ${s.name}`, id);
    bus.emit('stress.activated', s);
    return s;
  };

  // ── WR5. Comp modeling ──
  const modelComp = (partnerId, proposedComp, user) => {
    const p = state.partners.find(x => x.id === partnerId);
    if (!p) return null;
    p.modeledComp = proposedComp;
    audit('comp.modeled', user, `${p.name}: proposed ${window.wr.money(proposedComp)}`, partnerId);
    bus.emit('comp.modeled', p);
    return p;
  };

  // ── WR6. Succession ──
  const openSuccessionPlan = (partnerId, user) => {
    const r = state.retirements.find(x => x.partnerId === partnerId);
    if (!r) return null;
    r.readiness = r.readiness === 'none' ? 'initial' : r.readiness;
    audit('succession.opened', user, `Succession plan opened for ${r.name}`, partnerId);
    bus.emit('succession.opened', r);
    return r;
  };

  // ── WR8. Retention ──
  const triggerRetentionPlay = (assocId, play, user) => {
    const a = state.associates.find(x => x.id === assocId);
    if (!a) return null;
    a.retentionPlay = { play, triggeredBy: user, triggeredAt: new Date().toISOString().slice(0, 10) };
    audit('retention.assoc', user, `${a.name}: ${play}`, assocId);
    bus.emit('retention.assoc', a);
    return a;
  };

  // ── WR9. Promotion scenario ──
  const selectPromotionScenario = (count, user) => {
    const s = state.promotionPipeline.scenarios.find(x => x.promotedThisYear === count);
    if (!s) return null;
    state.promotionPipeline.selected = s;
    audit('promotion.select', user, `Modeled ${count} new equity partners: PPP → ${window.wr.money(s.newPPP)}`);
    bus.emit('promotion.select', s);
    return s;
  };

  // ── WR11. White-space engagement ──
  const pursueWhiteSpace = (clientId, practice, user) => {
    const c = state.clients.find(x => x.id === clientId);
    if (!c) return null;
    c.pursuits = c.pursuits || [];
    c.pursuits.push({ practice, openedBy: user, openedAt: new Date().toISOString().slice(0, 10) });
    audit('whitespace.pursued', user, `${c.name}: ${practice}`, clientId);
    bus.emit('whitespace.pursued', { client: c.name, practice });
    return c;
  };

  // ── WR12. Panel response ──
  const submitPanelResponse = (id, response, user) => {
    const e = state.panelEvents.find(x => x.id === id);
    if (!e) return null;
    e.responseSubmitted = { response, submittedBy: user, submittedAt: new Date().toISOString().slice(0, 10) };
    audit('panel.response', user, `${e.client}: ${response}`, id);
    bus.emit('panel.response', e);
    return e;
  };

  // ── WR13. GC playbook ──
  const runGcPlaybook = (client, user) => {
    const g = state.gcSignals.find(x => x.client === client);
    if (!g) return null;
    g.playbookStatus = 'in-progress';
    g.playbookTriggeredBy = user;
    audit('gc.playbook', user, `${client} — ${g.priorGc} → ${g.newGc}`, client);
    bus.emit('gc.playbook', g);
    return g;
  };

  // ── WR18. Conflicts override request ──
  const requestConflictOverride = (id, reason, user) => {
    const c = state.conflictsDeclined.find(x => x.id === id);
    if (!c) return null;
    c.overrideRequest = { reason, requestedBy: user, requestedAt: new Date().toISOString().slice(0, 10), status: 'pending' };
    audit('conflict.override', user, `Override requested for ${c.matter}`, id);
    bus.emit('conflict.override', c);
    return c;
  };

  // ── Cross-platform bridges ──
  const pushLateralToCalendar = ({ lateralId, milestone, dueDate }) => {
    const entry = { source: 'execStrategy', lateralId, milestone, dueDate, ts: new Date().toISOString() };
    audit('calendar.push', 'System', `→ Calendar: ${milestone} on ${dueDate}`);
    bus.emit('calendar.push', entry);
    try { window.dispatchEvent(new CustomEvent('arbiter:wr.calendar.push', { detail: entry })); } catch {}
    return entry;
  };
  const pushRetentionToBilling = ({ partner, note }) => {
    const entry = { source: 'execStrategy', partner, note, ts: new Date().toISOString() };
    audit('billing.push', 'System', `→ Billing: retention flag on ${partner}`);
    bus.emit('billing.push', entry);
    try { window.dispatchEvent(new CustomEvent('arbiter:wr.billing.push', { detail: entry })); } catch {}
    return entry;
  };

  // ── Listeners ──
  window.addEventListener('arbiter:ba.retention.flagged', (ev) => {
    audit('billing.inbound', 'System', `Billing flagged partner retention: ${ev.detail?.partner || '?'}`);
  });
  window.addEventListener('arbiter:ba.churn.response', (ev) => {
    audit('billing.inbound', 'System', `Billing churn response on ${ev.detail?.client || '?'}`);
  });

  // ── Aggregations ──
  const activeLaterals     = () => state.lateralProposals.filter(p => p.status !== 'rejected' && p.status !== 'withdrawn');
  const totalLateralNpv    = () => activeLaterals().reduce((s, p) => s + (p.fiveYrNPV || 0), 0);
  const plansBehindSchedule = () => state.strategicInitiatives.filter(i => i.status === 'behind').length;
  const totalCommitted     = () => state.strategicInitiatives.reduce((s, i) => s + (i.committed || 0), 0);
  const totalDeployed      = () => state.strategicInitiatives.reduce((s, i) => s + (i.deployed || 0), 0);
  const totalRetentionRisk = () => state.retirements.reduce((s, r) => s + r.transferRisk, 0);
  const highAttritionCount = () => state.associates.filter(a => a.departureRisk >= 0.5).length;
  const associateCostAtRisk= () => state.associates.filter(a => a.departureRisk >= 0.5).reduce((s, a) => s + a.costOfLoss, 0);
  const totalWhiteSpace    = () => state.clients.reduce((s, c) => s + (c.whiteSpace || 0), 0);
  const convergenceAtRisk  = () => state.panelEvents.reduce((s, e) => s + Math.abs(e.estImpact), 0);
  const gcsChanged         = () => state.gcSignals.length;
  const gcBookAtRisk       = () => state.gcSignals.reduce((s, g) => s + g.bookAtRisk, 0);
  const conflictsRarYtd    = () => state.conflictsDeclined.filter(c => c.year === 2026).reduce((s, c) => s + c.estLifetimeValue, 0);
  const aiNetRoi           = () => state.aiTools.reduce((s, t) => s + (t.netRoi - t.subscription), 0);

  const API = {
    state, bus, audit,
    advanceLateral, runLateralSensitivity,
    advanceMaTarget,
    updateInitiative,
    activateScenario,
    modelComp,
    openSuccessionPlan,
    triggerRetentionPlay,
    selectPromotionScenario,
    pursueWhiteSpace,
    submitPanelResponse,
    runGcPlaybook,
    requestConflictOverride,
    pushLateralToCalendar, pushRetentionToBilling,
    activeLaterals, totalLateralNpv, plansBehindSchedule, totalCommitted, totalDeployed,
    totalRetentionRisk, highAttritionCount, associateCostAtRisk,
    totalWhiteSpace, convergenceAtRisk, gcsChanged, gcBookAtRisk,
    conflictsRarYtd, aiNetRoi,
  };

  window.ExecStrategyStore = API;

  window.useExecStrategyStore = (topics) => {
    const topicList = Array.isArray(topics) ? topics : [topics || '*'];
    const [, force] = React.useReducer(x => x + 1, 0);
    React.useEffect(() => {
      const offs = topicList.map(t => bus.on(t, () => force()));
      return () => offs.forEach(off => off());
    }, []);
    return state;
  };
})();
