// VNC-консоль через noVNC.
//
// В noVNC 1.4.0 основной модуль — это ES-модуль (core/rfb.js), который
// экспортирует класс RFB через `export default`. Грузим его через
// динамический import(). Скрипт и его зависимости (vendor/, utils/,
// core/inflator.js и т.п.) лежат в /novnc/* внутри nginx-контейнера —
// собирается в Docker-образе из GitHub release (см. frontend/Dockerfile).

import { useEffect, useRef, useState } from "react";
import { api } from "../api.js";

// @vite-ignore — запрещаем Vite пытаться разрешить путь на этапе сборки,
// иначе он упадёт, не найдя модуль в локальной файловой системе.
const NOVNC_MODULE_URL = "/novnc/core/rfb.js";

let modulePromise = null;

function loadNoVNC() {
  if (modulePromise) return modulePromise;
  modulePromise = import(/* @vite-ignore */ NOVNC_MODULE_URL)
    .then((mod) => {
      if (!mod.default) {
        throw new Error("RFB не найден в модуле noVNC");
      }
      return mod.default;
    });
  return modulePromise;
}

export default function ConsoleViewer({ instanceId }) {
  const containerRef = useRef(null);
  const rfbRef = useRef(null);
  const [status, setStatus] = useState("Подключение…");
  const [error, setError] = useState("");

  useEffect(() => {
    let cancelled = false;

    async function connect() {
      try {
        const info = await api.getConsole(instanceId);
        const RFB = await loadNoVNC();
        if (cancelled) return;

        const proto = window.location.protocol === "https:" ? "wss" : "ws";
        const wsUrl =
          `${proto}://${window.location.host}/api/console/ws?` +
          `node=${encodeURIComponent(info.node)}` +
          `&vmid=${info.vmid}` +
          `&guest_type=${info.guest_type}` +
          `&port=${info.port}` +
          `&ticket=${encodeURIComponent(info.ticket)}`;

        const rfb = new RFB(containerRef.current, wsUrl);
        rfb.addEventListener("connect", () => !cancelled && setStatus("Подключено"));
        rfb.addEventListener("disconnect", () => !cancelled && setStatus("Соединение закрыто"));
        rfbRef.current = rfb;
      } catch (err) {
        if (!cancelled) setError(err.message || String(err));
      }
    }

    connect();
    return () => {
      cancelled = true;
      if (rfbRef.current && typeof rfbRef.current.disconnect === "function") {
        try { rfbRef.current.disconnect(); } catch { /* noop */ }
      }
    };
  }, [instanceId]);

  return (
    <div>
      <div className="status-row" style={{ marginBottom: 8 }}>
        <span className={`dot ${error ? "error" : "running"}`} /> {error ? "Ошибка консоли" : status}
      </div>
      {error && (
        <div className="error-box">
          {error}. Консоль VNC зависит от версии Proxmox и настроек аутентификации — см. README, раздел
          «Консоль VNC».
        </div>
      )}
      <div className="console-frame" ref={containerRef} style={{ width: "100%", height: 480 }} />
    </div>
  );
}
