/* AZIS prototype — first-run intro: Update-Loading → 6.0 Glitch-Reveal ===
   Wrapped in IIFE damit Top-Level-`const`s (TRACES, REVEAL_ITEMS) nicht im
   globalen Scope landen — kollidieren sonst mit gleichnamigen Konstanten
   in app.js (siehe app.js REVEAL_ITEMS). */
(function () {

/* PCB traces (reused from the app's start/welcome circuit) */
const TRACES = [
  "M 0 18 H 50 V 5 H 65","M 0 42 H 30 V 80 H 65","M 0 78 H 65","M 0 105 H 22 V 130 H 60",
  "M 0 152 H 50 V 130 H 95","M 0 178 H 70 V 162 H 100","M 200 22 H 145 V 8 H 130",
  "M 200 50 H 168 V 80 H 130","M 200 92 H 130","M 200 120 H 178 V 142 H 140",
  "M 200 148 H 150 V 130 H 105","M 200 178 H 130 V 162 H 100","M 25 0 V 50 H 65",
  "M 55 0 V 12 H 70","M 100 0 V 10","M 140 0 V 12 H 130","M 170 0 V 50 H 135",
  "M 25 200 V 145 H 80 V 115","M 60 200 V 168 H 90","M 100 200 V 90","M 138 200 V 165 H 112",
  "M 175 200 V 150 H 120 V 90","M 18 60 V 110 H 48","M 182 60 V 110 H 152",
];

/* ---- Web-Audio synth: "biometric glitch logo reveal" (fallback if no mp3) ---- */
function synthReveal() {
  try {
    const AC = window.AudioContext || window.webkitAudioContext;
    if (!AC) return;
    const ctx = new AC();
    const t0 = ctx.currentTime;
    const master = ctx.createGain();
    master.gain.value = 0.9;
    master.connect(ctx.destination);

    // 1) riser: filtered noise sweeping up (0 → 0.7s)
    const noise = ctx.createBufferSource();
    const buf = ctx.createBuffer(1, ctx.sampleRate * 2, ctx.sampleRate);
    const d = buf.getChannelData(0);
    for (let i = 0; i < d.length; i++) d[i] = (Math.random() * 2 - 1) * 0.6;
    noise.buffer = buf;
    const bp = ctx.createBiquadFilter();
    bp.type = "bandpass"; bp.Q.value = 1.2;
    bp.frequency.setValueAtTime(300, t0);
    bp.frequency.exponentialRampToValueAtTime(4200, t0 + 0.7);
    const ng = ctx.createGain();
    ng.gain.setValueAtTime(0.0001, t0);
    ng.gain.exponentialRampToValueAtTime(0.5, t0 + 0.65);
    ng.gain.exponentialRampToValueAtTime(0.0001, t0 + 0.95);
    noise.connect(bp); bp.connect(ng); ng.connect(master);
    noise.start(t0); noise.stop(t0 + 1.0);

    // 2) digital glitch stutters (square blips, random)
    for (let i = 0; i < 6; i++) {
      const tt = t0 + 0.06 + Math.random() * 0.6;
      const o = ctx.createOscillator();
      o.type = "square";
      o.frequency.value = 600 + Math.random() * 2600;
      const g = ctx.createGain();
      g.gain.setValueAtTime(0.0001, tt);
      g.gain.linearRampToValueAtTime(0.10, tt + 0.004);
      g.gain.exponentialRampToValueAtTime(0.0001, tt + 0.05);
      o.connect(g); g.connect(master);
      o.start(tt); o.stop(tt + 0.06);
    }

    // 3) impact at ~0.72s: sub boom + bright lock-in ding
    const tImpact = t0 + 0.72;
    const sub = ctx.createOscillator();
    sub.type = "sine";
    sub.frequency.setValueAtTime(150, tImpact);
    sub.frequency.exponentialRampToValueAtTime(45, tImpact + 0.4);
    const sg = ctx.createGain();
    sg.gain.setValueAtTime(0.0001, tImpact);
    sg.gain.linearRampToValueAtTime(0.9, tImpact + 0.02);
    sg.gain.exponentialRampToValueAtTime(0.0001, tImpact + 0.6);
    sub.connect(sg); sg.connect(master);
    sub.start(tImpact); sub.stop(tImpact + 0.7);

    [880, 1320, 1760].forEach((f, i) => {
      const o = ctx.createOscillator();
      o.type = "triangle"; o.frequency.value = f;
      const g = ctx.createGain();
      g.gain.setValueAtTime(0.0001, tImpact);
      g.gain.linearRampToValueAtTime(0.14 / (i + 1), tImpact + 0.012);
      g.gain.exponentialRampToValueAtTime(0.0001, tImpact + 0.5 + i * 0.1);
      o.connect(g); g.connect(master);
      o.start(tImpact); o.stop(tImpact + 0.9);
    });

    // 4) shimmer tail
    const tail = ctx.createOscillator();
    tail.type = "sawtooth"; tail.frequency.value = 5200;
    const lp = ctx.createBiquadFilter(); lp.type = "lowpass";
    lp.frequency.setValueAtTime(6000, tImpact);
    lp.frequency.exponentialRampToValueAtTime(800, tImpact + 1.1);
    const tg = ctx.createGain();
    tg.gain.setValueAtTime(0.06, tImpact + 0.05);
    tg.gain.exponentialRampToValueAtTime(0.0001, tImpact + 1.2);
    tail.connect(lp); lp.connect(tg); tg.connect(master);
    tail.start(tImpact); tail.stop(tImpact + 1.3);

    setTimeout(() => ctx.close(), 2600);
  } catch (e) { /* no-op */ }
}

/* Preload the reveal sound as a blob (bare Audio(src) can mis-resolve) */
let _revealBlobUrl = null;
(function preloadReveal() {
  try {
    fetch("reveal.mp3").then((r) => (r.ok ? r.blob() : Promise.reject())).then((b) => { _revealBlobUrl = URL.createObjectURL(b); }).catch(() => {});
  } catch (e) {}
})();

/* Play real mp3 if available, else synth. Must be called from a user gesture. */
function playReveal() {
  const tryUrl = (url) => { const a = new Audio(url); a.volume = 0.95; return a.play(); };
  if (_revealBlobUrl) { tryUrl(_revealBlobUrl).catch(() => synthReveal()); return; }
  fetch("reveal.mp3").then((r) => (r.ok ? r.blob() : Promise.reject()))
    .then((b) => tryUrl(URL.createObjectURL(b)))
    .catch(() => synthReveal());
}

/* ---------- Update-wird-geladen (kept faithful; fake gesture-getter) ------ */
const ULOAD_TASKS = [
  "Verschlüsselte Daten migrieren",
  "Krypto-Module verifizieren",
  "UI-Komponenten initialisieren",
  "Service-Worker aktualisieren",
  "Konfiguration anwenden",
];
function UpdateLoading({ onContinue }) {
  const [step, setStep] = useState(0);
  const done = step >= ULOAD_TASKS.length;
  useEffect(() => {
    if (done) return;
    const id = setTimeout(() => setStep((s) => s + 1), step === 0 ? 500 : 460);
    return () => clearTimeout(id);
  }, [step, done]);
  return (
    <div className="uload">
      <div className="uload__bgGrid" aria-hidden="true" />
      <div className="uload__spinner" aria-hidden="true">
        <svg viewBox="0 0 64 64">
          <circle cx="32" cy="32" r="26" className="uload__track" />
          <circle cx="32" cy="32" r="26" className="uload__arc" />
        </svg>
      </div>
      <h2 className="uload__title">{done ? "Update abgeschlossen" : "Update wird geladen…"}</h2>
      <ul className="uload__tasks">
        {ULOAD_TASKS.map((tk, i) => (
          <li key={i} className={"uload__task" + (i < step ? " done" : i === step ? " active" : "")}>
            <span className="uload__marker">{i < step ? "✓" : "›"}</span>
            <span className="uload__label">{tk}</span>
          </li>
        ))}
      </ul>
      <div className="uload__progress"><div className="uload__bar" style={{ width: (step / ULOAD_TASKS.length * 100) + "%" }} /></div>
      <button className="uload__continue" disabled={!done} onClick={onContinue}>Weiter</button>
    </div>
  );
}

/* ---------- 6.0 Glitch-Reveal -------------------------------------------- */
const REVEAL_ITEMS = [
  { icon: "play", title: "Stempeln im Heute-Hero", where: "Start · oben" },
  { icon: "chart", title: "Monats-Saldo & Verlauf", where: "Start · Monats-Band" },
  { icon: "zap", title: "Konten griffbereit", where: "Start · Chips" },
  { icon: "moon", title: "Theme & Hell/Dunkel", where: "Einstellungen" },
];
function Reveal({ onDone }) {
  const [stage, setStage] = useState(0); // 0 build → 1 lock → 2 content
  useEffect(() => {
    const a = setTimeout(() => setStage(1), 1000);   // impact / lock
    const b = setTimeout(() => setStage(2), 1520);  // content in
    return () => { clearTimeout(a); clearTimeout(b); };
  }, []);
  return (
    <div className="reveal" data-stage={stage}>
      <svg className="reveal__circuit" viewBox="0 0 200 200" preserveAspectRatio="none" aria-hidden="true">
        {TRACES.map((d, i) => <path key={i} className="reveal__trace" style={{ animationDelay: (i * 26) + "ms" }} d={d} />)}
      </svg>
      <div className="reveal__scan" aria-hidden="true" />
      <div className="reveal__top">
        <div className="reveal__logo">
          <BrandLogo variant="blue" size={150} idp="rev" glitch />
          <span className="reveal__ghost reveal__ghost--r" aria-hidden="true"><BrandLogo variant="blue" size={150} idp="rgr" /></span>
          <span className="reveal__ghost reveal__ghost--c" aria-hidden="true"><BrandLogo variant="blue" size={150} idp="rgc" /></span>
        </div>
        <div className="reveal__eyebrow">Update erfolgreich</div>
        <h1 className="reveal__title" data-text="AZIS 6.0">AZIS <span className="reveal__ver">6.0</span></h1>
        <p className="reveal__sub">Willkommen zur neuen Oberfläche</p>
      </div>
      <div className="reveal__sheet">
        <div className="reveal__sheet-title">Was ist neu — und wo</div>
        <div className="reveal__list">
          {REVEAL_ITEMS.map((it, i) => (
            <div className="whl" key={i} style={{ animationDelay: (1620 + i * 90) + "ms" }}>
              <div className="whl__icon"><Icon name={it.icon} /></div>
              <div className="whl__text"><strong>{it.title}</strong><span className="whl__where">{"↳ " + it.where}</span></div>
            </div>
          ))}
        </div>
        <button className="reveal__cta" onClick={onDone}>Los geht's</button>
      </div>
    </div>
  );
}

/* ---------- Sequence controller ----------------------------------------- */
function IntroSequence({ onDone, startAt }) {
  const [phase, setPhase] = useState(startAt === "reveal" ? "reveal" : "loading");
  useEffect(() => {
    if (startAt === "reveal") playReveal(); // triggered by a user click (settings) → gesture OK
  }, [startAt]);
  const start = useCallback(() => {
    playReveal();          // user gesture → sound
    setPhase("reveal");
  }, []);
  return (
    <div className="intro">
      {phase === "loading"
        ? <UpdateLoading onContinue={start} />
        : <Reveal onDone={onDone} />}
    </div>
  );
}

window.IntroSequence = IntroSequence;

})();

