type Rarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';

const FREQS: Record<Rarity, number[]> = {
  common: [420],
  uncommon: [520, 680],
  rare: [620, 820, 1040],
  epic: [440, 660, 880, 1320],
  legendary: [330, 660, 990, 1320, 1760],
};

function getAudioContext(): AudioContext | null {
  const AudioCtx =
    window.AudioContext ||
    (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
  if (!AudioCtx) return null;
  return new AudioCtx();
}

export function playRaritySfx(rarity: string, enabled: boolean): void {
  if (!enabled) return;

  const ctx = getAudioContext();
  if (!ctx) return;

  const normalized = (['common', 'uncommon', 'rare', 'epic', 'legendary'].includes(rarity)
    ? rarity
    : 'common') as Rarity;
  const freqs = FREQS[normalized];
  const now = ctx.currentTime;
  const master = ctx.createGain();
  master.gain.setValueAtTime(normalized === 'legendary' ? 0.12 : 0.08, now);
  master.connect(ctx.destination);

  freqs.forEach((freq, index) => {
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    const start = now + index * 0.055;
    const duration = normalized === 'legendary' ? 0.34 : normalized === 'epic' ? 0.24 : 0.16;

    osc.type = normalized === 'common' ? 'sine' : normalized === 'legendary' ? 'triangle' : 'square';
    osc.frequency.setValueAtTime(freq, start);
    gain.gain.setValueAtTime(0.0001, start);
    gain.gain.exponentialRampToValueAtTime(0.65, start + 0.018);
    gain.gain.exponentialRampToValueAtTime(0.0001, start + duration);

    osc.connect(gain);
    gain.connect(master);
    osc.start(start);
    osc.stop(start + duration + 0.03);
  });

  window.setTimeout(() => {
    void ctx.close().catch(() => undefined);
  }, 900);
}

export function vibrate(pattern: number | number[], enabled: boolean): void {
  if (!enabled || !navigator.vibrate) return;
  navigator.vibrate(pattern);
}
