import { Direction, EntityComponentTypes, ItemStack, Player, system, world } from "@minecraft/server";
import { SuppEntities } from "../reg/suppEntities";
import { offsetVec } from "../util/dirUtils";
import { getPlacementPosition } from "../util/placementUtils";
import { getItemInInventory, giveItemToPlayer, goesInHatSlot, isBlockSolid, isLivingEntity, playSwingArm, setItemOnHead, shrinkIfInSurvival } from "../util/miscUtils";
import { vecDiff, vecScale, vecSum } from "../util/mthUtils";
import { McEntities } from "../reg/mcEntities";
import { isBottomSlab } from "../util/blockProperties";
import { SuppParticles } from "../reg/suppParticles";
world.afterEvents.dataDrivenEntityTrigger.subscribe((event) => {
    let entity = event.entity;
    if (entity.typeId == SuppEntities.HatStand && event.eventId == "razz_sup:damaged_by_player") {
        // Get the variant component
        const itemStack = new ItemStack(entity.typeId, 1); // Drops the same item as the entity type
        const currentHatStandHat = getItemInInventory(entity, 0);
        if (currentHatStandHat) {
            entity.dimension.spawnItem(currentHatStandHat, offsetVec(entity.location, Direction.Up, 0.125));
        }
        entity.dimension.spawnItem(itemStack, offsetVec(entity.location, Direction.Up, 0.125));
        entity.dimension.spawnParticle(SuppParticles.BreakingHatStand, entity.location);
        // Remove the entity
        entity.remove();
    }
});
export const HatStandItemComponent = {
    onUseOn(event) {
        const block = getPlacementPosition(event.block, event.blockFace);
        if (block) {
            const below = block.below();
            const isSlab = isBottomSlab(below);
            if (isSlab || isBlockSolid(block.below(), Direction.Up)) {
                //check for entities
                const eOpt = {
                    location: block.location,
                    volume: { x: 0, y: 1, z: 0 },
                    closest: 100,
                };
                let entities = block.dimension.getEntities(eOpt);
                entities = entities.filter(e => (!isLivingEntity(e) && e.typeId != McEntities.Item));
                if (entities.length == 0) {
                    const player = event.source;
                    const item = event.itemStack;
                    const cushion = event.block.dimension.spawnEntity(item.typeId, offsetVec(event.block.bottomCenter(), Direction.Up, isSlab ? 0.5 : 1));
                    //thanks mojang for this
                    const actualFacePos = vecScale(vecSum(event.faceLocation, { x: -1, y: -1, z: -1 }), -1);
                    let hitDir = vecDiff(actualFacePos, //TODO:bug from mojang
                    event.source.getHeadLocation()); //yeah face rotation is inverted for some reason...
                    //calculate yaw in degrees
                    let yaw = 90 + Math.atan2(hitDir.z, hitDir.x) * (180 / Math.PI);
                    //mae yaw a multiple of 22.5
                    yaw = Math.round(yaw / 22.5) * 22.5;
                    //set color
                    cushion.setRotation({ x: 0, y: yaw });
                    cushion.dimension.playSound("dig.wood", cushion.location);
                    if (player instanceof Player) {
                        shrinkIfInSurvival(player, item);
                    }
                }
            }
        }
    }
};
world.beforeEvents.playerInteractWithEntity.subscribe((event) => {
    const entity = event.target;
    if (entity.typeId == SuppEntities.HatStand) {
        event.cancel = true;
        const item = event.itemStack;
        const inv = entity.getComponent(EntityComponentTypes.Inventory);
        if (inv && inv.container) {
            const currentHatStandHat = inv.container.getItem(0);
            const player = event.player;
            if (!currentHatStandHat && item) {
                if (goesInHatSlot(item)) {
                    system.run(() => {
                        playSwingArm(player);
                        const hatClone = item.clone();
                        hatClone.amount = 1;
                        setItemOnHead(entity, hatClone);
                        inv.container.setItem(0, hatClone);
                        shrinkIfInSurvival(player, item);
                    });
                }
                return;
            }
            if (!item && currentHatStandHat && player.isSneaking) {
                system.run(() => {
                    playSwingArm(player);
                    setItemOnHead(entity, undefined);
                    inv.container.setItem(0, undefined);
                    giveItemToPlayer(player, currentHatStandHat);
                });
                return;
            }
            system.run(() => {
                playSwingArm(player);
                entity.playAnimation("animation.razz_sup.hat_stand_wobble");
            });
        }
    }
});
