/* global React, THREE */
const { useEffect, useRef } = React;

/**
 * 3D GLB logo viewer.
 *  - Loads assets/Meshy_AI_Iconic_Emblem_0204072858_texture.glb via three.js GLTFLoader.
 *  - Rotates around Y-axis driven by `rotationRef.current` (radians).
 *  - Falls back to the JPEG lockup if the GLB is missing.
 */
const GLB_URL = '../../3d/LogoMatowoe.glb';

function ThreeLogo({ rotationRef, size = '65vmin' }) {
  const hostRef = useRef(null);
  const fallbackRef = useRef(null);

  useEffect(() => {
    const host = hostRef.current;
    if (!host) return;

    let cancelled = false;
    let resizeRO = null;
    let raf = 0;
    let renderer = null;

    const start = () => {
      if (cancelled || !host || !window.THREE) return;

    const width = host.clientWidth;
    const height = host.clientHeight;

    // ---- Scene ----
    const scene = new THREE.Scene();

    // ---- Camera ----
    const camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 100);
    camera.position.set(0, 0, 4);
    camera.lookAt(0, 0, 0);

    // ---- Renderer ----
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.setSize(width, height, false);
    // sRGB output — API name differs by three.js version
    if ('outputColorSpace' in renderer && THREE.SRGBColorSpace) {
      renderer.outputColorSpace = THREE.SRGBColorSpace;
    } else if ('outputEncoding' in renderer && THREE.sRGBEncoding) {
      renderer.outputEncoding = THREE.sRGBEncoding;
    }
    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    renderer.toneMappingExposure = 1.1;
    // Канвас должен заполнять контейнер по CSS
    renderer.domElement.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;';
    host.appendChild(renderer.domElement);

    // ---- Lighting: тёплый мягкий свет (зеркально с двух сторон) ----
    const ambient  = new THREE.AmbientLight(0xfff5e0, 0.9);
    const key      = new THREE.DirectionalLight(0xffffff, 0.55); key.position.set(-3,  4,  10);
    const keyR     = new THREE.DirectionalLight(0xffffff, 0.55); keyR.position.set( 3,  4,  10);
    const keyBack  = new THREE.DirectionalLight(0xffffff, 0.45); keyBack.position.set(-3,  4, -10);
    const keyBackR = new THREE.DirectionalLight(0xffffff, 0.45); keyBackR.position.set( 3,  4, -10);
    const fill     = new THREE.DirectionalLight(0xffe8c0, 0.25); fill.position.set( 2, -1,   3);
    const fillR    = new THREE.DirectionalLight(0xffe8c0, 0.25); fillR.position.set(-2, -1,   3);
    const rim      = new THREE.DirectionalLight(0xfe0128, 0.4);  rim.position.set(-1.5, -1, -2.5);
    const rimR     = new THREE.DirectionalLight(0xfe0128, 0.4);  rimR.position.set( 1.5, -1, -2.5);
    // Дневной свет спереди — нейтральный белый, прямо в камеру
    const day      = new THREE.DirectionalLight(0xffffff, 0.85); day.position.set(0, 2, 12);
    scene.add(ambient, key, keyR, keyBack, keyBackR, fill, fillR, rim, rimR, day);

    let model = null;

    // ---- Load GLB ----
    const loader = new window.GLTFLoader();
    loader.load(
      GLB_URL,
      (gltf) => {
        if (cancelled) return;
        model = gltf.scene;

        // Auto-fit: compute bounding sphere, scale to fit camera frustum
        const box = new THREE.Box3().setFromObject(model);
        const center = box.getCenter(new THREE.Vector3());
        const sphere = box.getBoundingSphere(new THREE.Sphere());
        model.position.sub(center);                     // center on origin
        const targetRadius = 1.15;
        const scale = targetRadius / Math.max(0.0001, sphere.radius);
        model.scale.setScalar(scale);

        scene.add(model);
        if (fallbackRef.current) fallbackRef.current.style.opacity = 0;
      },
      undefined,
      (err) => {
        console.warn('[WoTraFa] GLB load failed — using JPEG fallback. Re-upload the .glb to assets/ to enable 3D.', err);
      }
    );

    // ---- Animation loop ----
    const tick = () => {
      const t = (rotationRef && rotationRef.current) || 0;
      if (model) {
        // K=1: модель делает ровно 1 оборот за 1 цикл орбиты → при t=0,2π,4π… смотрит прямо
        model.rotation.y = -t;
        model.rotation.x =  Math.sin(t * 0.4) * 0.08;
      }
      renderer.render(scene, camera);
      raf = requestAnimationFrame(tick);
    };
    tick();

    // ---- Resize ----
    resizeRO = new ResizeObserver(() => {
      const w = host.clientWidth, h = host.clientHeight;
      if (!w || !h) return;
      renderer.setSize(w, h, false);
      camera.aspect = w / h;
      camera.updateProjectionMatrix();
    });
    resizeRO.observe(host);
    };

    if (window.THREE) start();
    else window.addEventListener('three-ready', start, { once: true });

    return () => {
      cancelled = true;
      cancelAnimationFrame(raf);
      if (resizeRO) resizeRO.disconnect();
      if (renderer) {
        renderer.dispose();
        if (renderer.domElement.parentNode) renderer.domElement.parentNode.removeChild(renderer.domElement);
      }
    };
  }, [rotationRef]);

  return (
    <div
      ref={hostRef}
      className="wt-three"
      style={{
        position: 'absolute',
        left: '50%', top: '59%',
        width: size, height: size,
        transform: 'translate(-50%, -50%)',
        pointerEvents: 'none',
      }}
    >
      {/* JPEG fallback shown until the GLB loads (or if it never does) */}
      <img
        ref={fallbackRef}
        src="../../assets/wotrafa-logo.jpg"
        alt="WoTraFa"
        className="wt-three__fallback"
        style={{
          position: 'absolute', inset: 0,
          width: '100%', height: '100%',
          objectFit: 'cover', borderRadius: 18,
          transition: 'opacity 320ms ease',
          boxShadow:
            '0 6px 0 #0a0a0a, 0 12px 0 #050505, 0 18px 0 #020202,' +
            '0 26px 40px rgba(0,0,0,0.75), 0 0 0 2px rgba(254,1,40,0.15)',
        }}
      />
    </div>
  );
}

window.ThreeLogo = ThreeLogo;
