/* aevion.ai — award layer: scramble type, receipt ticker, boot sequence,
   session ledger HUD, opt-in console audio. All reduced-motion safe. */
const { useState: useStateF, useEffect: useEffectF, useRef: useRefF } = React;

const AEV_HEXCHARS = '0123456789abcdef';

function aevHash(s) {
  let h = 2166136261;
  for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 16777619); }
  return ('00000000' + (h >>> 0).toString(16)).slice(-8);
}

/* opt-in console tones — muted by default, tiny sine blips only */
const AevSound = {
  enabled: false, ctx: null,
  blip(freq, dur) {
    if (!this.enabled) { return; }
    try {
      this.ctx = this.ctx || new (window.AudioContext || window.webkitAudioContext)();
      const o = this.ctx.createOscillator();
      const g = this.ctx.createGain();
      o.type = 'sine'; o.frequency.value = freq || 880;
      g.gain.setValueAtTime(0.03, this.ctx.currentTime);
      g.gain.exponentialRampToValueAtTime(0.0001, this.ctx.currentTime + (dur || 0.12));
      o.connect(g); g.connect(this.ctx.destination);
      o.start(); o.stop(this.ctx.currentTime + (dur || 0.14));
    } catch (e) { /* audio unavailable */ }
  }
};

/* text that resolves from hex noise when scrolled into view */
function ScrambleText({ text, className }) {
  const ref = useRefF(null);
  const [out, setOut] = useStateF(text);
  const [run, setRun] = useStateF(false);
  useEffectF(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { return; }
    const io = new IntersectionObserver(es => {
      if (es.some(e => e.isIntersecting)) { setRun(true); io.disconnect(); }
    }, { threshold: 0.5 });
    if (ref.current) { io.observe(ref.current); }
    return () => io.disconnect();
  }, []);
  useEffectF(() => {
    if (!run) { return; }
    let tick = 0;
    const id = setInterval(() => {
      tick += 1;
      const resolved = Math.floor(tick * text.length / 26);
      if (resolved >= text.length) { setOut(text); clearInterval(id); return; }
      setOut(text.split('').map((ch, idx) =>
        idx < resolved || ch === ' ' ? ch : AEV_HEXCHARS[(Math.random() * 16) | 0]).join(''));
    }, 36);
    return () => clearInterval(id);
  }, [run]);
  return <span ref={ref} className={className}>{out}</span>;
}

/* slow receipt tape under the hero */
function ReceiptTicker() {
  const items = window.AEV_RECEIPTS.map(r =>
    r.id + ' · ' + r.type + ' · ' + r.state.toUpperCase() + ' · sha256:' + r.hash.slice(0, 12) + '…');
  const row = items.concat(items);
  return (
    <div className="rticker" aria-hidden="true">
      <div className="rticker-track">
        {row.map((t, i) => <span key={i}>{t}</span>)}
      </div>
    </div>
  );
}

/* boot-in verification sequence — skippable, session-once */
const AEV_BOOT_LINES = [
  'AEVION CONTROL PLANE · v0.1',
  'wordmark checksum ........ VERIFIED',
  'synthetic receipts ....... 6/6 LOADED',
  'claim ceilings ........... ENFORCED',
  'DON\u2019T TRUST US. VERIFY US.'
];

function BootOverlay({ onDone }) {
  const [n, setN] = useStateF(0);
  const leaving = n > AEV_BOOT_LINES.length;
  useEffectF(() => {
    const t = setTimeout(() => {
      if (n <= AEV_BOOT_LINES.length) { setN(n + 1); }
      else { onDone(); }
    }, n === 0 ? 150 : n <= AEV_BOOT_LINES.length ? 185 : 420);
    return () => clearTimeout(t);
  }, [n]);
  return (
    <div className="boot" data-leaving={leaving} onClick={onDone} role="presentation">
      <div className="boot-box">
        {AEV_BOOT_LINES.slice(0, n).map(l => <div key={l} className="boot-line">{l}</div>)}
        <span className="boot-caret" aria-hidden="true"></span>
      </div>
    </div>
  );
}

/* session ledger — the page audits itself as you scroll */
function LedgerHUD({ entries, total }) {
  const [open, setOpen] = useStateF(false);
  return (
    <div className="hud">
      <button className="hud-head" onClick={() => setOpen(!open)} aria-expanded={open}>
        <span className="aui-dot aui-c-green aui-pulse" style={{ width: '6px', height: '6px' }}></span>
        SESSION LEDGER {entries.length}/{total}
      </button>
      {open ? (
        <ul className="hud-list">
          {entries.map(e => (
            <li key={e.id}><span className="aui-c-green">PASS</span> {e.id} · {e.hash}</li>
          ))}
          {entries.length < total
            ? <li className="hud-pending">{total - entries.length} section{total - entries.length > 1 ? 's' : ''} unverified — keep scrolling</li>
            : <li className="hud-sealed">SESSION SEALED · sha256:{aevHash(entries.map(e => e.hash).join(''))}</li>}
        </ul>
      ) : null}
    </div>
  );
}

Object.assign(window, { AevSound, ScrambleText, ReceiptTicker, BootOverlay, LedgerHUD, aevHash });
