import { world, system, EasingType, EntityRideableComponent, Entity } from "@minecraft/server";
import { GeneralUtils } from "../utils.js";

/**
 * @param {Entity} planeEntity - The entity to use for the tick
 * @param {EntityRideableComponent} rideable_component - The rideable component to use for the tick
 */
export const planeEntityTick = (planeEntity, rideable_component) => {
    // --- Properties ---
    const planeSpeed = planeEntity.getProperty("af:plane.speed")
    const takeoffspeed = planeEntity.getProperty("af:plane.takeoffspeed") ?? planeSpeed / 2;
    const turnRate = planeEntity.getProperty("af:plane.turnrate") ?? 3

    if (!planeSpeed) return;

    var currentPlaneThrottle = planeEntity.getDynamicProperty("planeThrottle");

    if (!currentPlaneThrottle) {
        planeEntity.setDynamicProperty("planeThrottle", 0)
        currentPlaneThrottle = 0;
    }

    const riding_controller = rideable_component.getRiders()[rideable_component.controllingSeat]

    if (riding_controller) {
        const player = GeneralUtils.world.getPlayerFromEntity(riding_controller)

        if (player) {
            const playerInput = player.inputInfo.getMovementVector();

            if (playerInput.y > 0) {
                currentPlaneThrottle += playerInput.y / 50
            } else {
                if (currentPlaneThrottle > takeoffspeed) {
                    currentPlaneThrottle -= 0.1
                }
                if (planeEntity.isOnGround) {
                    currentPlaneThrottle -= 0.1
                }
            }

            const playerRotation = player.getRotation();
            const currentRotation = planeEntity.getRotation();
            const yawDiff = ((playerRotation.y - currentRotation.y + 540) % 360) - 180;
            const easingFactor = 0.1 / turnRate;

            if (planeEntity.isOnGround && planeSpeed <= takeoffspeed) {
                planeEntity.setRotation({
                    x: currentRotation.x,
                    y: currentRotation.y + yawDiff * easingFactor
                });
            } else {
                const easedYaw = currentRotation.y + yawDiff * easingFactor;
                const easedYawRad = GeneralUtils.math.toRad(easedYaw);

                planeEntity.lookAt({
                    x: planeEntity.location.x + Math.sin(-easedYawRad) * 100,
                    y: planeEntity.location.y - Math.max(playerRotation.x, currentPlaneThrottle * -40),
                    z: planeEntity.location.z + Math.cos(-easedYawRad) * 100
                });
            }

            if (currentPlaneThrottle > planeSpeed) {
                currentPlaneThrottle = planeSpeed
            }

            if (currentPlaneThrottle < 0) {
                currentPlaneThrottle = 0
            }

            player.onScreenDisplay.setActionBar(`Throttle: ${Math.round(currentPlaneThrottle * 10) / 10} / ${planeSpeed}`)
        }
    } else if (currentPlaneThrottle > 0) {
        currentPlaneThrottle -= 0.1;
    }

    if (currentPlaneThrottle > planeSpeed) {
        currentPlaneThrottle = planeSpeed
    }

    if (currentPlaneThrottle < 0) {
        currentPlaneThrottle = 0
    }

    const rotation = planeEntity.getRotation();

    planeEntity.setRotation({
        x: rotation.x + (((180 - rotation.x) / 10) / (currentPlaneThrottle + 1)) * !planeEntity.isOnGround,
        y: rotation.y,
    })

    const velocity = {
        x: -Math.sin(GeneralUtils.math.toRad(rotation.y)) * Math.cos(GeneralUtils.math.toRad(rotation.x)) * currentPlaneThrottle,
        y: (-Math.sin(GeneralUtils.math.toRad(rotation.x)) * currentPlaneThrottle) - (((150 / (180 - rotation.x)) + planeEntity.getVelocity().y)) + ((currentPlaneThrottle / takeoffspeed) / 2),
        z: Math.cos(GeneralUtils.math.toRad(rotation.y)) * Math.cos(GeneralUtils.math.toRad(rotation.x)) * currentPlaneThrottle
    };

    if (planeEntity.isOnGround) {
        if (rotation.x > 60) {
            planeEntity.applyDamage(rotation.x - 60)
            if (!riding_controller) {
                planeEntity.triggerEvent("af:explode");
            }
        }

        if (velocity.y < -1) {
            planeEntity.applyDamage((-velocity.y - 1) * 5)
            if (!riding_controller) {
                planeEntity.triggerEvent("af:explode");
            }
        }
    }

    planeEntity.clearVelocity()
    planeEntity.applyImpulse(velocity)

    planeEntity.setDynamicProperty("planeThrottle", currentPlaneThrottle)
}