/** オーディオの公開API。main.ts はここだけを見ればよい。 */
import type { GameState } from '../sim/state';
import { stopAmbience } from './ambience';
import { ensureAudio, isMuted, masterVolume, setMasterVolume, setMuted } from './engine';
import { startMusic, stopMusic } from './music';
import { reactToState, resetReactor } from './reactor';
import { playSfx } from './sfx';

let unlocked = false;

/**
 * ブラウザの自動再生制限があるため、最初のユーザー操作でオーディオを起こす。
 * 起きたらBGMと環境音のループを開始する。
 */
export function initAudio(): void {
  const unlock = (): void => {
    if (unlocked) return;
    const b = ensureAudio();
    if (!b) return;
    unlocked = true;
    if (!isMuted()) startMusic();
    window.removeEventListener('pointerdown', unlock);
    window.removeEventListener('keydown', unlock);
  };
  window.addEventListener('pointerdown', unlock);
  window.addEventListener('keydown', unlock);
}

export function audioUnlocked(): boolean {
  return unlocked;
}

/** 毎フレーム呼ぶ。状態の差分から効果音と環境音を決める。 */
export function updateAudio(s: GameState): void {
  if (!unlocked) return;
  reactToState(s);
}

export function toggleMute(next: boolean): void {
  setMuted(next);
  if (next) {
    stopMusic();
    stopAmbience();
  } else if (unlocked) {
    startMusic();
  }
}

/** ゲームをやり直した時に差分の基準をリセットする。 */
export function resetAudio(): void {
  resetReactor();
}

export { getBuses } from './engine';
export { isMusicPlaying, musicPosition, setMusicIntensity } from './music';
export { isMuted, masterVolume, playSfx, setMasterVolume };
