import confetti from "canvas-confetti";

type ConfettiFn = confetti.CreateTypes;

let _cannon: ConfettiFn | null = null;

function getCannon(): ConfettiFn {
  if (_cannon) return _cannon;

  const canvas = document.createElement("canvas");
  canvas.style.cssText =
    "position:fixed;inset:0;width:100vw;height:100vh;z-index:2147483647;pointer-events:none";
  document.body.appendChild(canvas);

  canvas.width = canvas.offsetWidth * (window.devicePixelRatio || 1);
  canvas.height = canvas.offsetHeight * (window.devicePixelRatio || 1);

  _cannon = confetti.create(canvas, { resize: true });
  return _cannon;
}

export function fireCelebration() {
  const fire = getCannon();
  const colors = ["#10b981", "#f59e0b", "#ef4444", "#6366f1", "#ec4899"];

  fire({
    particleCount: 80,
    spread: 100,
    origin: { y: 0.35 },
    colors,
    startVelocity: 45,
    ticks: 200,
  });

  const end = Date.now() + 2500;

  const frame = () => {
    if (Date.now() > end) return;

    fire({
      particleCount: 3,
      angle: 60,
      spread: 55,
      origin: { x: 0, y: 0.6 },
      colors,
      startVelocity: 35,
      ticks: 150,
    });
    fire({
      particleCount: 3,
      angle: 120,
      spread: 55,
      origin: { x: 1, y: 0.6 },
      colors,
      startVelocity: 35,
      ticks: 150,
    });

    requestAnimationFrame(frame);
  };

  setTimeout(frame, 300);
}

let _audioCtx: AudioContext | null = null;

function getAudioContext(): AudioContext {
  if (!_audioCtx || _audioCtx.state === "closed") {
    _audioCtx = new AudioContext();
  }
  return _audioCtx;
}

export function playChime() {
  try {
    const ctx = getAudioContext();
    if (ctx.state === "suspended") ctx.resume();

    const gain = ctx.createGain();
    gain.connect(ctx.destination);
    gain.gain.setValueAtTime(0.15, ctx.currentTime);
    gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 1.2);

    const notes = [523.25, 659.25, 783.99, 1046.5]; // C5, E5, G5, C6
    notes.forEach((freq, i) => {
      const osc = ctx.createOscillator();
      osc.type = "sine";
      osc.frequency.value = freq;

      const noteGain = ctx.createGain();
      noteGain.connect(gain);

      const start = ctx.currentTime + i * 0.12;
      noteGain.gain.setValueAtTime(0, start);
      noteGain.gain.linearRampToValueAtTime(0.3, start + 0.03);
      noteGain.gain.exponentialRampToValueAtTime(0.001, start + 0.6);

      osc.connect(noteGain);
      osc.start(start);
      osc.stop(start + 0.6);
    });
  } catch {
    // Audio not available — silent fallback
  }
}
