/** HTML `<video>` для эффекта «Взрыв» — WebM с альфой (Pixi video/webp давали чёрный фон). */

import React, { useEffect, useMemo, useState } from 'react';

import type { EffectInstance, EffectsState, ExplosionInstance } from '../../../shared/types/effects';

import styles from './ExplosionVideoOverlay.module.css';

function explosionEffectVideoUrl(): string {
  return new URL('vfx/explosion/aerial-debris-smoke.webm', window.location.href).href;
}

type Viewport = { x: number; y: number; w: number; h: number };

type Props = {
  state: EffectsState | null;
  viewport: Viewport | null | undefined;
  /** Draft с пульта (пока ведём кисть) — тоже через video с альфой. */
  draft?: ExplosionInstance | null;
};

function isLiveExplosion(inst: EffectInstance, nowMs: number): inst is ExplosionInstance {
  if (inst.type !== 'explosion') return false;
  return nowMs - inst.createdAtMs < inst.lifetimeMs;
}

export function ExplosionVideoOverlay({ state, viewport, draft = null }: Props) {
  const [nowMs, setNowMs] = useState(() => state?.serverNowMs ?? Date.now());

  const explosions = useMemo(() => {
    const list = (state?.instances ?? []).filter((i): i is ExplosionInstance =>
      isLiveExplosion(i, nowMs),
    );
    if (draft && draft.type === 'explosion') {
      return [...list.filter((i) => i.id !== '__draft__'), draft];
    }
    return list;
  }, [draft, nowMs, state?.instances]);

  useEffect(() => {
    if (explosions.length === 0) return;
    const id = window.setInterval(() => {
      setNowMs(state?.serverNowMs ?? Date.now());
    }, 100);
    return () => window.clearInterval(id);
  }, [explosions.length, state?.serverNowMs]);

  useEffect(() => {
    setNowMs(state?.serverNowMs ?? Date.now());
  }, [state?.revision, state?.serverNowMs]);

  if (!viewport || explosions.length === 0) return null;
  const minDim = Math.min(viewport.w, viewport.h);

  return (
    <div className={styles.layer} aria-hidden>
      {explosions.map((inst) => {
        const sizePx = Math.max(16, inst.radiusN * minDim);
        const width = Math.max(sizePx * 4.2, minDim * 0.18);
        const isDraft = inst.id === '__draft__';
        return (
          <video
            key={inst.id}
            className={styles.video}
            style={{
              left: viewport.x + inst.at.x * viewport.w,
              top: viewport.y + inst.at.y * viewport.h,
              width,
              opacity: Math.max(0.35, Math.min(1, inst.intensity)),
            }}
            src={explosionEffectVideoUrl()}
            autoPlay={!isDraft}
            muted
            playsInline
            loop={false}
            preload="auto"
            ref={
              isDraft
                ? (el) => {
                    if (!el) return;
                    el.pause();
                    try {
                      el.currentTime = 0.05;
                    } catch {
                      /* ignore */
                    }
                  }
                : undefined
            }
          />
        );
      })}
    </div>
  );
}
