import GUI from "lil-gui";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { CameraC_internal, Delegate, UpdateController } from "@24tools/playable_template";
import { FollowCameraC } from "./FollowCameraC";
import { TestSceneC } from "./TestSceneC";

// Transparent overlay for OrbitControls — sits above canvas but below GUI panel.
// Allows the GUI to keep receiving clicks while OrbitControls is active.
function createOrbitOverlay(): HTMLDivElement {
  const div = document.createElement("div");
  div.style.cssText = `
    position: fixed; inset: 0;
    z-index: 9000;
    touch-action: auto;
    cursor: grab;
  `;
  return div;
}

export class CameraDebugUI {
  static init() {
    const gui = new GUI({ title: "📷 Camera Debug", width: 280 });
    gui.domElement.style.zIndex = "99999";
    gui.domElement.style.position = "fixed";

    const offsetFolder = gui.addFolder("Offset — camera position (from config)");
    offsetFolder.add(FollowCameraC.offset, "x", -10, 10, 0.1).name("X  (left / right)");
    offsetFolder.add(FollowCameraC.offset, "y", -10, 10, 0.1).name("Y  (height)");
    offsetFolder.add(FollowCameraC.offset, "z", -10, 10, 0.1).name("Z  (distance behind)");

    gui.add(FollowCameraC, "lerpSpeed", 1, 15, 0.5).name("Follow smoothness  [1–15]");

    const charFolder = gui.addFolder("Character");
    const scaleProxy = { scale: TestSceneC.characterObject.scale.x };
    charFolder
      .add(scaleProxy, "scale", 0.1, 3, 0.01)
      .name("Scale  [0.1–3]")
      .onChange((v: number) => TestSceneC.characterObject.scale.setScalar(v));

    charFolder.add(TestSceneC.characterObject.position, "x", -50, 50, 0.1).name("Pos X");
    charFolder.add(TestSceneC.characterObject.position, "y", -10, 10, 0.1).name("Pos Y");
    charFolder.add(TestSceneC.characterObject.position, "z", -50, 50, 0.1).name("Pos Z");

    let orbitControls: OrbitControls | null = null;
    let orbitDelegate: Delegate<number> | null = null;
    let orbitOverlay: HTMLDivElement | null = null;

    const orbitProxy = { enabled: false };
    gui
      .add(orbitProxy, "enabled")
      .name("🔭 Free camera (OrbitControls)")
      .onChange((enabled: boolean) => {
        if (enabled) {
          FollowCameraC.paused = true;

          orbitOverlay = createOrbitOverlay();
          document.body.appendChild(orbitOverlay);

          orbitControls = new OrbitControls(CameraC_internal.camera!, orbitOverlay);
          orbitControls.update();

          orbitDelegate = UpdateController.Instance.onUpdate.addDelegate(() => {
            orbitControls?.update();
          });
        } else {
          if (orbitDelegate !== null) {
            UpdateController.Instance.onUpdate.removeListeners(orbitDelegate);
            orbitDelegate = null;
          }
          orbitControls?.dispose();
          orbitControls = null;

          orbitOverlay?.remove();
          orbitOverlay = null;

          FollowCameraC.paused = false;
          FollowCameraC.snapToTarget();
        }
      });

    gui
      .add(
        {
          log: () => {
            const cam = CameraC_internal.camera!;
            const s = TestSceneC.characterObject.scale.x;

            const p = cam.position;
            // Convert radians to degrees for config
            const rx = Math.round(cam.rotation.x * (180 / Math.PI));
            const ry = Math.round(cam.rotation.y * (180 / Math.PI));
            const rz = Math.round(cam.rotation.z * (180 / Math.PI));

            console.log(
              `%c[CameraDebug] Paste into globalSettings.ts:
  camera_position:  x=${p.x.toFixed(2)},  y=${p.y.toFixed(2)},  z=${p.z.toFixed(2)}
  camera_rotation:  x=${rx}°,  y=${ry}°,  z=${rz}°
  charScale: ${s.toFixed(2)}`,
              "color: #7cf; font-weight: bold"
            );
          },
        },
        "log"
      )
      .name("📋 Print values to console");
  }
}
