/* OPHI-118 — shared HUD helpers used by every overlay.
 *
 * Exposes:
 *   - HUD.startClock(el)       — UTC ticker into the given element.
 *   - HUD.startSignal(el, opts) — signal-bar fluctuator.
 *   - HUD.scrambleReveal(...)  — cyberpunk decode/scramble used by landing.
 *
 * Designed to no-op if the target element isn't on the page, so the
 * base layout can include it unconditionally.
 */
(function (root) {
  'use strict';

  const pad = n => String(n).padStart(2, '0');

  function startClock(el) {
    if (!el) return;
    const tick = () => {
      const d = new Date();
      el.textContent =
        `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;
    };
    tick();
    setInterval(tick, 1000);
  }

  // n thresholds default to the original landing/loading/game distribution:
  //   r < .06 → 2 bars  (occasional drop)
  //   r < .70 → 3 bars  (typical)
  //   r < .95 → 4 bars
  //          → 5 bars  (occasional spike)
  function startSignal(el, opts) {
    if (!el) return;
    const profile = opts?.profile || 'normal';
    const FILL = '▮', EMPTY = '▯';
    const draw = n => FILL.repeat(n) + EMPTY.repeat(5 - n);
    setInterval(() => {
      const r = Math.random();
      let n;
      if (profile === 'strong') {
        n = r < 0.15 ? 3 : r < 0.65 ? 4 : 5;
      } else if (profile === 'degrading') {
        n = r < 0.45 ? 1 : r < 0.85 ? 2 : r < 0.97 ? 3 : 0;
      } else {
        n = r < 0.06 ? 2 : r < 0.70 ? 3 : r < 0.95 ? 4 : 5;
      }
      el.textContent = draw(n);
    }, 1500);
  }

  // ASCII-only glyph pool — DejaVu Mono renders these at 1ch each, so the
  // intermediate frames don't shift width.
  const GLITCH_GLYPHS = '01ABCDEFGHIJKLMNOPQRSTUVWXYZ#@*?!§%';
  const glyph = () => GLITCH_GLYPHS[(Math.random() * GLITCH_GLYPHS.length) | 0];
  const _scrambleHandles = new WeakMap();

  function scrambleReveal(el, finalText, opts) {
    opts = opts || {};
    const { scrambleMs = 360, stepMs = 50, resolveStepMs = 60 } = opts;
    const prev = _scrambleHandles.get(el);
    if (prev) { clearInterval(prev.s); clearInterval(prev.r); }
    const len = finalText.length;
    if (!len) {
      el.textContent = '';
      el.classList.remove('glitching');
      _scrambleHandles.delete(el);
      return;
    }
    el.classList.add('glitching');
    const scrambleSteps = Math.max(1, Math.floor(scrambleMs / stepMs));
    const handle = { s: null, r: null };
    _scrambleHandles.set(el, handle);
    let step = 0;
    handle.s = setInterval(() => {
      let s = '';
      for (let i = 0; i < len; i++) s += glyph();
      el.textContent = s;
      if (++step < scrambleSteps) return;
      clearInterval(handle.s); handle.s = null;
      let resolved = 0;
      handle.r = setInterval(() => {
        resolved++;
        let s = finalText.slice(0, resolved);
        for (let i = resolved; i < len; i++) s += glyph();
        el.textContent = s;
        if (resolved < len) return;
        clearInterval(handle.r); handle.r = null;
        el.textContent = finalText;
        el.classList.remove('glitching');
        _scrambleHandles.delete(el);
      }, resolveStepMs);
    }, stepMs);
  }

  root.HUD = { pad, startClock, startSignal, scrambleReveal };

  // Auto-bind: every overlay has #clock and #signal in the shared partial.
  document.addEventListener('DOMContentLoaded', () => {
    startClock(document.getElementById('clock'));
    const sigEl = document.getElementById('signal');
    if (sigEl) {
      const profile = sigEl.dataset.profile || 'normal';
      startSignal(sigEl, { profile });
    }
  });
})(typeof window !== 'undefined' ? window : globalThis);
