import { Entity, world, Player, InvalidEntityError, EntityRideableComponent } from "@minecraft/server"
import { GeneralUtils } from "../utils.js"

/**
 * @param {EntitySpawnAfterEvent} event - The event to use
 */
export const turretHandleEntitySpawn = (event) => {
    try {
        const entity = event.entity;
        if (entity.getProperty("af:has_turret")) {
            const spawned = entity.dimension.spawnEntity(`${entity.typeId}_turret`, entity.location);
            if (spawned) {
                entity.setDynamicProperty("turret_id", spawned.id)
            }
        }
    } catch (err) {
        if (!(err instanceof InvalidEntityError)) throw err;
    }
}

/**
 * @param {Entity} turretedEntity - The entity to use for the tick
 * @param {EntityRideableComponent} rideableComponent - The rideablle component to control the turret
 */
export const turretEntityTick = (turretedEntity, rideableComponent) => {
    const turret_id = turretedEntity.getDynamicProperty("turret_id");
    if (!turret_id) return;

    const turret = world.getEntity(turret_id);
    if (!turret) return;

    const offsetX = (turretedEntity.getProperty("af:turret.offset-x") ?? 0) / 10
    const offsetY = (turretedEntity.getProperty("af:turret.offset-y") ?? 0) / 10
    const offsetZ = (turretedEntity.getProperty("af:turret.offset-z") ?? 0) / 10
    const endDeadzonePitch = turretedEntity.getProperty("af:turret.end-deadzone-pitch") ?? 40
    const endDeadzoneYaw = turretedEntity.getProperty("af:turret.end-deadzone-yaw") ?? -1
    const turretSpeedDPS = turretedEntity.getProperty("af:turret.speed") ?? 90;
    const turretDrag = GeneralUtils.math.toDeg(turretedEntity.getDynamicProperty("turret_drag")) ?? 0;

    const turretControllerPlayer = GeneralUtils.world.getPlayerFromEntity(rideableComponent.getRiders()[rideableComponent.controllingSeat]);
    const targetRot = turretControllerPlayer ? turretControllerPlayer.getRotation() : undefined;

    var rotation = GeneralUtils.world.rotateByClamped(turret, targetRot, turretSpeedDPS, { x: 0, y: turretDrag });

    if (endDeadzonePitch >= 0) {
        rotation.x = GeneralUtils.math.clamp(rotation.x, -endDeadzonePitch, endDeadzonePitch);
    }
    if (endDeadzoneYaw >= 0) {
        rotation.y = GeneralUtils.math.clamp(rotation.y, -endDeadzoneYaw, endDeadzoneYaw);
    }

    const entityRot = turretedEntity.getRotation();
    const entityPos = turretedEntity.location;

    const yawRad = GeneralUtils.math.toRad(entityRot.y);
    const pitchRad = GeneralUtils.math.toRad(entityRot.x);

    const yawCos = Math.cos(yawRad), yawSin = Math.sin(yawRad);
    const pitchCos = Math.cos(pitchRad), pitchSin = Math.sin(pitchRad);

    turret.teleport(
        {
            x: entityPos.x + offsetX * yawCos - offsetZ * yawSin,
            y: entityPos.y + offsetY * pitchCos - offsetZ * pitchSin,
            z: entityPos.z + offsetX * yawSin + offsetZ * yawCos
        },
        { rotation: { x: rotation.x - 15, y: rotation.y } }
    );

    turret.setRotation({ x: rotation.x - 15, y: rotation.y });

    turretedEntity.setDynamicProperty("turret-pitch", rotation.x - 15);
    turretedEntity.setDynamicProperty("turret-yaw", rotation.y);
}