/* global React, OrbitTab, ThreeLogo */
const { useEffect, useRef, useState } = React;

const TABS = [
  { id: 'planetarium', i18n: 'nav.planetarium', dropdown: ['tab.planetarium.d1', 'tab.planetarium.d2', 'tab.planetarium.d3'] },
  { id: 'blog',        i18n: 'nav.blog', url: 'https://inf.wotrafa.com', dropdown: ['tab.blog.d1'] },
  { id: 'academy',     i18n: 'nav.academyShort', dropdown: ['tab.academy.d1'] },
  { id: 'about',       i18n: 'nav.about', dropdown: ['tab.about.d1', 'tab.about.d2'] },
];

// Knobs
const SCROLL_SENS    = 0.009;    // rad per px of wheel/touch
const TOUCHPAD_BOOST = 2.4;      // touchpad (deltaMode 0) gets an extra multiplier
const KEY_STEP       = Math.PI / 2; // 90° per arrow press → next tab
const SETTLE_MS      = 1200;
const ORBIT_RADIUS_PX = 280;     // vertical orbit radius
const ORBIT_DEPTH_PX  = 320;     // push-back of back-side tabs
const LOGO_SIZE       = '80.93vh';
const MOBILE_AUTO_SPIN = 0.004;  // rad/frame — медленное авто-вращение на мобильном

// Авто-вращение только на телефонах (≤768px), планшеты крутят сами скроллом/свайпом
const isMobileDevice = () => window.innerWidth <= 768;

