/** Звук и длительность эффекта «Заморозка» (`public/zamorozka.mp3`). */

import { getEffectsSfxGain } from './effectsSfxGain';

const DEFAULT_FREEZE_LIFE_MS = 820;

const FREEZE_SFX_BASE_VOLUME = 0.88;
/** На 25% тише базовой громкости эффекта (до множителя «Звук эффектов»). */
export const FREEZE_SFX_VOLUME = FREEZE_SFX_BASE_VOLUME * 0.75;

export function freezeEffectSoundUrl(): string {
  return new URL('zamorozka.mp3', window.location.href).href;
}

let cachedFreezeSfxDurationMs: number | null = null;

/** Длительность трека в мс (кэш после первого чтения метаданных). */
export function getFreezeSfxDurationMs(): Promise<number> {
  if (cachedFreezeSfxDurationMs !== null) {
    return Promise.resolve(cachedFreezeSfxDurationMs);
  }
  const url = freezeEffectSoundUrl();
  return new Promise((resolve) => {
    const a = new Audio();
    const done = (ms: number): void => {
      cachedFreezeSfxDurationMs = ms;
      a.removeAttribute('src');
      resolve(ms);
    };
    a.addEventListener('loadedmetadata', () => {
      const d = a.duration;
      done(Number.isFinite(d) && d > 0 ? Math.round(d * 1000) : DEFAULT_FREEZE_LIFE_MS);
    });
    a.addEventListener('error', () => done(DEFAULT_FREEZE_LIFE_MS));
    a.src = url;
    a.load();
  });
}

/** Длительность полноэкранной заморозки и льда — по времени звука, с разумными пределами. */
export async function getFreezeEffectLifeMs(): Promise<number> {
  const raw = await getFreezeSfxDurationMs();
  return Math.min(45_000, Math.max(400, raw));
}

export function playFreezeEffectSound(): void {
  try {
    const el = new Audio(freezeEffectSoundUrl());
    el.volume = Math.max(0, Math.min(1, FREEZE_SFX_VOLUME * getEffectsSfxGain()));
    void el.play().catch(() => undefined);
  } catch {
    /* ignore */
  }
}
