/* ============================================================
   VYNDR 2.0 — living-layer tick engine (§8).
   ONE interval, many subscribers (fan-out). Drives HeartbeatBar's
   elapsed-since-snapshot clock. Plain CommonJS so the React hook imports it
   AND Jest drives it manually via tick().

   Does NOT auto-start on import (would run in SSR/tests). The React hook
   calls start() on mount; tests call tick() directly. Animations are gated
   behind reduced-motion in the CSS layer (Session 33), not here — the tick
   only updates data.

   Session 57 (Phase 0) — the fake counters are DEAD. This used to carry a
   cosmetically auto-incrementing graded count, a sin-driven brain-%, and
   invented aPlus/cascades counts. All deleted: real numbers now come from
   /api/snapshot/summary (see LiveLayer). The tick survives ONLY as the 1s
   re-render pulse. Do not add display data back here.
   ============================================================ */

const INITIAL = { tick: 0 };

const liveTick = {
  listeners: new Set(),
  state: { ...INITIAL },
  _timer: null,

  subscribe(fn) {
    this.listeners.add(fn);
    return () => this.listeners.delete(fn);
  },

  _notify() {
    for (const fn of this.listeners) fn(this.state);
  },

  /** Advance one tick. New state object so React subscribers re-render. */
  tick() {
    this.state = { tick: this.state.tick + 1 };
    this._notify();
    return this.state;
  },

  start(intervalMs = 1000) {
    if (this._timer || typeof setInterval === 'undefined') return;
    this._timer = setInterval(() => this.tick(), intervalMs);
    if (this._timer && typeof this._timer.unref === 'function') this._timer.unref();
  },

  stop() {
    if (this._timer) {
      clearInterval(this._timer);
      this._timer = null;
    }
  },

  reset() {
    this.stop();
    this.state = { ...INITIAL };
    this.listeners.clear();
  },
};

module.exports = { liveTick, INITIAL };
