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) {
    // Расширенный compare — учитываем все поля стилизации.
    if (a === b) return true;
    if (!a || !b) return false;
    const keys = ['x','y','color','size','textSize','bold','bg','border',
                  'borderRadius','padding','w','h','textAlign','anchor'];
    for (const k of keys) {
        if (a[k] !== b[k]) return false;
    }
    return true;
}
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 || {};
                // Поддерживаем как старый формат opts (x/y в %, color, size),
                // так и расширенный (bg, border, borderRadius, padding,
                // w/h/textSize/bold/textAlign, x/y в пикселях или с '%').
                const hasPercentXY = (typeof o.x === 'number' && o.x <= 100 && typeof o.y === 'number' && o.y <= 100)
                                     && (o.bg === undefined && o.w === undefined && o.h === undefined);
                const usePixelPos = (typeof o.x === 'number' && !hasPercentXY)
                                    || typeof o.x === 'string';
                const style = {
                    fontFamily: '"Roboto Condensed", system-ui, sans-serif',
                    fontWeight: o.bold ? 800 : DEFAULT_LABEL_STYLE.fontWeight,
                    fontSize: o.textSize || o.size || DEFAULT_LABEL_STYLE.fontSize,
                    color: o.color || DEFAULT_LABEL_STYLE.color,
                    background: o.bg || 'rgba(15,12,8,0.55)',
                    padding: o.padding != null ? o.padding : '4px 10px',
                    borderRadius: o.borderRadius != null ? o.borderRadius : 5,
                    border: o.border || undefined,
                    textAlign: o.textAlign || 'center',
                    maxWidth: '70vw',
                    whiteSpace: 'pre-line',
                    wordBreak: 'break-word',
                    width: o.w != null ? o.w : undefined,
                    height: o.h != null ? o.h : undefined,
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: o.textAlign === 'left' ? 'flex-start' : 'center',
                    boxSizing: 'border-box',
                };
                if (hasPercentXY) {
                    return (
                        <div key={id} style={{
                            ...style,
                            position: 'absolute',
                            left: `${o.x}%`,
                            top: `${o.y}%`,
                            transform: 'translate(-50%, -50%)',
                        }}>{lbl.text}</div>
                    );
                }
                if (usePixelPos) {
                    // Якорь: 'center' — translate(-50%,-50%); по умолчанию top-left
                    const isCenter = o.anchor === 'center';
                    const leftVal = typeof o.x === 'string' ? o.x : `${o.x}px`;
                    const topVal  = typeof o.y === 'string' ? o.y : `${o.y}px`;
                    return (
                        <div key={id} style={{
                            ...style,
                            position: 'absolute',
                            left: leftVal,
                            top: topVal,
                            transform: isCenter ? 'translate(-50%, -50%)' : undefined,
                        }}>{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;
