// flippy-thunder-v3.jsx — lightning + audio + right-click + ratio lock

// =====================================================================
// LightningStorm — random acid-green flashes + zigzag bolts
// =====================================================================
const LightningStorm = ({ enabled = true }) => {
  const flashRef = useRef(null);
  const boltRef = useRef(null);
  useEffect(() => {
    if (!enabled) return;
    let alive = true;
    let timeoutId;

    const fireBolt = () => {
      if (!alive) return;
      const flash = flashRef.current;
      const bolt = boltRef.current;
      if (!flash || !bolt) return;

      // generate random zigzag path
      const w = window.innerWidth;
      const h = window.innerHeight;
      const startX = Math.random() * w;
      let path = `M ${startX} 0 `;
      let x = startX;
      let y = 0;
      const steps = 10 + Math.floor(Math.random() * 6);
      for (let i = 0; i < steps; i++) {
        x += (Math.random() - 0.5) * 80;
        y += h / steps;
        path += `L ${x} ${y} `;
      }
      const pathEl = bolt.querySelector("path");
      if (pathEl) pathEl.setAttribute("d", path);

      // trigger flash CSS animation
      flash.classList.remove("flash-on");
      bolt.classList.remove("bolt-on");
      // force reflow then add class
      // eslint-disable-next-line no-unused-expressions
      void flash.offsetWidth;
      flash.classList.add("flash-on");
      bolt.classList.add("bolt-on");

      // fire a custom event so the audio can sync
      window.dispatchEvent(new CustomEvent("flippy:lightning"));

      // schedule next
      const delay = 3500 + Math.random() * 8500;
      timeoutId = setTimeout(fireBolt, delay);
    };

    // initial delay
    timeoutId = setTimeout(fireBolt, 2500 + Math.random() * 2000);
    return () => { alive = false; if (timeoutId) clearTimeout(timeoutId); };
  }, [enabled]);

  return (
    <div style={{ display: "contents" }}>
      <div ref={flashRef} className="lightning-flash" aria-hidden="true" />
      <svg
        ref={boltRef}
        className="lightning-bolt"
        viewBox={`0 0 ${typeof window !== "undefined" ? window.innerWidth : 1920} ${typeof window !== "undefined" ? window.innerHeight : 1080}`}
        preserveAspectRatio="none"
        aria-hidden="true"
      >
        <path d="M 0 0 L 0 0" fill="none" stroke="#b9ff1f" strokeWidth="3" strokeLinecap="round" strokeLinejoin="miter" />
      </svg>
    </div>
  );
};

