/**
 * ModalOverlay — рендерит затемнение модальной сцены.
 * Задача 04. Подписан на ModalManager.setOnChange — получает state.
 *
 * Архитектура:
 *   - Слой ПОД GUI-overlay (z-index ниже GuiOverlay) но НАД Babylon-канвасом.
 *   - Если target='screen' — слой поверх ВСЕГО (включая GUI). z-index выше.
 *   - Spotlights через CSS mask-image: radial-gradient(...) — вырезает «дырки».
 *   - pointer-events: auto когда модал открыт (перехватывает клики кроме GUI).
 */

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

export default function ModalOverlay({ scene }) {
    const [state, setState] = useState(null);

    // Поллинг — надёжнее чем setOnChange callback, который может перетереться
    // или не вызваться если scene изменился на следующем кадре.
    useEffect(() => {
        if (!scene?.modalManager) return;
        let cancelled = false;
        const tick = () => {
            if (cancelled) return;
            const s = scene.modalManager.getState?.();
            // Снимок shallow-clone — иначе React не увидит изменение
            setState(s ? {
                id: s.id,
                fadePhase: s.fadePhase,
                currentAlpha: s.currentAlpha,
                opts: s.opts,
                spotlightScreens: s.spotlightScreens,
            } : null);
            requestAnimationFrame(tick);
        };
        tick();
        return () => { cancelled = true; };
    }, [scene]);

    if (!state || state.fadePhase === 'closed') return null;
    if (state.currentAlpha <= 0.001) return null;
    console.log('[ModalOverlay] RENDERING alpha=', state.currentAlpha.toFixed(2), 'phase=', state.fadePhase, 'target=', state.opts?.target);

    const opts = state.opts;
    const isScreen = opts.target === 'screen';
    const color = opts.darkenColor || '#000000';
    const alpha = Math.max(0, Math.min(1, state.currentAlpha));
    // RGBA bg
    const bg = _hexToRgba(color, alpha);

    // mask-image для spotlights (только для target='scene' — на 'screen' нет смысла)
    let maskStyle = {};
    if (!isScreen && Array.isArray(state.spotlightScreens) && state.spotlightScreens.length) {
        const softEdge = opts.spotlightSoftEdge ?? 40;
        const gradients = state.spotlightScreens.map(s => {
            const inner = Math.max(0, s.r - softEdge);
            const outer = s.r;
            // mask-image: внутри круга — transparent (вырезаем), снаружи — black (показываем затемнение)
            return `radial-gradient(circle at ${s.x.toFixed(0)}px ${s.y.toFixed(0)}px, transparent ${inner}px, black ${outer}px)`;
        });
        maskStyle = {
            WebkitMaskImage: gradients.join(', '),
            maskImage: gradients.join(', '),
            WebkitMaskComposite: 'source-in',
            maskComposite: 'intersect',
        };
    }

    // ВАЖНО pointer-events: none — иначе overlay перехватывает клики и кнопки модала не работают.
    // Затемнение — это просто визуальный фильтр, blockInput реализован в PlayerController.
    // zIndex:
    //   target='scene' → 24 (под GuiOverlay zIndex=25 чтобы GUI был ВИДЕН поверх затемнения)
    //   target='screen' → 60 (поверх GUI — закрывает ВСЁ)
    // Для 'screen' GUI модала всё равно поверх (GuiOverlay zIndex=25, наш ScreenOverlay 60,
    // GUI элементы модала рендерятся в GuiOverlay — поэтому надо ставить их в отдельный
    // слой ВЫШЕ overlay). Простой фикс: для screen ставим overlay на 24 тоже.
    const zIdx = 24;
    return (
        <div
            style={{
                position: 'absolute', inset: 0,
                background: bg,
                zIndex: zIdx,
                pointerEvents: 'none',  // НЕ перехватываем клики — иначе кнопки не работают
                transition: 'background-color 0.05s linear',
                ...maskStyle,
            }}
            data-modal-overlay={state.id}
        />
    );
}

function _hexToRgba(hex, a) {
    if (typeof hex !== 'string' || !hex.startsWith('#')) return `rgba(0,0,0,${a})`;
    let h = hex.slice(1);
    if (h.length === 3) h = h.split('').map(c => c + c).join('');
    if (h.length !== 6) return `rgba(0,0,0,${a})`;
    const r = parseInt(h.slice(0, 2), 16);
    const g = parseInt(h.slice(2, 4), 16);
    const b = parseInt(h.slice(4, 6), 16);
    return `rgba(${r},${g},${b},${a})`;
}
