import * as BABYLON from "babylonjs";

/**
 * Create first-person and overview cameras
 */
export function createCameras(scene, canvas) {
    // First-person camera
    const fpCamera = new BABYLON.UniversalCamera("cam", new BABYLON.Vector3(0, 1.6, 0), scene);
    fpCamera.minZ = 0.1;
    fpCamera.speed = 1.12;
    fpCamera.angularSensibility = 1000;
    fpCamera.inertia = 0.6;
    fpCamera.keysUp = [87]; // W
    fpCamera.keysDown = [83]; // S
    fpCamera.keysLeft = [65]; // A
    fpCamera.keysRight = [68]; // D
    fpCamera.checkCollisions = true;
    fpCamera.applyGravity = true;
    fpCamera.ellipsoid = new BABYLON.Vector3(0.35, 0.9, 0.35);

    // Overview camera
    const overviewCamera = new BABYLON.ArcRotateCamera(
        "overviewCam",
        -Math.PI / 2,
        Math.PI / 3.2,
        40,
        new BABYLON.Vector3(0, 0, 0),
        scene,
    );
    overviewCamera.lowerBetaLimit = 0.2;
    overviewCamera.upperBetaLimit = Math.PI / 2.05;
    overviewCamera.lowerRadiusLimit = 8;
    overviewCamera.inertia = 0.7;

    return { fpCamera, overviewCamera };
}

/**
 * Switch between camera modes
 */
export function switchCameraMode(scene, canvas, fpCamera, overviewCamera, state) {
    const currentMode = state.cameraMode || "fp";
    
    if (currentMode === "fp") {
        if (document.pointerLockElement === canvas && document.exitPointerLock) {
            document.exitPointerLock();
        }
        fpCamera.detachControl(canvas);
        overviewCamera.attachControl(canvas, true);
        scene.activeCamera = overviewCamera;
        state.cameraMode = "overview";
        state.runtime.message = "Overview camera (press V to return to first-person).";
        return "overview";
    } else {
        overviewCamera.detachControl(canvas);
        fpCamera.attachControl(canvas, true);
        scene.activeCamera = fpCamera;
        state.cameraMode = "fp";
        state.runtime.message = "First-person camera (W/A/S/D + mouse).";
        return "fp";
    }
}

/**
 * Update overview camera for maze size
 */
export function updateOverviewCameraForMaze(overviewCamera, w, h, cellSize = 2) {
    const mazeSpan = Math.max(w, h) * cellSize;
    overviewCamera.radius = Math.max(mazeSpan * 1.05, 16);
    overviewCamera.target = new BABYLON.Vector3(0, 0, 0);
}

/**
 * Attach camera to canvas and activate it
 */
export function attachCamera(scene, camera, canvas) {
    camera.attachControl(canvas, true);
    scene.activeCamera = camera;
}