// =====================================================================
// AmbientAudio — procedurally-generated thunder ambience using Web Audio API.
// Mute toggle stored in localStorage. User gesture starts the audio context.
// =====================================================================
const AmbientAudio = () => {
  const [armed, setArmed] = useState(false);
  const [muted, setMuted] = useState(() => {
    try { return localStorage.getItem("flippy-muted") === "on"; } catch { return false; }
  });
  const ctxRef = useRef(null);
  const masterRef = useRef(null);

  // Build & start the audio graph on first user gesture
  const start = useCallback(() => {
    if (ctxRef.current) return;
    try {
      const AC = window.AudioContext || window.webkitAudioContext;
      const ctx = new AC();
      ctxRef.current = ctx;

      const master = ctx.createGain();
      master.gain.value = muted ? 0 : 0.18;
      master.connect(ctx.destination);
      masterRef.current = master;

      // Low rumble: brown-noise generator → low-pass filter
      const bufferSize = 2 * ctx.sampleRate;
      const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
      const data = buffer.getChannelData(0);
      let lastOut = 0;
      for (let i = 0; i < bufferSize; i++) {
        const white = Math.random() * 2 - 1;
        lastOut = (lastOut + 0.02 * white) / 1.02;
        data[i] = lastOut * 3.5;
      }
      const noise = ctx.createBufferSource();
      noise.buffer = buffer;
      noise.loop = true;

      const lp = ctx.createBiquadFilter();
      lp.type = "lowpass";
      lp.frequency.value = 220;

      const noiseGain = ctx.createGain();
      noiseGain.gain.value = 0.45;

      noise.connect(lp).connect(noiseGain).connect(master);
      noise.start();

      // Slow LFO modulating the low-pass cutoff
      const lfo = ctx.createOscillator();
      const lfoGain = ctx.createGain();
      lfo.frequency.value = 0.07;
      lfoGain.gain.value = 80;
      lfo.connect(lfoGain).connect(lp.frequency);
      lfo.start();

      // Thunder crack triggered by the lightning event (synced to bolt)
      const thunder = () => {
        if (!ctxRef.current) return;
        const dur = 1.4 + Math.random() * 1.8;
        const bs = ctx.sampleRate * dur;
        const b = ctx.createBuffer(1, bs, ctx.sampleRate);
        const d = b.getChannelData(0);
        let lo = 0;
        for (let i = 0; i < bs; i++) {
          const w = Math.random() * 2 - 1;
          lo = (lo + 0.018 * w) / 1.018;
          d[i] = lo * 6 * Math.pow(1 - i / bs, 1.6);
        }
        const src = ctx.createBufferSource();
        src.buffer = b;
        const gn = ctx.createGain();
        gn.gain.value = 0;
        gn.gain.setValueAtTime(0, ctx.currentTime);
        gn.gain.linearRampToValueAtTime(0.85, ctx.currentTime + 0.04);
        gn.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + dur);
        const flt = ctx.createBiquadFilter();
        flt.type = "lowpass";
        flt.frequency.value = 600 + Math.random() * 800;
        src.connect(flt).connect(gn).connect(master);
        src.start();
        src.stop(ctx.currentTime + dur);
      };

      const onLightning = () => {
        // small delay so sound trails the visual flash (felt realistic)
        setTimeout(thunder, 80 + Math.random() * 280);
      };
      window.addEventListener("flippy:lightning", onLightning);
      // store remover
      ctxRef.current._unsub = () => window.removeEventListener("flippy:lightning", onLightning);

      setArmed(true);
    } catch (e) {
      // ignore — audio context disallowed
    }
  }, [muted]);

  useEffect(() => {
    if (!masterRef.current || !ctxRef.current) return;
    const target = muted ? 0 : 0.18;
    try {
      masterRef.current.gain.cancelScheduledValues(ctxRef.current.currentTime);
      masterRef.current.gain.linearRampToValueAtTime(target, ctxRef.current.currentTime + 0.4);
    } catch {}
    try { localStorage.setItem("flippy-muted", muted ? "on" : "off"); } catch {}
  }, [muted]);

  useEffect(() => {
    const handler = () => {
      start();
      if (muted === false) {
        try { masterRef.current && (masterRef.current.gain.value = 0.18); } catch {}
      }
    };
    window.addEventListener("pointerdown", handler, { once: true });
    window.addEventListener("keydown", handler, { once: true });
    return () => {
      window.removeEventListener("pointerdown", handler);
      window.removeEventListener("keydown", handler);
    };
  }, [start, muted]);

  return (
    <button
      type="button"
      className={`audio-toggle ${muted ? "muted" : "on"}`}
      onClick={() => {
        if (!ctxRef.current) start();
        setMuted((m) => !m);
      }}
      aria-label={muted ? "Unmute ambient thunder" : "Mute ambient thunder"}
      title={muted ? "UNMUTE" : "MUTE"}
    >
      {muted ? (
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
          <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
          <line x1="23" y1="9" x2="17" y2="15"/>
          <line x1="17" y1="9" x2="23" y2="15"/>
        </svg>
      ) : (
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
          <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
          <path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/>
        </svg>
      )}
    </button>
  );
};

// =====================================================================
// disable right-click + drag (light hardening, not security)
// =====================================================================
const DisableRightClick = () => {
  useEffect(() => {
    const c = (e) => { e.preventDefault(); };
    const d = (e) => {
      // allow text selection but block image drag
      if (e.target.tagName === "IMG") e.preventDefault();
    };
    document.addEventListener("contextmenu", c);
    document.addEventListener("dragstart", d);
    return () => {
      document.removeEventListener("contextmenu", c);
      document.removeEventListener("dragstart", d);
    };
  }, []);
  return null;
};

Object.assign(window, { LightningStorm, AmbientAudio, DisableRightClick });
