import { BlockPermutation, Direction, system, world } from "@minecraft/server";
import { SuppTags } from "./reg/suppTags";
import { isReplaceable } from "./util/blockProperties";
import { getPlacementPosition } from "./util/placementUtils";
import { SuppStates } from "./reg/suppStates";
import { shrinkIfInSurvival } from "./util/miscUtils";
//very dumb, just needed for client side animation as aparently the stuff below still lets vanilla logic apply on the client
export const SlabCancelPlacementComponent = {
    //apparently having this also swings the animation JUST on empty item, at random. too bad this time we dont want this...
    beforeOnPlayerPlace: (event) => {
        const targetPos = getValidTargetLayerBlock(event.block, event.face, event.permutationToPlace.type.id, 1);
        if (targetPos) {
            event.cancel = true;
        }
    }
};
export const SlabItemAnimationComponent = {
    onUseOn: (event) => {
        //actualy might aswell put all this in use on.
        //TODO: we need an item for this
    }
};
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
    if (!event.isFirstEvent)
        return;
    const item = event.itemStack;
    if (!item)
        return;
    if (item.typeId == "razz_sup:ash" /* SuppBlocks.Ash */ || item.typeId == "razz_sup:pancake" /* SuppBlocks.Pancakes */) {
        event.cancel = incrementLayers(event.block, item, event.player, event.blockFace, 8);
    }
    else if (isSlab(item.typeId)) {
        event.cancel = incrementLayers(event.block, item, event.player, event.blockFace, 1);
    }
});
function isSlab(id) {
    try {
        return BlockPermutation.resolve(id).hasTag(SuppTags.Slabs);
    }
    catch (e) {
    }
    return false;
}
function getValidTargetLayerBlock(block, face, typeId, maxValue) {
    let ignoreWhenNeighborIs = undefined;
    if (maxValue == 1 && !isSameFaceAsMissingSide(block, face)) {
        ignoreWhenNeighborIs = isReplaceable;
    }
    return getPlacementPosition(block, face, (b) => b && (b.typeId == typeId) && (getLayers(b) != maxValue));
}
export function getLayers(targetBlock) {
    return getLayersPerm(targetBlock.permutation);
}
export function getLayersPerm(perm) {
    return perm.getState(SuppStates.LayerCount);
}
function incrementLayers(block, item, player, face, maxValue) {
    const targetBlock = getValidTargetLayerBlock(block, face, item.typeId, maxValue);
    if (!targetBlock)
        return false;
    const currentLayerCount = getLayers(targetBlock);
    const newLayerCount = Math.min(currentLayerCount + 1, maxValue);
    system.run(() => {
        const level = targetBlock.dimension;
        level.setBlockPermutation(targetBlock.location, targetBlock.permutation.withState(SuppStates.LayerCount, newLayerCount));
        shrinkIfInSurvival(player, item);
        //mega dumb. why is it using using sounds!!! These are same as stripping sounds for logs!!!
        const sound = getSoundType(targetBlock.typeId);
        level.playSound(sound, targetBlock.center(), { volume: 1, pitch: 1 });
    });
    return true;
}
function getSoundType(typeId) {
    switch (typeId) {
        case "razz_sup:ash" /* SuppBlocks.Ash */:
            return 'dig.sand';
        case "razz_sup:fine_wood_slab" /* SuppBlocks.FineWoodSlab */:
            return 'use.wood';
        case "razz_sup:pancake" /* SuppBlocks.Pancakes */:
            return 'hit.cloth';
        default:
            return 'use.stone';
    }
}
function isSameFaceAsMissingSide(b, face) {
    const top = b.permutation.getState("minecraft:vertical_half") == "top";
    return (!top && face == Direction.Up) || (top && face == Direction.Down);
}
