import * as mc from "@minecraft/server";
import { dinoList, meteor, amber } from "./constants";
import { NAMESPACE } from "./anvilConstants";
export function getCardinalRotation(identifier, block) {
    if (block.permutation.matches(identifier, { "minecraft:cardinal_direction": "south" })) {
        return "south";
    }
    if (block.permutation.matches(identifier, { "minecraft:cardinal_direction": "east" })) {
        return "east";
    }
    if (block.permutation.matches(identifier, { "minecraft:cardinal_direction": "west" })) {
        return "west";
    }
    return "north";
}
export function cardinalRotationToDegrees(cardinalRotation) {
    switch (cardinalRotation) {
        case "north":
            return 0;
        case "east":
            return 90;
        case "south":
            return 180;
        case "west":
            return 270;
    }
    return 0;
}
export function rotationToCardinalRotation(rotation) {
    switch (rotation) {
        case 0:
            return "north";
        case 90:
            return "east";
        case 180:
            return "south";
        case 270:
            return "west";
    }
    return "north";
}
export function getSyringeDNAInfo(itemStack) {
    const itemStackLore = itemStack.getLore();
    if (itemStackLore.length > 0) {
        const status = itemStackLore[1].includes("§bReady§r");
        const dinoName = Object.keys(dinoList).find((key) => {
            return dinoList[key].name === itemStackLore[2].split("§8")[1].replace("§r", "");
        });
        const playerName = itemStackLore[3].split("§8")[1].replace("§r", "");
        return { status: status, dinoName: dinoName, playerName: playerName };
    }
    else {
        return undefined;
    }
}
export function setSyringeDNAInfo(item, ready, dinoName, playerName) {
    item.setLore([
        "",
        `§rState§r: ${ready ? "§bReady§r" : "§cNot Ready§r"}`,
        `§dDinosaur DNA§r: ${dinoName ? `§8${dinoList[dinoName].name}§r` : "§8None§r"}`,
        `§aPlayer DNA§r: ${playerName ? `§8${playerName}§r` : "§8None§r"}`,
    ]);
    item.setDynamicProperty(`${NAMESPACE}:ready`, ready);
    item.setDynamicProperty(`${NAMESPACE}:dinosaur`, dinoName);
    item.setDynamicProperty(`${NAMESPACE}:player`, playerName);
    if (ready) {
        item.nameTag = `${dinoList[dinoName].name} §2[Dinosaurs]§r`;
    }
}
export function dinosaurCanRoar(entity) {
    return entity.getProperty(`${NAMESPACE}:can_roar_on_kill`) === true;
}
export function isPlayer(entity) {
    return entity.typeId === "minecraft:player";
}
export function isDinosaur(entity) {
    return Object.keys(dinoList).includes(entity.typeId.replace(`${NAMESPACE}:`, ""));
}
export function takeOneItem(player, itemStack) {
    const playerEquippable = player.getComponent("minecraft:equippable");
    itemStack.amount = itemStack.amount > 1 ? itemStack.amount - 1 : itemStack.amount;
    playerEquippable.setEquipment(mc.EquipmentSlot.Mainhand, itemStack.amount > 1 ? itemStack : undefined);
}
export function setItemDinoDNALore(itemName, dino) {
    let item = new mc.ItemStack(itemName, 1);
    item.setLore(["", `§gDNA:§r §8${dino}§r`]);
    item.setDynamicProperty(`${NAMESPACE}:dinosaur`, dino);
    return item;
}
export function getItemDinoDNAInfo(itemStack) {
    const itemStackLore = itemStack.getLore();
    if (itemStackLore.length > 0) {
        const dinoName = itemStack.getDynamicProperty(`${NAMESPACE}:dinosaur`);
        return Object.keys(dinoList).find((key) => dinoList[key].name === dinoName);
    }
    else {
        return undefined;
    }
}
export function giveItemToPlayer(player, itemStack) {
    const playerInv = player.getComponent("minecraft:inventory");
    playerInv.container?.addItem(itemStack);
}
function toRadians(degrees) {
    return degrees * (Math.PI / 180);
}
export function getOffsetRelativeToEntityRotation(player, offset) {
    const yawRadians = toRadians(player.getRotation().y);
    const pitchRadians = toRadians(player.getRotation().x);
    const sinYaw = Math.sin(yawRadians);
    const cosYaw = Math.cos(yawRadians);
    const sinPitch = Math.sin(pitchRadians);
    const cosPitch = Math.cos(pitchRadians);
    const deltaX = cosYaw * offset.x - sinYaw * offset.z;
    const deltaZ = sinYaw * offset.x + cosYaw * offset.z;
    const deltaY = cosPitch * offset.y + sinPitch * Math.sqrt(offset.x * offset.x + offset.z * offset.z);
    return {
        x: player.location.x + cosPitch * deltaX,
        y: player.location.y + deltaY,
        z: player.location.z + cosPitch * deltaZ,
    };
}
export function thirdPersonOverShoulder(player, offset) {
    player.camera.setCamera("minecraft:free", {
        rotation: player.getRotation(),
        location: getOffsetRelativeToEntityRotation(player, offset),
        easeOptions: {
            easeTime: 0.2,
            easeType: mc.EasingType.Linear,
        },
    });
}
export function getCoordinatesInLine(player, entity) {
    const playerLocation = player.location;
    const entityLocation = entity.location;
    const dx = entityLocation.x - playerLocation.x;
    const dy = entityLocation.y - playerLocation.y;
    const dz = entityLocation.z - playerLocation.z;
    const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
    const stepX = dx / distance;
    const stepY = dy / distance;
    const stepZ = dz / distance;
    const coordinates = [];
    for (let i = 0; i < distance; i++) {
        const x = playerLocation.x + stepX * i;
        const y = playerLocation.y + stepY * i + 1.5;
        const z = playerLocation.z + stepZ * i;
        coordinates.push({
            x: x,
            y: y,
            z: z,
        });
    }
    return coordinates;
}
export function droprandomDinosaurDNAmber(event) {
    const block = event.block;
    if (block.typeId === `${NAMESPACE}:amber_ore` || block.typeId === `${NAMESPACE}:deepslate_amber_ore`) {
        const dinoNames = Object.values(dinoList).map(dino => dino.name);
        const randomIndex = Math.floor(Math.random() * dinoNames.length);
        const dinoName = dinoNames[randomIndex];
        mc.system.run(() => {
          const itemStack = setItemDinoDNALore(amber, dinoName);
          block.dimension.spawnItem(itemStack, block.location);
        });
    }
}
export function spawnXPandAmber(hitEntity, damagingEntity) {
    if (hitEntity && damagingEntity) {
        const isBaby = hitEntity.getComponent(mc.EntityIsBabyComponent.componentId);
        const health = hitEntity.getComponent(mc.EntityHealthComponent.componentId);
        if (
            hitEntity.isValid() &&
            isDinosaur(hitEntity) &&
            hitEntity.dimension.getBlock(hitEntity.location)?.isValid() &&
            !isBaby &&
            health.currentValue <= 1 &&
            hitEntity.location.y > -64 &&
            hitEntity.location.y < 512
        ) {
            if (!hitEntity.hasTag(`${NAMESPACE}:droppedXPandAmber`)) {
                hitEntity.addTag(`${NAMESPACE}:droppedXPandAmber`);
                if (damagingEntity.typeId === "minecraft:player") {
                    const xpCount = Math.ceil((Math.random() * health.defaultValue) / 10);
                    for (let i = 0; i < xpCount; i++) {
                        hitEntity.dimension.spawnEntity("minecraft:xp_orb", hitEntity.location);
                    }
                }
                const dinoName = dinoList[hitEntity.typeId.replace(`${NAMESPACE}:`, "")].name;
                const itemStack = setItemDinoDNALore(amber, dinoName);
                hitEntity.dimension.spawnItem(itemStack, hitEntity.location);
            }
        }
    }
}
export function triggerDinosaurRoar(killerEntity, deadEntity) {
    if (isPlayer(deadEntity) || isDinosaur(deadEntity)) {
        if (killerEntity && isDinosaur(killerEntity) && dinosaurCanRoar(killerEntity)) {
            killerEntity.triggerEvent("is_roaring");
            killerEntity.dimension
                .getEntities({ location: killerEntity.location, maxDistance: 10, excludeTypes: ["item", "player", "xp_orb"] })
                .forEach((entity) => {
                    if (entity.isValid() && killerEntity.id !== entity.id) {
                        const vector = {
                            x: entity.location.x - killerEntity.location.x,
                            y: entity.location.y - killerEntity.location.y,
                            z: entity.location.z - killerEntity.location.z,
                        };
                        try {
                            entity.applyKnockback(vector.x, vector.z, 8, 0.8);
                        }
                        catch (e) { }
                    }
                });
        }
    }
}
export function meteorEvent() {
    const players = mc.world.getAllPlayers();
    for (const player of players) {
        const location = {
            x: player.location.x + Math.random() * 60 - 30,
            y: player.location.y,
            z: player.location.z + Math.random() * 60 - 30,
        };
        if (player.dimension.getBlock(location)?.isValid()) {
            player.dimension.spawnEntity(meteor, location);
        }
    }
}
export function getEntityName(namespace) {
    return namespace.replace(`${NAMESPACE}:`, "");
}
export function getEntityDisplayName(namespace) {
    return dinoList[getEntityName(namespace)].name;
}
export function poisonSpray(eventData) {
    const entity = eventData.sourceEntity;
    const id = eventData.id;
    if (id === `${NAMESPACE}:poison_spray` && isDinosaur(entity)) {
        entity.getEntitiesFromViewDirection({ maxDistance: 10 }).forEach((entity) => {
            if (!["item", "xp_orb"].includes(entity.entity.typeId)) {
                entity.entity.addEffect("poison", 10, { amplifier: 3 });
                entity.entity.addEffect("nausea", 10, { amplifier: 3 });
            }
        });
    }
}
export function damageItem(player) {
    const equippable = player.getComponent("minecraft:equippable");
    if (!equippable) return;
    const mainhand = equippable.getEquipmentSlot(mc.EquipmentSlot.Mainhand);
    if (!mainhand.hasItem()) return;
    if (player.getGameMode() === mc.GameMode.creative) return;
    const itemStack = mainhand.getItem();
    const durability = itemStack.getComponent("minecraft:durability");
    if (!durability) return;
    const enchantable = itemStack.getComponent("minecraft:enchantable");
    const unbreakingLevel = enchantable?.getEnchantment("unbreaking")?.level;
    const damageChance = durability.getDamageChance(unbreakingLevel) / 100;
    if (Math.random() > damageChance) return;
    const shouldBreak = durability.damage === durability.maxDurability;
    if (shouldBreak) {
        mainhand.setItem(undefined);
        player.playSound("random.break");
    } else {
        durability.damage++;
        mainhand.setItem(itemStack);
    }
}
export function getOrCreateScoreboard(id) {
    let scoreboard = mc.world.scoreboard.getObjective(id);
    if (!scoreboard) {
        scoreboard = mc.world.scoreboard.addObjective(id, id);
    }
    return scoreboard;
}