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

  const state = {
    fre:                clone(seed.fre || []),
    frap:               clone(seed.frap || []),
    judgeOrders:        clone(seed.judgeOrders || []),
    stateRules:         clone(seed.stateRules || []),
    amendments:         clone(seed.amendments || []),
    proposedAmendments: clone(seed.proposedAmendments || []),
    motionTemplates:    clone(seed.motionTemplates || []),
    sanctionsFactors:   clone(seed.sanctionsFactors || []),
    deadlineIncidents:  clone(seed.deadlineIncidents || []),
    matterPins:         clone(seed.matterPins || []),
    subscriptions:      clone(seed.subscriptions || []),
    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:rb.' + topic, { detail: data })); } catch {}
    },
  };

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

  // ── Pin a rule to a matter ─────────────────────────────
  const pinRule = ({ matterId, ruleId, reason, context, pinnedBy }) => {
    const id = 'PIN-' + String(state.matterPins.length + 1).padStart(3, '0');
    const entry = { id, matterId, ruleId, reason: reason || '', context: context || '', pinnedBy: pinnedBy || 'User', date: new Date().toISOString().slice(0, 10) };
    state.matterPins.push(entry);
    audit('pin.added', pinnedBy, `Pinned ${ruleId} to ${matterId}`, ruleId);
    bus.emit('pin.added', entry);
    return entry;
  };

  const unpinRule = (id, user) => {
    const idx = state.matterPins.findIndex(p => p.id === id);
    if (idx < 0) return null;
    const [removed] = state.matterPins.splice(idx, 1);
    audit('pin.removed', user, `Unpinned ${removed.ruleId} from ${removed.matterId}`, removed.ruleId);
    bus.emit('pin.removed', removed);
    return removed;
  };

  // ── Rule subscriptions ─────────────────────────────────
  const subscribeRule = ({ ruleId, topic, user }) => {
    const id = 'SUB-' + String(state.subscriptions.length + 1).padStart(3, '0');
    const entry = { id, ruleId, topic: topic || 'amendments', user: user || 'User', created: new Date().toISOString().slice(0, 10) };
    state.subscriptions.push(entry);
    audit('subscription.added', user, `Subscribed to ${ruleId} (${topic})`, ruleId);
    bus.emit('subscription.added', entry);
    return entry;
  };

  const unsubscribeRule = (id, user) => {
    const idx = state.subscriptions.findIndex(s => s.id === id);
    if (idx < 0) return null;
    const [removed] = state.subscriptions.splice(idx, 1);
    audit('subscription.removed', user, `Unsubscribed from ${removed.ruleId}`, removed.ruleId);
    bus.emit('subscription.removed', removed);
    return removed;
  };

  // ── Record a deadline incident ─────────────────────────
  const logIncident = ({ rule, court, matter, severity, outcome, reportedBy }) => {
    const id = 'INC-' + String(state.deadlineIncidents.length + 1).padStart(3, '0');
    const entry = {
      id, rule, court, matter: matter || '—',
      severity: severity || 'high',
      outcome: outcome || '',
      date: new Date().toISOString().slice(0, 10),
      resolved: false,
    };
    state.deadlineIncidents.push(entry);
    audit('incident.logged', reportedBy, `${rule} missed in ${court}`, rule);
    bus.emit('incident.logged', entry);
    return entry;
  };

  const resolveIncident = (id, user) => {
    const inc = state.deadlineIncidents.find(i => i.id === id);
    if (!inc) return null;
    inc.resolved = true;
    audit('incident.resolved', user, `${inc.rule} incident ${id}`, inc.rule);
    bus.emit('incident.resolved', inc);
    return inc;
  };

  // ── Aggregations ───────────────────────────────────────
  const incidentsByRule = () => {
    const map = {};
    state.deadlineIncidents.forEach(inc => {
      if (!map[inc.rule]) map[inc.rule] = { rule: inc.rule, total: 0, critical: 0, high: 0, unresolved: 0 };
      map[inc.rule].total += 1;
      if (inc.severity === 'critical') map[inc.rule].critical += 1;
      if (inc.severity === 'high') map[inc.rule].high += 1;
      if (!inc.resolved) map[inc.rule].unresolved += 1;
    });
    return Object.values(map).sort((a, b) => b.total - a.total);
  };

  const incidentsByCourt = () => {
    const map = {};
    state.deadlineIncidents.forEach(inc => {
      if (!map[inc.court]) map[inc.court] = { court: inc.court, total: 0, critical: 0 };
      map[inc.court].total += 1;
      if (inc.severity === 'critical') map[inc.court].critical += 1;
    });
    return Object.values(map).sort((a, b) => b.total - a.total);
  };

  const pinsForMatter = (matterId) => state.matterPins.filter(p => p.matterId === matterId);
  const subscriptionsForUser = (user) => state.subscriptions.filter(s => s.user === user);

  // ── Send a deadline to the Calendar platform ───────────
  const pushToCalendar = ({ ruleId, ruleLabel, date, matter, assignee, priority, notes }) => {
    const entry = {
      source: 'rulebook',
      ruleId: ruleId || null,
      ruleLabel: ruleLabel || '',
      date: date || new Date().toISOString().slice(0, 10),
      matter: matter || '',
      assignee: assignee || '',
      priority: priority || 'high',
      notes: notes || '',
    };
    audit('calendar.pushed', assignee, `→ Calendar: ${ruleLabel} · ${date}`, ruleId);
    bus.emit('calendar.push', entry);
    try { window.dispatchEvent(new CustomEvent('arbiter:rb.calendar.push', { detail: entry })); } catch {}
    return entry;
  };

  // ── Send a discovery request shell to Discovery ────────
  const pushDiscoveryShell = ({ type, ruleId, matter, notes, requestedBy }) => {
    const entry = { source: 'rulebook', type, ruleId, matter, notes: notes || '', requestedBy: requestedBy || 'User', date: new Date().toISOString().slice(0, 10) };
    audit('discovery.pushed', requestedBy, `→ Discovery: ${type} shell (${ruleId})`, ruleId);
    bus.emit('discovery.push', entry);
    try { window.dispatchEvent(new CustomEvent('arbiter:rb.discovery.push', { detail: entry })); } catch {}
    return entry;
  };

  // ── Cross-platform bridges (listen) ────────────────────
  window.addEventListener('arbiter:cal.deadline.missed', (ev) => {
    const d = ev.detail || {};
    if (d.rule) logIncident({ rule: d.rule, court: d.court || '—', matter: d.matter || '—', severity: 'high', outcome: 'Missed — logged from Calendar' });
  });

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

  window.addEventListener('arbiter:rk.incident.logged', (ev) => {
    const d = ev.detail || {};
    if (d.relatedRule) audit('risk.incident', 'System', `Risk incident touched rule ${d.relatedRule}`, d.relatedRule);
  });

  const API = {
    state, bus, audit,
    pinRule, unpinRule,
    subscribeRule, unsubscribeRule,
    logIncident, resolveIncident,
    incidentsByRule, incidentsByCourt,
    pinsForMatter, subscriptionsForUser,
    pushToCalendar, pushDiscoveryShell,
  };

  window.RulebookStore = API;

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