import React, { useEffect, useState, useRef } from 'react';
import Icon from './Icon';

/**
 * GameHud — слой UI поверх viewport в Play-режиме.
 *
 * Получает команды от game.ui.* через ref-API:
 *   hudRef.current.handle({ cmd, payload })
 *
 * Поддерживает:
 *   - ui.set { id, text, opts? } — показать или обновить именованную метку.
 *     Если text == null — убрать.
 *     opts: { x, y } в %, { color, size }.
 *     Спец. id: '__score' (правый верх), '__timer' (правый верх под счётом).
 *   - ui.flash { text, seconds } — большой текст по центру на N секунд.
 *   - ui.clear — стереть всё.
 *
 * Props:
 *   visible — true в Play-режиме
 *   hudRef  — useRef для прокидывания handle
 */

function _optsEqual(a, b) {
    if (a === b) return true;
    if (!a || !b) return false;
    return a.x === b.x && a.y === b.y && a.color === b.color && a.size === b.size;
}

const DEFAULT_LABEL_STYLE = {
    fontSize: 18,
    fontWeight: 700,
    color: '#fff',
    textShadow: '0 2px 6px rgba(0,0,0,0.7), 0 0 2px rgba(0,0,0,0.9)',
    pointerEvents: 'none',
    fontFamily: '"Roboto Condensed", system-ui, sans-serif',
};

function GameHud({ visible, hudRef }) {
    // labels: { id: { text, opts } }
    const [labels, setLabels] = useState({});
    // flash: { text, expiresAt } | null
    const [flash, setFlash] = useState(null);

    // hide-таймер для flash
    const flashTimerRef = useRef(null);

    // Регистрируем handle в hudRef чтобы родитель мог посылать команды
    useEffect(() => {
        if (!hudRef) return;
        hudRef.current = {
            handle: ({ cmd, payload }) => {
                if (cmd === 'ui.set') {
                    const { id, text, opts } = payload || {};
                    if (!id) return;
                    setLabels((prev) => {
                        const cur = prev[id];
                        // Диф: если ничего не поменялось — возвращаем тот же объект,
                        // React не перерендерит. Это критично для скриптов которые
                        // вызывают ui.set каждый кадр (60 fps) с одним и тем же текстом —
                        // без диффа React всё равно перерисовывает HUD каждый кадр.
                        if (text == null || text === '') {
                            if (!cur) return prev;
                            const next = { ...prev };
                            delete next[id];
                            return next;
                        }
                        const newOpts = opts || cur?.opts || null;
                        if (cur && cur.text === text && _optsEqual(cur.opts, newOpts)) return prev;
                        return { ...prev, [id]: { text, opts: newOpts } };
                    });
                } else if (cmd === 'ui.flash') {
                    const seconds = Number(payload?.seconds) || 2;
                    if (flashTimerRef.current) clearTimeout(flashTimerRef.current);
                    setFlash({ text: payload?.text || '', key: Date.now() });
                    flashTimerRef.current = setTimeout(() => setFlash(null), seconds * 1000);
                } else if (cmd === 'ui.clear') {
                    setLabels({});
                    setFlash(null);
                    if (flashTimerRef.current) clearTimeout(flashTimerRef.current);
                }
            },
            // Полный сброс HUD при exit Play
            reset: () => {
                setLabels({});
                setFlash(null);
                if (flashTimerRef.current) clearTimeout(flashTimerRef.current);
            },
        };
    }, [hudRef]);

    if (!visible) return null;

    // Спец. метки (счёт, таймер) — фиксированная позиция в правом верхнем углу.
    // Произвольные метки (с opts.x/y) — позиционируем по их opts.
    // Произвольные метки без opts — стек слева сверху.
    const score = labels['__score'];
    const timer = labels['__timer'];
    const otherIds = Object.keys(labels).filter(id => id !== '__score' && id !== '__timer');

    return (
        <div style={{
            position: 'absolute',
            inset: 0,
            pointerEvents: 'none',
            zIndex: 30,
            overflow: 'hidden',
        }}>
            {/* Счёт + таймер в правом верхнем углу */}
            {(score || timer) && (
                <div style={{
                    position: 'absolute',
                    top: 14, right: 16,
                    display: 'flex', flexDirection: 'column', gap: 4,
                    alignItems: 'flex-end',
                    ...DEFAULT_LABEL_STYLE,
                }}>
                    {score && (
                        <div style={{ background: 'rgba(15,12,8,0.55)', padding: '6px 14px', borderRadius: 6 }}>
                            {score.text}
                        </div>
                    )}
                    {timer && (
                        <div style={{
                            background: 'rgba(15,12,8,0.55)',
                            padding: '6px 14px', borderRadius: 6,
                            fontVariantNumeric: 'tabular-nums',
                        }}>
                            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                                <Icon name="clock" size={14} /> {timer.text}
                            </span>
                        </div>
                    )}
                </div>
            )}

            {/* Произвольные метки */}
            {otherIds.map((id, i) => {
                const lbl = labels[id];
                const o = lbl.opts || {};
                const hasPos = typeof o.x === 'number' || typeof o.y === 'number';
                const style = {
                    ...DEFAULT_LABEL_STYLE,
                    fontSize: o.size || DEFAULT_LABEL_STYLE.fontSize,
                    color: o.color || DEFAULT_LABEL_STYLE.color,
                    background: 'rgba(15,12,8,0.55)',
                    padding: '4px 10px',
                    borderRadius: 5,
                    // длинные подписи переносятся и остаются по центру,
                    // не вылезая за края экрана
                    textAlign: 'center',
                    maxWidth: '70vw',
                    whiteSpace: 'normal',
                    wordBreak: 'break-word',
                };
                if (hasPos) {
                    return (
                        <div key={id} style={{
                            ...style,
                            position: 'absolute',
                            left: typeof o.x === 'number' ? `${o.x}%` : undefined,
                            top: typeof o.y === 'number' ? `${o.y}%` : undefined,
                            transform: 'translate(-50%, -50%)',
                        }}>{lbl.text}</div>
                    );
                }
                // Без позиции — стек в левом верхнем углу
                return (
                    <div key={id} style={{
                        ...style,
                        position: 'absolute',
                        left: 16,
                        top: 14 + i * 32,
                    }}>{lbl.text}</div>
                );
            })}

            {/* Flash-текст по центру */}
            {flash && (
                <div
                    key={flash.key}
                    style={{
                        position: 'absolute',
                        left: '50%', top: '38%',
                        transform: 'translate(-50%, -50%)',
                        fontSize: 42,
                        fontWeight: 800,
                        color: '#fff',
                        textShadow: '0 4px 16px rgba(0,0,0,0.8), 0 0 4px rgba(0,0,0,1)',
                        textAlign: 'center',
                        pointerEvents: 'none',
                        animation: 'kubikonHudFlash 0.4s cubic-bezier(0.2, 0.8, 0.3, 1.2)',
                    }}
                >
                    {flash.text}
                </div>
            )}
            {/* Inline keyframes — без CSS-modules */}
            <style>{`
                @keyframes kubikonHudFlash {
                    0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.7); }
                    60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
                    100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
                }
            `}</style>
        </div>
    );
}

export default GameHud;
