import { Delegate, JoystickC } from "@24tools/playable_template";
import { Vector3 } from "three";
import { IMoveInput } from "./MoveInput";
import { FollowCameraC } from "../Movment/CameraMovment/FollowCamera";

export class PlayerInput implements IMoveInput {
    private static threshold = 0.25;

    public static initJoystick() {
        const screenSize = window.screenSize;
        const minSize = Math.min(screenSize.width, screenSize.height);
        const joystickSizeAspect = 0.2;
        const options = {
            zone: document.getElementById("joystick_zone") as HTMLElement,
            size: minSize * joystickSizeAspect,
            restJoystick: true,
            dynamicPage: true,
            catchDistance: minSize * joystickSizeAspect / 2,
            fadeTime: 200,
        };
        JoystickC.init(options);
    }

    protected currentDirection = new Vector3();
    private moveDelegate: Delegate<any>;
    private stopDelegate: Delegate<any>;
    private startDelegate: Delegate<any>;

    get CurrentDirection() {
        return this.currentDirection;
    }

    get IsActive() {
        return this.inputActive;
    }

    inputActive = false;

    constructor() {
        this.moveDelegate = JoystickC.onJoysticMove.addDelegate(this.onTouchMove.bind(this));
        JoystickC.onJoysticDown.addListener(this.moveDelegate);
        this.stopDelegate = JoystickC.onJoysticEnd.addDelegate(this.onTouchUp.bind(this));
        this.startDelegate = JoystickC.onJoysticStart.addDelegate(this.onTouchDown.bind(this));
    }

    onTouchMove(payload: any) {
        this.getDirection(payload, this.currentDirection);
        if (this.currentDirection.length() <= PlayerInput.threshold) {
            this.currentDirection.multiplyScalar(0);
        }
    }

    onTouchDown(_event: any) {
        if (this.inputActive) return;
        this.inputActive = true;
    }

    onTouchUp() {
        if (!this.inputActive) return;
        this.inputActive = false;
        this.currentDirection.multiplyScalar(0);
    }

    private getDirection(payload: any, out: Vector3) {
        const normalizedData =
            payload?.data ??
            payload?.event?.data ??
            payload?.event;
        const vector = normalizedData?.vector;
        if (!vector) {
            out.set(0, 0, 0);
            return out;
        }

        out.set(-vector.x, 0, vector.y);
        out.applyEuler(FollowCameraC.RotationCorrection);
        return out;
    }
}
