import * as mc from "@minecraft/server";
import { NAMESPACE } from "../anvilConstants";
import { restoreInventory } from "../inventoryManager/restoreInventory";
import { playerCameraOffset } from "./morphPlayer";
import { saveInventory } from "../inventoryManager/saveInventory";
import { dinoList, unmorphSyringe } from "../constants";
import { isDinosaur, isPlayer, setSyringeDNAInfo } from "../utilities";
function giveLockedItem(itemIdentifier, amount = 1) {
    const item = new mc.ItemStack(itemIdentifier, amount);
    item.lockMode = mc.ItemLockMode.slot;
    return item;
}
function giveMorphActionItems(player, morphName) {
    const invComponent = player.getComponent("minecraft:inventory");
    for (let i = 0; i < 36; i++) {
        invComponent.container.setItem(i, giveLockedItem(`${NAMESPACE}:locked_slot`, 1));
    }
    let slots = [4, 3, 5, 2, 6, 1, 7, 0, 8];
    const syringe = new mc.ItemStack(unmorphSyringe, 1);
    syringe.lockMode = mc.ItemLockMode.slot;
    setSyringeDNAInfo(syringe, true, morphName, player.name);
    invComponent.container.setItem(slots.shift(), syringe);
    if (dinoList[morphName].roar) {
        const item = giveLockedItem(`${NAMESPACE}:morph_roar`, 1);
        invComponent.container.setItem(slots.shift(), item);
    }
    if (dinoList[morphName].attack_animation) {
        const item = giveLockedItem(`${NAMESPACE}:morph_attack`, 1);
        invComponent.container.setItem(slots.shift(), item);
    }
    if (dinoList[morphName].can_grab) {
        const item = giveLockedItem(`${NAMESPACE}:morph_grab`, 1);
        invComponent.container.setItem(slots.shift(), item);
    }
    if (dinoList[morphName].can_sprint) {
        const item = giveLockedItem(`${NAMESPACE}:morph_sprint`, 1);
        invComponent.container.setItem(slots.shift(), item);
    }
    if (dinoList[morphName].can_charge) {
        const item = giveLockedItem(`${NAMESPACE}:morph_charge`, 1);
        invComponent.container.setItem(slots.shift(), item)
    }
    if (dinoList[morphName].can_sleep) {
        const item = giveLockedItem(`${NAMESPACE}:morph_sleep`, 1);
        invComponent.container.setItem(slots.shift(), item);
    }
    if (dinoList[morphName].has_variant) {
        const item = giveLockedItem(`${NAMESPACE}:morph_switch_variant`, 1);
        invComponent.container.setItem(slots.shift(), item);
    }
}
export function damageMorph(player) {
    if (player && isPlayer(player) && player.getDynamicProperty(`${NAMESPACE}:morph_name`)) {
        player.dimension
            .getEntities({
                location: player.location,
                closest: 1,
                tags: [`${NAMESPACE}.owner.${player.id.toString()}`],
                excludeTypes: ["player"],
            })
            .forEach((entity) => {
                entity.applyDamage(5);
            });
    }
}
export function morphDeath(eventData) {
    if (eventData.entity.isValid() &&
        isDinosaur(eventData.entity) &&
        eventData.entity.getProperty(`${NAMESPACE}:is_morphed`) === true &&
        eventData.newValue <= 1) {
        let playerId = eventData.entity
            .getTags()
            .find((tag) => tag.startsWith(`${NAMESPACE}.owner.`))
            .split(".")[2];
        const player = eventData.entity.dimension.getPlayers({ location: eventData.entity.location, tags: [playerId], closest: 1 })[0];
        endMorphing(player);
        mc.system.runTimeout(() => player.kill(), 10);
    }
}
export function endMorphing(player) {
    try {
        restoreInventory(player, player.id);
    }
    catch (e) { }
    player.removeEffect("invisibility");
    player.removeEffect("resistance");
    player.runCommand(`/ride @s stop_riding`);
    player.runCommand("/inputpermission set @s camera enabled");
    player.runCommand("/inputpermission set @s movement enabled");
    player.runCommand(`/tag @s remove ${NAMESPACE}:is_morphed`);
    player.setDynamicProperty(`${NAMESPACE}:morph_name`, undefined);
    mc.system.runTimeout(() => {
        if (player.isValid()) {
            player.camera.clear();
        }
    }, 5);
}
export function startMorphing(player, morphName) {
    player.setDynamicProperty(`${NAMESPACE}:morph_name`, morphName);
    player.runCommand(`/ride @s summon_ride ${NAMESPACE}:${morphName} reassign_rides "morph"`);
    player.addEffect("invisibility", 999999, { showParticles: false });
    player.addEffect("resistance", 999999, { amplifier: 255, showParticles: false });
    player.runCommand(`titleraw @s actionbar ${JSON.stringify({ rawtext: [{ translate: `${NAMESPACE}.morph_end` }] })}`);
    player.runCommand(`/tag @s add ${NAMESPACE}:is_morphed`);
    player.dimension
        .getEntities({ location: player.location, closest: 1, type: `${NAMESPACE}:${morphName}` })[0]
        .addTag(`${NAMESPACE}.owner.${player.id.toString()}`);
    saveInventory(player, player.id);
    giveMorphActionItems(player, morphName);
}
export function morphTick(player) {
    if (player.isValid() && player.getDynamicProperty(`${NAMESPACE}:morph_name`)) {
        playerCameraOffset(player);
        const morph = player.dimension.getEntities({
            location: player.location,
            closest: 1,
            tags: [`${NAMESPACE}.owner.${player.id.toString()}`],
            excludeTypes: ["minecraft:player"],
        })[0];
        if (!morph || morph.getProperty(`${NAMESPACE}:is_morphing`) === false) {
            endMorphing(player);
        }
        if (!player.getComponent("minecraft:riding") && player.hasTag(`${NAMESPACE}:is_morphed`)) {
        	morph.triggerEvent("end_morph");
        	endMorphing(player);
        }
    }
}