// Zentrales Haptik- und Sound-Feedback, ganz ohne externe Pakete.
//
// - Haptik: navigator.vibrate (in der installierten App/Android-TWA spuerbar,
//   im normalen Browser meist ein No-op).
// - Sound: dezenter, synthetischer Drei-Noten-Klang ueber die Web Audio API -
//   kein Audio-Asset noetig.
//
// Beide sind ueber LocalStorage-Toggles in den Einstellungen abschaltbar
// (Default: aktiviert).

const HAPTICS_KEY = 'yumder_haptics_enabled';
const SOUND_KEY = 'yumder_sound_enabled';

function readToggle(key: string): boolean {
  if (typeof window === 'undefined') return true;
  try {
    return window.localStorage.getItem(key) !== '0';
  } catch {
    return true;
  }
}

function writeToggle(key: string, enabled: boolean): void {
  if (typeof window === 'undefined') return;
  try {
    window.localStorage.setItem(key, enabled ? '1' : '0');
  } catch {
    // LocalStorage kann deaktiviert sein - dann einfach nichts speichern.
  }
}

export function isHapticsEnabled(): boolean {
  return readToggle(HAPTICS_KEY);
}

export function setHapticsEnabled(enabled: boolean): void {
  writeToggle(HAPTICS_KEY, enabled);
}

export function isSoundEnabled(): boolean {
  return readToggle(SOUND_KEY);
}

export function setSoundEnabled(enabled: boolean): void {
  writeToggle(SOUND_KEY, enabled);
}

/** Kurzes Vibrations-Muster, z. B. bei einem Match. */
export function hapticMatch(): void {
  if (!isHapticsEnabled()) return;
  try {
    navigator.vibrate?.([30, 50, 30]);
  } catch {
    // Vibration ist rein dekorativ - Fehler nie nach aussen tragen.
  }
}

let audioCtx: AudioContext | null = null;

function ensureAudioCtx(): AudioContext | null {
  try {
    const Ctor = window.AudioContext || (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
    if (!Ctor) return null;
    if (!audioCtx) audioCtx = new Ctor();
    if (audioCtx.state === 'suspended') void audioCtx.resume();
    return audioCtx;
  } catch {
    return null;
  }
}

/** Dezenter Aufsteig-Dreiklang (C5-E5-G5) als Match-Jingle. */
export function playMatchSound(): void {
  if (!isSoundEnabled()) return;
  const ctx = ensureAudioCtx();
  if (!ctx) return;
  try {
    const now = ctx.currentTime;
    const notes = [523.25, 659.25, 783.99];
    notes.forEach((freq, i) => {
      const osc = ctx.createOscillator();
      const gain = ctx.createGain();
      osc.type = 'sine';
      osc.frequency.value = freq;
      const t = now + i * 0.09;
      gain.gain.setValueAtTime(0, t);
      gain.gain.linearRampToValueAtTime(0.2, t + 0.02);
      gain.gain.exponentialRampToValueAtTime(0.0001, t + 0.5);
      osc.connect(gain);
      gain.connect(ctx.destination);
      osc.start(t);
      osc.stop(t + 0.55);
    });
  } catch {
    // Audio kann blockiert sein (Autoplay-Policy) - stillschweigend ignorieren.
  }
}

/** Beides zusammen, z. B. wenn ein neues Match bestaetigt wird. */
export function celebrateMatch(): void {
  playMatchSound();
  hapticMatch();
}
