// RISK STORE — mutable state, pub/sub, APIs (pattern: DiscoveryStore, CalendarStore)
(function () {
  const clone = (x) => JSON.parse(JSON.stringify(x));
  const seed = window.RISK_DATA || {};

  const state = {
    register:           clone(seed.register || []),
    categories:         clone(seed.categories || []),
    scenarios:          clone(seed.scenarios || []),
    compliance:         clone(seed.compliance || []),
    mitigations:        clone(seed.mitigations || []),
    monteCarlo:         clone(seed.monteCarlo || {}),
    dependencies:       clone(seed.dependencies || []),
    evidenceLinks:      clone(seed.evidenceLinks || {}),
    auditLog:           clone(seed.auditLog || []),
    appetiteThresholds: clone(seed.appetiteThresholds || []),
    controlTests:       clone(seed.controlTests || []),
    treatmentDecisions: clone(seed.treatmentDecisions || []),
    insurancePolicies:  clone(seed.insurancePolicies || []),
    kriIndicators:      clone(seed.kriIndicators || []),
    triggerRules:       clone(seed.triggerRules || []),
    regulatoryWatch:    clone(seed.regulatoryWatch || []),
    incidents:          clone(seed.incidents || []),
    cyberRegister:      clone(seed.cyberRegister || []),
    clientPortfolios:   clone(seed.clientPortfolios || []),
    riskCommittee:      clone(seed.riskCommittee || []),
    reportTemplates:    clone(seed.reportTemplates || []),
    ermMaturity:        clone(seed.ermMaturity || []),
    ethicalWalls:       clone(seed.ethicalWalls || []),
    vendorPanel:        clone(seed.vendorPanel || []),
    clientRatings:      clone(seed.clientRatings || []),
    attorneyProfiles:   clone(seed.attorneyProfiles || []),
    settlementTrees:    clone(seed.settlementTrees || []),
    sensitivityFactors: clone(seed.sensitivityFactors || []),
    varResults:         clone(seed.varResults || {}),
    reserves:           clone(seed.reserves || []),
    bowTies:            clone(seed.bowTies || []),
    stressTests:        clone(seed.stressTests || []),
  };

  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:rk.' + topic, { detail: data })); } catch {}
    },
  };

  const audit = (riskId, action, user, detail) => {
    const entry = { date: new Date().toISOString().slice(0, 10), user: user || 'System', action, detail: detail || '', riskId: riskId || null };
    state.auditLog.unshift(entry);
    bus.emit('audit.logged', entry);
    return entry;
  };

  // ── Risk register ───────────────────────────────────────────
  const addRisk = (r) => {
    const id = r.id || 'RSK-' + String(state.register.length + 101).padStart(3, '0');
    const entry = { id, status: 'Active', trend: 'stable', controls: [], history: [], residualScore: r.score || 0, ...r };
    state.register.push(entry);
    audit(id, 'created', r.createdBy || 'System', r.name || '');
    bus.emit('risk.added', entry);
    return entry;
  };

  const updateRisk = (id, patch, reason) => {
    const idx = state.register.findIndex(r => r.id === id);
    if (idx < 0) return null;
    const before = state.register[idx];
    const after = { ...before, ...patch };
    if (patch.likelihood || patch.impact) {
      after.score = (patch.likelihood || before.likelihood) * (patch.impact || before.impact);
    }
    state.register[idx] = after;
    audit(id, 'updated', patch.updatedBy || 'User', reason || `Score ${before.score} → ${after.score}`);
    bus.emit('risk.updated', { id, before, after });
    return after;
  };

  // ── Treatment decisions ─────────────────────────────────────
  const recordTreatment = (riskId, strategy, rationale, cost, decidedBy) => {
    const entry = {
      id: 'TD-' + String(state.treatmentDecisions.length + 1).padStart(2, '0'),
      riskId, strategy, rationale, cost: cost || 0,
      decidedBy: decidedBy || 'User', date: new Date().toISOString().slice(0, 10),
      residualScore: (state.register.find(r => r.id === riskId) || {}).residualScore || 0,
    };
    state.treatmentDecisions.push(entry);
    audit(riskId, 'treatment.' + strategy, decidedBy, rationale);
    bus.emit('treatment.recorded', entry);
    return entry;
  };

  // ── Control tests ───────────────────────────────────────────
  const recordControlTest = (controlId, result, findings, owner) => {
    const c = state.controlTests.find(x => x.id === controlId);
    if (!c) return null;
    c.lastTested = new Date().toISOString().slice(0, 10);
    c.result = result; c.findings = findings || ''; if (owner) c.owner = owner;
    bus.emit('control.tested', c);
    return c;
  };

  // ── Mitigations ─────────────────────────────────────────────
  const updateMitigation = (id, patch) => {
    const m = state.mitigations.find(x => x.id === id);
    if (!m) return null;
    Object.assign(m, patch);
    if (patch.status === 'Complete') m.progress = 100;
    bus.emit('mitigation.updated', m);
    return m;
  };

  // ── Incidents ───────────────────────────────────────────────
  const logIncident = (inc) => {
    const entry = { id: 'INC-' + String(state.incidents.length + 1).padStart(2, '0'), date: new Date().toISOString().slice(0, 10), resolved: false, ...inc };
    state.incidents.push(entry);
    audit(inc.relatedRisk, 'incident.logged', inc.reportedBy, inc.description);
    bus.emit('incident.logged', entry);
    return entry;
  };

  // ── Stress test ─────────────────────────────────────────────
  const runStressTest = ({ scenario, impactedRisks, deltaScore, deltaLoss }) => {
    const baselineScore = impactedRisks.reduce((sum, id) => {
      const r = state.register.find(x => x.id === id); return sum + (r ? r.score : 0);
    }, 0);
    const entry = {
      id: 'ST-T' + (state.stressTests.length + 1),
      scenario, impactedRisks,
      newScore: baselineScore + (deltaScore || 0), baselineScore,
      deltaLoss: deltaLoss || 0,
      ran: new Date().toISOString().slice(0, 10),
    };
    state.stressTests.push(entry);
    bus.emit('stress.ran', entry);
    return entry;
  };

  // ── KRI check ───────────────────────────────────────────────
  const checkKRIs = () => {
    const breaches = state.kriIndicators.filter(k => k.current > k.threshold);
    bus.emit('kri.checked', { breaches, total: state.kriIndicators.length });
    return breaches;
  };

  // ── Trigger rule fire ───────────────────────────────────────
  const fireTrigger = (id) => {
    const t = state.triggerRules.find(x => x.id === id);
    if (!t || !t.enabled) return null;
    t.triggered = (t.triggered || 0) + 1;
    audit(null, 'trigger.fired', 'System', t.name);
    bus.emit('trigger.fired', t);
    return t;
  };

  // ── Appetite breach check ───────────────────────────────────
  const checkAppetite = () => {
    const breaches = state.appetiteThresholds.filter(a => a.status === 'breach');
    bus.emit('appetite.checked', { breaches, total: state.appetiteThresholds.length });
    return breaches;
  };

  // ── Reserves (ASC 450) ──────────────────────────────────────
  const setReserve = (matterId, estimate, category, reviewedBy) => {
    const r = state.reserves.find(x => x.matterId === matterId);
    if (!r) return null;
    r.estimate = estimate; r.ascCategory = category; r.lastReviewed = new Date().toISOString().slice(0, 10);
    audit(null, 'reserve.updated', reviewedBy, `${matterId}: ${category} · $${estimate}`);
    bus.emit('reserve.updated', r);
    return r;
  };

  // ── Insurance claim ─────────────────────────────────────────
  const triggerInsuranceNotice = (policyId, riskId, noticedBy) => {
    const p = state.insurancePolicies.find(x => x.id === policyId);
    if (!p) return null;
    audit(riskId, 'insurance.noticed', noticedBy, `${p.carrier} ${p.type}`);
    bus.emit('insurance.noticed', { policy: p, riskId });
    return p;
  };

  // ── Risk committee ──────────────────────────────────────────
  const closeCommittee = (id, decisions, minutesUrl) => {
    const m = state.riskCommittee.find(x => x.id === id);
    if (!m) return null;
    m.decisions = decisions || []; m.minutesUrl = minutesUrl || null;
    bus.emit('committee.closed', m);
    return m;
  };

  // ── Aggregations ────────────────────────────────────────────
  const aggregateByClient = () => state.clientPortfolios.slice();
  const aggregateByCategory = () => state.categories.map(c => ({
    ...c,
    count: state.register.filter(r => r.category === c.name).length,
    avgScore: (() => {
      const items = state.register.filter(r => r.category === c.name);
      return items.length ? +(items.reduce((s, r) => s + r.score, 0) / items.length).toFixed(1) : 0;
    })(),
  }));

  // ── Priority queue (risk-weighted) ──────────────────────────
  const priorityQueue = () => {
    return state.register
      .filter(r => r.status === 'Active')
      .map(r => ({
        id: r.id, name: r.name, matter: r.matter, owner: r.owner,
        score: r.score,
        urgencyDays: Math.max(0, Math.ceil((new Date(r.nextReview) - new Date('2026-04-20')) / 86400000)),
        priorityIndex: r.score * (r.trend === 'rising' ? 1.5 : r.trend === 'stable' ? 1.0 : 0.7),
      }))
      .sort((a, b) => b.priorityIndex - a.priorityIndex);
  };

  // ── Cross-platform bridges ──────────────────────────────────
  window.addEventListener('arbiter:dc.production.shipped', (ev) => {
    const p = ev.detail || {};
    audit(null, 'bridge.discovery.production', 'System', 'Discovery production shipped: ' + (p.id || ''));
  });

  window.addEventListener('arbiter:cal.deadline.missed', (ev) => {
    const d = ev.detail || {};
    audit(null, 'bridge.calendar.deadline-missed', 'System', 'Missed deadline: ' + (d.label || ''));
    bus.emit('calendar.deadline.missed', d);
  });

  window.addEventListener('arbiter:cal.cascade.ran', (ev) => {
    bus.emit('calendar.cascade.ran', ev.detail || {});
  });

  window.addEventListener('arbiter:jx.ruling.adverse', (ev) => {
    const r = ev.detail || {};
    audit(null, 'bridge.jurisdictions.ruling', 'System', 'Adverse ruling: ' + (r.case || ''));
  });

  window.addEventListener('arbiter:matter.opened', (ev) => {
    bus.emit('matter.focus', ev.detail || {});
  });

  const API = {
    state, bus, audit,
    addRisk, updateRisk,
    recordTreatment, recordControlTest,
    updateMitigation,
    logIncident,
    runStressTest,
    checkKRIs, fireTrigger, checkAppetite,
    setReserve,
    triggerInsuranceNotice,
    closeCommittee,
    aggregateByClient, aggregateByCategory,
    priorityQueue,
  };

  window.RiskStore = API;

  window.useRiskStore = (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;
  };
})();