function OrbitalLogo() {
  // rotation in radians; advances with scroll
  const [rotation, setRotation] = useState(0);
  // locale state — перерисовывает компонент при смене языка
  const [locale, setLocale] = useState(() => window.WTi18n ? WTi18n.current : 'ru');
  useEffect(() => {
    const onLocale = (e) => setLocale(e.detail.locale);
    window.addEventListener('wt:locale', onLocale);
    return () => window.removeEventListener('wt:locale', onLocale);
  }, []);
  const targetRef = useRef(0);
  const rafRef = useRef(0);
  const rotationRef = useRef(0);
  const stageRef = useRef(null);
  const isMobileRef = useRef(isMobileDevice());

  // Smooth follow target → rotation
  useEffect(() => {
    const tick = () => {
      // Авто-вращение на мобильном — медленное, плавное
      if (isMobileRef.current) {
        targetRef.current += MOBILE_AUTO_SPIN;
      }
      const diff = targetRef.current - rotationRef.current;
      const settled = Math.abs(diff) < 0.0005;
      if (settled) {
        rotationRef.current = targetRef.current;
      } else {
        rotationRef.current += diff * 0.22;
      }
      window.__wtOrbitRotation = rotationRef.current;
      window.__wtOrbitSettled = settled;
      setRotation(rotationRef.current);
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, []);

  // Wheel + touch + keyboard drive the target
  useEffect(() => {
    const stage = stageRef.current;
    if (!stage) return;

    const onWheel = (e) => {
      e.preventDefault();
      // deltaMode 0 = pixels (touchpad), 1 = lines (mouse wheel), 2 = pages
      const boost = e.deltaMode === 0 ? TOUCHPAD_BOOST : 1;
      targetRef.current += e.deltaY * SCROLL_SENS * boost;
    };

    let touchY = null;
    const onTouchStart = (e) => { touchY = e.touches[0].clientY; };
    const onTouchMove = (e) => {
      if (touchY === null) return;
      const y = e.touches[0].clientY;
      const dy = touchY - y;
      touchY = y;
      targetRef.current += dy * SCROLL_SENS * 2.5;
      e.preventDefault();
    };
    const onTouchEnd = () => { touchY = null; };

    const onKey = (e) => {
      if (e.key === 'ArrowRight' || e.key === 'ArrowDown')
        targetRef.current += KEY_STEP;
      else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp')
        targetRef.current -= KEY_STEP;
    };

    stage.addEventListener('wheel', onWheel, { passive: false });
    stage.addEventListener('touchstart', onTouchStart, { passive: true });
    stage.addEventListener('touchmove', onTouchMove, { passive: false });
    stage.addEventListener('touchend', onTouchEnd);
    window.addEventListener('keydown', onKey);
    return () => {
      stage.removeEventListener('wheel', onWheel);
      stage.removeEventListener('touchstart', onTouchStart);
      stage.removeEventListener('touchmove', onTouchMove);
      stage.removeEventListener('touchend', onTouchEnd);
      window.removeEventListener('keydown', onKey);
    };
  }, []);

  // Click a tab → snap it to the front; если уже активен и по центру и есть ссылка — переходим
  const snapTo = (i) => {
    if (i === frontIdx && TABS[i].url) {
      // проверяем что кнопка действительно по центру (< 3% от диаметра орбиты)
      let t = (i * step + rotationRef.current) % (2 * Math.PI);
      if (t > Math.PI) t -= 2 * Math.PI;
      if (t < -Math.PI) t += 2 * Math.PI;
      if (Math.abs(Math.sin(t)) < 0.06) {
        window.open(TABS[i].url, '_blank');
        return;
      }
    }
    const cur = targetRef.current;
    let theta = (i * step + cur) % (2 * Math.PI);
    if (theta > Math.PI) theta -= 2 * Math.PI;
    targetRef.current -= theta;
  };

  // Which tab is currently "front"? (smallest |cos(θ)-1|)
  const n = TABS.length;
  const step = (2 * Math.PI) / n;
  let frontIdx = 0;
  let best = -Infinity;
  for (let i = 0; i < n; i++) {
    const c = Math.cos(i * step + rotation);
    if (c > best) { best = c; frontIdx = i; }
  }

  // Slow Y-axis counter-spin on the logo itself, parallax-style
  const logoSpin = -rotation * 0.25;

  return (
    <div className="wt-stage" ref={stageRef}>
      <div className="wt-stage__perspective">
        {/* Orbit ring — horizontal disc the tabs slide along, tilted slightly */}
        <div
          className="wt-orbit-ring"
          style={{
            width: ORBIT_RADIUS_PX * 2,
            height: ORBIT_RADIUS_PX * 2,
            transform: `translate(-50%, -50%) rotateX(72deg)`,
          }}
        />

        {/* 3D logo — three.js GLB renderer (falls back to JPEG until GLB loads) */}
        <ThreeLogo rotationRef={rotationRef} size={LOGO_SIZE} />

        {/* Двойной клик по логотипу → Planetarium вперёд, логотип лицом */}
        <div
          style={{
            position: 'absolute',
            left: '50%', top: '50%',
            width: LOGO_SIZE, height: LOGO_SIZE,
            transform: 'translate(-50%, -50%)',
            cursor: 'pointer',
            zIndex: 2,
          }}
          onDoubleClick={() => snapTo(0)}
        />

        {/* Orbiting tabs */}
        {TABS.map((tab, i) => {
          const theta = i * step + rotation;
          // normalize to [-π, π] for cleaner sin/cos behavior
          let t = theta % (2 * Math.PI);
          if (t > Math.PI) t -= 2 * Math.PI;
          if (t < -Math.PI) t += 2 * Math.PI;
          const settled = Math.abs(targetRef.current - rotationRef.current) < 0.0005;
          return (
            <OrbitTab
              key={tab.id}
              label={tab}
              theta={t}
              radius={ORBIT_RADIUS_PX}
              depth={ORBIT_DEPTH_PX}
              active={i === frontIdx}
              settled={settled}
              onClick={() => snapTo(i)}
            />
          );
        })}
      </div>

      {!isMobileRef.current && (
        <div className="wt-stage__hint">
          <span data-i18n="hero.scrollHint">Прокрутите, чтобы исследовать</span>
          <svg width="20" height="32" viewBox="0 0 20 32" fill="none" aria-hidden="true">
            <rect x="1" y="1" width="18" height="30" rx="9" stroke="currentColor" strokeOpacity="0.4" />
            <circle className="wt-stage__hint-dot" cx="10" cy="9" r="2" fill="currentColor" />
          </svg>
        </div>
      )}
    </div>
  );
}

window.OrbitalLogo = OrbitalLogo;
