import { AxesHelper, Object3D, Vector3 } from "three";

import { serializable } from "../../engine/engine_serialization_decorator.js";
import type { IGameObject } from "../../engine/engine_types.js";
import { getParam } from "../../engine/engine_utils.js";
import type { IXRRig } from "../../engine/engine_xr.js";
import { type NeedleXREventArgs, NeedleXRSession } from "../../engine/engine_xr.js";
import { Behaviour } from "../Component.js";
import { BoxGizmo } from "../Gizmos.js";

const debug = getParam("debugwebxr");

/**
 * A user in XR (VR or AR) is parented to an XR rig during the session.  
 * When moving through the scene the rig is moved instead of the user.
 * 
 * You can create multiple rigs in your scene and switch between them during an active XR session by calling {@link setAsActiveXRRig} on the XRRig instance.   
 * For advanced use-cases you can also provide your own XRRig class by implementing the {@link IXRRig} interface and adding it to your scene.
 * 
 * @category XR
 * @group Components
 */
export class XRRig extends Behaviour implements IXRRig {

    @serializable()
    priority: number = 0;

    get isActive() { return this.activeAndEnabled && this.gameObject.visible; }

    /** 
     * Sets this rig to be the active XR rig (needs to be called during an active XR session) 
     * Note that this might modify the priority of this rig to be the highest.
    */
    setAsActiveXRRig() {
        NeedleXRSession.active?.setRigActive(this);
    }
    /** 
     * Sets the priority of the rig.
     */
    setPriority(value: number) {
        this.priority = value;
    }

    /** @internal */
    awake(): void {
        if (debug) {
            const gizmoObj = new Object3D() as IGameObject;
            gizmoObj.position.y += .5;
            this.gameObject.add(gizmoObj);
            const box = gizmoObj.addNewComponent(BoxGizmo);
            if (box)
                box.isGizmo = false;
            const axes = new AxesHelper(.5);
            this.gameObject.add(axes)
        }
    }

    isXRRig(): boolean {
        return true;
    }

    supportsXR(_mode: XRSessionMode): boolean {
        return true;
    }

    private _startScale?: Vector3;

    /** @internal */
    onEnterXR(args: NeedleXREventArgs): void {
        this._startScale = this.gameObject.scale.clone();
        args.xr.addRig(this);
        if (debug) console.log("WebXR: add Rig", this.name, this.priority);
    }
    /** @internal */
    onLeaveXR(args: NeedleXREventArgs): void {
        args.xr.removeRig(this);
        if (this._startScale && this.gameObject)
            this.gameObject.scale.copy(this._startScale);
    }


}