"use client";

import { useEffect, useRef, useState } from "react";
import type { KhimkiEngine as KhimkiEngineType } from "./engine";
import { ORIGIN } from "./world";
import type { HudSnapshot } from "./types";

const initialHud: HudSnapshot = {
  fps: 0,
  latitude: ORIGIN.latitude,
  longitude: ORIGIN.longitude,
  speed: 0,
  renderer: "Инициализация GPU…",
  quality: "Авто",
};

export default function KhimkiExperience() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const engineRef = useRef<KhimkiEngineType | null>(null);
  const [hud, setHud] = useState(initialHud);
  const [ready, setReady] = useState(false);
  const [launched, setLaunched] = useState(false);
  const [locked, setLocked] = useState(false);
  const [showHelp, setShowHelp] = useState(false);
  const [showReference, setShowReference] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    let disposed = false;
    let engine: KhimkiEngineType | null = null;
    void import("./engine").then(({ KhimkiEngine }) => {
      if (disposed) return;
      engine = new KhimkiEngine(canvas, {
        onHud: setHud,
        onPointerLock: setLocked,
        onReady: () => setReady(true),
        onError: setError,
      });
      engineRef.current = engine;
      void engine.init();
    }).catch((reason: unknown) => {
      setError(reason instanceof Error ? reason.message : "Не удалось загрузить игровой модуль");
    });
    return () => {
      disposed = true;
      engine?.dispose();
      engineRef.current = null;
    };
  }, []);

  useEffect(() => {
    const onKey = (event: KeyboardEvent) => {
      if (event.code === "F1") {
        event.preventDefault();
        setShowHelp((value) => !value);
      }
      if (event.code === "F4") {
        event.preventDefault();
        setShowReference((value) => !value);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const enterWorld = () => {
    setLaunched(true);
    setShowHelp(false);
    setShowReference(false);
    engineRef.current?.start();
  };

  return (
    <main className="game-shell">
      <canvas ref={canvasRef} className="game-canvas" aria-label="Интерактивная 3D-сцена Новых Химок" />

      <header className="topbar">
        <div className="brand" aria-label="Radius Zero">
          <span className="brand-mark">RZ</span>
          <span className="brand-copy">
            <strong>RADIUS ZERO</strong>
            <small>НОВЫЕ ХИМКИ · ПРОТОТИП 01</small>
          </span>
        </div>
        <div className="location-pill">
          <span className="location-pulse" />
          <span>{ORIGIN.label}</span>
        </div>
        <div className="top-actions">
          <button className="hud-button" type="button" onClick={() => setShowReference((value) => !value)} aria-label="Показать визуальные источники">
            ИСТОЧНИК
            <kbd>F4</kbd>
          </button>
          <button className="icon-button" type="button" onClick={() => setShowHelp((value) => !value)} aria-label="Показать управление">
            ?
          </button>
        </div>
      </header>

      <aside className="telemetry" aria-label="Телеметрия">
        <div className="telemetry-row">
          <span>FPS</span>
          <strong className={hud.fps > 0 && hud.fps < 42 ? "warning" : ""}>{hud.fps || "—"}</strong>
        </div>
        <div className="telemetry-row">
          <span>СКОРОСТЬ</span>
          <strong>{hud.speed.toFixed(1)} м/с</strong>
        </div>
        <div className="telemetry-divider" />
        <div className="coordinate">
          <span>ШИРОТА</span>
          <strong>{hud.latitude.toFixed(6)}</strong>
        </div>
        <div className="coordinate">
          <span>ДОЛГОТА</span>
          <strong>{hud.longitude.toFixed(6)}</strong>
        </div>
        <div className="telemetry-note">{hud.renderer}</div>
        <div className="telemetry-note">Качество: {hud.quality}</div>
      </aside>

      <div className="reticle" aria-hidden="true"><span /><i /></div>

      <div className="controls-strip" aria-label="Краткое управление">
        <span><kbd>WASD</kbd> движение</span>
        <span><kbd>SHIFT</kbd> бег</span>
        <span><kbd>SPACE</kbd> прыжок</span>
        <span><kbd>МЫШЬ</kbd> камера</span>
        <span><kbd>I</kbd> инверсия</span>
      </div>

      {(!ready || !launched || !locked || error) && (
        <section className="entry-layer" aria-live="polite">
          <div className="entry-card">
            <p className="eyebrow">55.899338 · 37.409289</p>
            <h1>Новые Химки.<br />Свободное движение.</h1>
            <p className="entry-description">
              Реальная планировка превращена в локальную игровую сцену. Карта скрыта: перед вами только город, персонаж и непрерывное управление от третьего лица.
            </p>
            {error ? (
              <div className="error-box">Ошибка запуска: {error}</div>
            ) : (
              <button className="enter-button" type="button" onClick={enterWorld} disabled={!ready}>
                <span>{!ready ? "СОБИРАЕМ МИР…" : launched ? "ПРОДОЛЖИТЬ" : "ВОЙТИ В МИР"}</span>
                <span className="enter-arrow">↗</span>
              </button>
            )}
            <p className="entry-hint">Для камеры браузер захватит указатель. ESC ставит приложение на паузу.</p>
          </div>
          <div className="entry-side-label">RZ / KHIMKI / BUILD 001</div>
        </section>
      )}

      {showHelp && (
        <section className="drawer help-drawer">
          <button className="drawer-close" type="button" onClick={() => setShowHelp(false)} aria-label="Закрыть">×</button>
          <p className="eyebrow">УПРАВЛЕНИЕ</p>
          <h2>Движение без дрожи</h2>
          <div className="help-grid">
            <div><kbd>W A S D</kbd><span>Идти относительно камеры</span></div>
            <div><kbd>Shift</kbd><span>Ускориться до бега</span></div>
            <div><kbd>Space</kbd><span>Прыгнуть</span></div>
            <div><kbd>Мышь</kbd><span>Повернуть камеру</span></div>
            <div><kbd>I</kbd><span>Переключить инверсию X/Y</span></div>
            <div><kbd>ESC</kbd><span>Освободить курсор</span></div>
          </div>
          <p className="drawer-copy">Физика и камера работают в локальных метрах, а мировые координаты рассчитываются отдельно. Поэтому географическая точность не вызывает вибрацию сцены.</p>
        </section>
      )}

      {showReference && (
        <section className="drawer reference-drawer">
          <button className="drawer-close" type="button" onClick={() => setShowReference(false)} aria-label="Закрыть">×</button>
          <p className="eyebrow">ВИЗУАЛЬНЫЙ ИСТОЧНИК 01</p>
          <h2>Яндекс Панорамы · 2021</h2>
          <div className="reference-frame">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img src="/references/yandex-new-khimki.png" alt="Панорама у торгового центра Новые Химки" />
          </div>
          <dl className="source-meta">
            <div><dt>ТОЧКА</dt><dd>55.899338, 37.409289</dd></div>
            <div><dt>ОБЪЕКТ</dt><dd>ТЦ «Новые Химки» и круговое движение</dd></div>
            <div><dt>РОЛЬ</dt><dd>Фасады, разметка, улица, масштаб окружения</dd></div>
          </dl>
          <p className="drawer-copy">Снимок используется как визуальный эталон. Геометрия и коллизии остаются отдельным лёгким 3D-слоем, поэтому персонаж может двигаться свободно.</p>
        </section>
      )}

      <div className="mobile-notice">Для управления необходимы клавиатура и мышь.</div>
    </main>
  );
}
