/**
 * Sound registry. To add a new effect, drop the file under
 * `js/assets/sounds/` and add a line to REGISTERED below.
 *
 * Names referenced from code that aren't in REGISTERED fall back to "click",
 * so the system feels alive end-to-end with one asset and stays consistent
 * as more are added.
 */

import clickUrl from '../../../assets/sounds/click.mp3';
import { soundEffects, type PlayOptions } from './engine';

/** Effect names referenced from code. Unmapped names fall back to "click". */
export type SoundName =
  | 'click'
  | 'key-tap'
  | 'key-action'
  | 'submit'
  | 'error'
  | 'open'
  | 'close';

/** Files that exist on disk. Add a line when you drop a new file. */
const REGISTERED: Partial<Record<SoundName, string>> = {
  click: clickUrl,
};

/** Per-sound default play options. Tuned for HUD feel — subtle and slightly varied. */
const SOUND_DEFAULTS: Record<SoundName, PlayOptions> = {
  click: { volume: 0.7, pitchVariance: 0.04 },
  'key-tap': { volume: 0.4, pitchVariance: 0.08, throttleMs: 25 },
  'key-action': { volume: 0.6, pitchVariance: 0.04 },
  submit: { volume: 0.85, pitchVariance: 0.02 },
  error: { volume: 0.7, pitchVariance: 0 },
  open: { volume: 0.6, pitchVariance: 0.03 },
  close: { volume: 0.5, pitchVariance: 0.03 },
};

const FALLBACK: SoundName = 'click';

let preloaded = false;

/** Preload every registered sound file. Idempotent. Called once at app start. */
export function preloadAllSounds(): void {
  if (preloaded) return;
  preloaded = true;
  for (const [name, url] of Object.entries(REGISTERED)) {
    if (url) void soundEffects.preload(name, url);
  }
}

/** Play a sound by name. Falls back to "click" if no dedicated file is registered. */
export function playSound(name: SoundName, override?: PlayOptions) {
  const defaults = SOUND_DEFAULTS[name];
  const resolvedName = REGISTERED[name] ? name : FALLBACK;
  soundEffects.play(resolvedName, { ...defaults, ...override });
}
