// Preview-режим аватара (полное тело R15). 2026-05-27.
//
// URL: https://player.rublox.pro/_preview-avatar/<itemId>#team_jwt=<JWT>
//
// Пустой мир + персонаж с указанным аватаром (вместо дефолтного bacon-hair).
// Можно бегать WASD, прыгать, крутить камеру — проверить как выглядит
// и анимируется новый аватар.
//
// Реализация: scene.setPlayerModelType('designer_avatar:<id>') →
// _resolveModelSource подтянет item.file_path из БД и подгрузит body.glb.

import { useEffect, useRef, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useAuth } from '../auth/PlayerAuth';
import { BabylonScene } from '../engine/BabylonScene';
import * as Kubikon3DApi from '../api/Kubikon3DService';
import LoadingScreen from '../LoadingScreen';

export default function PreviewAvatarRoute() {
  const { itemId } = useParams();
  const navigate = useNavigate();
  const { isAuthenticated, isLoading: authLoading, error: authError } = useAuth();

  const canvasRef = useRef(null);
  const sceneRef = useRef(null);
  const [avatar, setAvatar] = useState(null);
  const [loadErr, setLoadErr] = useState(null);
  const [phase, setPhase] = useState('auth');

  // 1) грузим метаданные аватара
  useEffect(() => {
    if (!isAuthenticated) return;
    setPhase('loading');
    Kubikon3DApi.getDesignerAvatar(itemId)
      .then((r) => {
        const a = r?.data?.item || r?.data || r;
        if (!a || !a.file_path) throw new Error('Аватар не найден');
        setAvatar(a);
      })
      .catch((e) => {
        const msg = e?.response?.data?.message
                 || e?.response?.data?.error
                 || e?.message || 'Не удалось загрузить аватара';
        setLoadErr(msg);
        setPhase('error');
      });
  }, [isAuthenticated, itemId]);

  // 2) сцена + спавн персонажа с этим аватаром
  useEffect(() => {
    if (!avatar || !canvasRef.current) return;
    if (sceneRef.current) return;
    let scene, destroyed = false;
    (async () => {
      try {
        scene = new BabylonScene(canvasRef.current);
        sceneRef.current = scene;
        scene.init();
        // НЕ ставить кубы по клику — обычный курсор
        try { scene.setActiveTool?.('select'); } catch (e) {}
        // Спавн рядом с центром
        try { scene.spawnPoint = { x: 0, y: 1, z: 0 }; } catch (e) {}
        // Главное — задать modelType ДО enterPlayMode чтобы PlayerController
        // подхватил наш designer_avatar.
        // Сбрасываем глобальный флаг ошибки fallback'а перед загрузкой —
        // если PlayerController не сможет дозагрузить, флаг будет установлен.
        try { window.__previewFallbackReason = null; } catch (e) {}
        try { scene.setPlayerModelType?.(`designer_avatar:${avatar.id}`); } catch (e) {}
        scene.enterPlayMode?.();
        // Подождём короткое время и проверим — был ли silent-fallback на бекона
        await new Promise(r => setTimeout(r, 1500));
        if (destroyed) return;
        try {
          const reason = window.__previewFallbackReason;
          if (reason) {
            setLoadErr(
              'Аватар не загрузился — показан стандартный бекон.\n\n'
              + 'Причина: ' + reason + '\n\n'
              + 'Возможные причины:\n'
              + '• Роль «дизайнер» ещё не пробросилась (подожди до 60 секунд после назначения)\n'
              + '• JWT истёк — открой через кнопку «Тестировать» в кабинете заново\n'
              + '• Аватар удалён из БД'
            );
            setPhase('error');
            return;
          }
        } catch (e) {}
        if (!destroyed) setPhase('ready');
      } catch (e) {
        console.error('[PreviewAvatar] scene init failed', e);
        if (!destroyed) {
          setLoadErr(e?.message || 'Ошибка инициализации сцены');
          setPhase('error');
        }
      }
    })();
    return () => {
      destroyed = true;
      try {
        if (scene && typeof scene.dispose === 'function') scene.dispose();
        else if (scene && scene.engine) scene.engine.dispose();
      } catch (e) {}
      sceneRef.current = null;
    };
  }, [avatar]);

  if (authLoading) return <LoadingScreen text="Подключение" />;
  if (authError === 'no_jwt_local') {
    return <LoadingScreen text="Нужен JWT"
                          subText="Открой из team.rublox.pro кнопкой «Тестировать»."/>;
  }
  if (!isAuthenticated) {
    return <LoadingScreen text="Сессия истекла"
                          subText="Вернись в team.rublox.pro и попробуй снова."/>;
  }

  return (
    <div style={{ position: 'fixed', inset: 0, background: '#000' }}>
      <canvas ref={canvasRef}
              style={{ width: '100%', height: '100%', display: 'block',
                       touchAction: 'none', outline: 'none' }}/>

      <div style={bannerStyle}>
        <div style={{ fontWeight: 700, fontSize: 14 }}>
          Тест аватара: «{avatar ? avatar.name : '...'}»
        </div>
        <div style={{ fontSize: 12, opacity: 0.7, marginTop: 2 }}>
          {avatar ? `код ${avatar.code}` : ''}
          {avatar && avatar.status !== 'published' && (
            <span style={{ color: '#ffcc66', marginLeft: 8 }}>
              · {avatar.status === 'draft' ? 'черновик' : 'на проверке'}
            </span>
          )}
        </div>
        <button onClick={() => { try { window.close(); } catch (e) {}; navigate('/'); }}
                style={closeBtnStyle}>Закрыть</button>
      </div>

      <div style={{
        position: 'absolute', bottom: 16, left: '50%',
        transform: 'translateX(-50%)',
        background: 'rgba(10, 14, 26, 0.88)', color: '#f1f5fb',
        padding: '8px 14px', borderRadius: 8,
        border: '1px solid rgba(255,255,255,0.10)',
        fontSize: 12,
        fontFamily: '"Roboto Condensed", system-ui, sans-serif',
      }}>
        WASD — движение · Space — прыжок · мышь — камера
      </div>

      {phase === 'loading' && (
        <div style={overlayStyle}><div>Загрузка аватара…</div></div>
      )}
      {phase === 'error' && (
        <div style={overlayStyle}>
          <div style={{ color: '#ff8888', fontWeight: 700, marginBottom: 8,
                         fontSize: 16 }}>
            Не удалось загрузить аватар
          </div>
          <div style={{ fontSize: 13, opacity: 0.9, maxWidth: 540,
                         textAlign: 'left', whiteSpace: 'pre-wrap',
                         lineHeight: 1.55,
                         padding: '12px 16px',
                         background: 'rgba(255, 100, 100, 0.06)',
                         border: '1px solid rgba(255, 100, 100, 0.25)',
                         borderRadius: 6 }}>
            {loadErr}
          </div>
          <button onClick={() => window.location.reload()}
                  style={{ marginTop: 12, padding: '6px 16px', fontSize: 13,
                            background: '#3357ff', color: '#fff',
                            border: 'none', borderRadius: 6, cursor: 'pointer' }}>
            Попробовать снова
          </button>
          <button onClick={() => window.close()}
                  style={{ ...closeBtnStyle, marginTop: 8, position: 'static' }}>
            Закрыть
          </button>
        </div>
      )}
    </div>
  );
}

const bannerStyle = {
  position: 'absolute', top: 12, left: 12,
  background: 'rgba(10, 14, 26, 0.88)', color: '#f1f5fb',
  padding: '10px 90px 10px 14px',
  borderRadius: 8, border: '1px solid rgba(255,255,255,0.10)',
  fontFamily: '"Roboto Condensed", system-ui, sans-serif',
  display: 'inline-block',
  maxWidth: 'calc(100vw - 40px)',
};
const closeBtnStyle = {
  position: 'absolute', top: 10, right: 10,
  background: 'rgba(255, 111, 122, 0.18)', color: '#ff6f7a',
  border: '1px solid rgba(255, 111, 122, 0.40)',
  borderRadius: 6, padding: '4px 10px',
  fontSize: 12, fontWeight: 700, cursor: 'pointer',
};
const overlayStyle = {
  position: 'absolute', inset: 0,
  background: 'rgba(0,0,0,0.65)', color: '#fff',
  display: 'flex', alignItems: 'center', justifyContent: 'center',
  flexDirection: 'column', fontFamily: 'system-ui, sans-serif',
};
