/** Звук и длительность эффекта «Взрыв» (`public/explosion.mp3` + WebM с альфой). */

import { getEffectsSfxGain } from './effectsSfxGain';

const EXPLOSION_SFX_VOLUME = 0.95;

/** Запас, если метаданные не прочитались (длина webm ~3.97 с). */
const DEFAULT_EXPLOSION_LIFE_MS = 4200;

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

/** VP8/VP9 WebM с `alpha_mode=1` — рендер через HTML `<video>`, не Pixi. */
export function explosionEffectVideoUrl(): string {
  return new URL('vfx/explosion/aerial-debris-smoke.webm', window.location.href).href;
}

let cachedExplosionSfxDurationMs: number | null = null;

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

/** Длительность визуала ≈ max(звук, webm), с разумными пределами. */
export async function getExplosionEffectLifeMs(): Promise<number> {
  const sfxMs = await getExplosionSfxDurationMs();
  const raw = Math.max(sfxMs, DEFAULT_EXPLOSION_LIFE_MS);
  return Math.min(60_000, Math.max(600, raw));
}

export async function playExplosionEffectSound(lifeMs: number): Promise<void> {
  try {
    const rawMs = await getExplosionSfxDurationMs();
    const target = Math.max(200, lifeMs);
    const rate = Math.max(0.25, Math.min(4, rawMs / target));
    const el = new Audio(explosionEffectSoundUrl());
    el.volume = Math.max(0, Math.min(1, EXPLOSION_SFX_VOLUME * getEffectsSfxGain()));
    el.playbackRate = rate;
    void el.play().catch(() => undefined);
  } catch {
    /* ignore */
  }
}
