import { world, system, ItemStack, BlockPermutation } from "@minecraft/server";
import { Vector } from './vector.js';
import { ActionFormData } from "@minecraft/server-ui";


system.afterEvents.scriptEventReceive.subscribe((data) => {
    const { id, sourceEntity, message } = data;

    if (id === "mf_mg:broomstick_remove") {
        if (!sourceEntity) return;

        sourceEntity.dimension.spawnItem(
            new ItemStack(`${sourceEntity.typeId}_spawn_egg`, 1),
            sourceEntity.location
        );
        sourceEntity.remove()
    }

    if (id === "mf_mg:wings_remove") {
        if (!sourceEntity) return;

        sourceEntity.dimension.spawnItem(
            new ItemStack(`${sourceEntity.typeId}_spawn_egg`, 1),
            sourceEntity.location
        );
        sourceEntity.remove()
    }

    if (id === 'mf_mg:broomstick_script_manager') {
        if (!sourceEntity) return
        const broomstickSim = new BroomstickClass(sourceEntity);
        broomstickSim.runSim();

    }

    if (id === 'mf_mg:broomstick_spawned') {
        if (!sourceEntity) return


    }

    if (id === 'mf_mg:wings_spawned') {
        if (!sourceEntity) return

        const player = sourceEntity.dimension.getEntities({ location: sourceEntity.location, maxDistance: 10, type: "minecraft:player" })[0]
        sourceEntity.getComponent("rideable").addRider(player);

        sourceEntity.addTag("mf_mg:wings_placed")

    }

    if (id === 'mf_mg:wings_leave') {
        if (!sourceEntity || !sourceEntity.hasTag("mf_mg:wings_placed")) return
        sourceEntity.dimension.spawnItem(
            new ItemStack(`${sourceEntity.typeId}_spawn_egg`, 1),
            sourceEntity.location
        );
        sourceEntity.remove()

    }

});




class BroomstickClass {
    constructor(broomstick) {
        this.broomstick = broomstick;
    }

    flyMovement(player) {
        const viewDirection = player.getViewDirection();

        this.broomstick.addEffect("speed", 1, { amplifier: 5, showParticles: false })
        if (viewDirection.y > 0 && viewDirection.y < 1) {
            this.broomstick.addEffect("levitation", 10, { amplifier: viewDirection.y * 8, showParticles: false })
        } else if (viewDirection.y > -1) {
            this.broomstick.addEffect("slow_falling", 10, { amplifier: (1 + viewDirection.y) * 3, showParticles: false })
        }
    }

    liquidLevitation() {
        const block = this.broomstick.dimension.getBlock(this.broomstick.location)
        if (!block) return
        if (block.below().typeId.includes("lava") || block.below().typeId.includes("water") || block.typeId.includes("lava") || block.typeId.includes("water")) {
            this.broomstick.addEffect("levitation", 10, { amplifier: 2, showParticles: false })
        }
    }

    adjustVelocityWithViewDirection(entity) {
        const velocity = entity.getVelocity();
        const viewDirection = entity.getViewDirection();
        const normViewDir = this.normalizeVector(viewDirection);
        const rightVelocity = velocity.z * normViewDir.x - velocity.x * normViewDir.z;

        return {
            left: Math.round(-rightVelocity * 100)
        };
    }

    dotProduct(vector1, vector2) {
        return vector1.x * vector2.x + vector1.z * vector2.z;
    }

    normalizeVector(vector) {
        const magnitude = Math.sqrt(vector.x ** 2 + vector.z ** 2);
        return { x: vector.x / magnitude, z: vector.z / magnitude };
    }

    calculateXZVelocity(entity) {
        const velocity = entity.getVelocity();
        return Math.sqrt(velocity.x ** 2 + velocity.z ** 2);
    }

    runSim() {
        const Launcher = system.runInterval(() => {
            try {
                let accesbroomstick = this.broomstick.location
            } catch {
                system.clearRun(Launcher);
                return;
            }
            const player = this.broomstick.getComponent("rideable").getRiders()[0]
            if (!this.broomstick || !player) {
                system.clearRun(Launcher);
                return;
            }

            if (this.broomstick.typeId.includes("wing")) {
                // player anim
                const elementNB = parseInt(this.broomstick.typeId.split("_")[2])

                switch (elementNB) {
                    case 2: player.addEffect("fire_resistance", 20, { amplifier: 1, showParticles: false }); break;
                    case 3: player.addEffect("water_breathing", 20, { amplifier: 1, showParticles: false }); break;
                    case 4: player.addEffect("speed", 20, { amplifier: 3, showParticles: false }); break;
                    case 5: player.addEffect("regeneration", 20, { amplifier: 1, showParticles: false }); break;
                    case 6: player.addEffect("resistance", 20, { amplifier: 2, showParticles: false }); break;
                    case 7: player.addEffect("strength", 20, { amplifier: 2, showParticles: false }); break;
                }
            }

            this.liquidLevitation()

            this.broomstick.addEffect("speed", 1, { amplifier: 1, showParticles: false })

            const currentVelocity = this.calculateXZVelocity(this.broomstick)
            const { left } = this.adjustVelocityWithViewDirection(this.broomstick);
            const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
            let steeringRotation = (left / -2) / (currentVelocity + 0.1);
            if (currentVelocity == 0)
                steeringRotation = 0
            this.broomstick.setProperty("mf_mg:steering", clamp(steeringRotation, -45, 45));

            if (player && this.broomstick.hasTag("mf_mg:hasPlayerRider")) {
                if (!this.broomstick.isOnGround) {
                    this.flyMovement(player)
                }
            }
        })
    }
}


