import { Direction, system } from "@minecraft/server";
import { SuppStates } from "../reg/suppStates";
import { flipDir, getADirectionState, getCounterClockwiseDir, offsetPos } from "../util/dirUtils";
import { suppEvents } from "../suppEventHandler";
import { McStates } from "../reg/mcStates";
import { getDoubleBlockHalf, isDoor, isReplaceable, setDoubleBlockHalf } from "../util/blockProperties";
import { breakBlock } from "../util/miscUtils";
import { McBlocks } from "../reg/mcBlocks";
function getFlippedHinge(permutation) {
    let hinge = permutation.getState(SuppStates.FlippedHinge);
    if (hinge == undefined) {
        hinge = permutation.getState(McStates.Hinge);
    }
    return hinge;
}
function setFlippedHinge(permutation, hinge) {
    if (permutation.getState(SuppStates.FlippedHinge) != undefined) {
        return permutation.withState(SuppStates.FlippedHinge, hinge);
    }
    if (permutation.getState(McStates.Hinge) != undefined) {
        return permutation.withState(McStates.Hinge, hinge);
    }
}
export const GoldTrapdoorComponent = {
    onPlayerInteract(event) {
        const block = event.block;
        const power = block.getRedstonePower() | 0;
        const powered = power > 0;
        if (!powered) {
            const opened = block.permutation.getState(SuppStates.Open);
            block.setPermutation(block.permutation.withState(SuppStates.Open, !opened));
            event.dimension.playSound(opened ? "close.iron_trapdoor" : "open.iron_trapdoor", block.center());
        }
        else {
            event.dimension.playSound("hit.copper", block.center(), { pitch: 0.5 });
        }
    }
};
export const GoldDoorComponent = {
    onPlayerInteract(event) {
        const block = event.block;
        const dir = getDoubleBlockHalf(block.permutation);
        const otherHalf = offsetPos(block, flipDir(dir));
        if (!otherHalf)
            return;
        const power = block.getRedstonePower() | 0;
        const power2 = otherHalf.getRedstonePower() | 0;
        const powered = (power + power2) > 0;
        if (!powered) {
            const opened = block.permutation.getState(SuppStates.Open);
            block.setPermutation(block.permutation.withState(SuppStates.Open, !opened));
            if (otherHalf && otherHalf.typeId == block.typeId) {
                otherHalf.setPermutation(otherHalf.permutation.withState(SuppStates.Open, !opened));
            }
            event.dimension.playSound(opened ? "close.iron_door" : "open.iron_door", block.center());
        }
        else {
            event.dimension.playSound("hit.copper", block.center(), { pitch: 0.5 });
        }
    },
    beforeOnPlayerPlace(event) {
        const block = event.block;
        const above = block.above();
        if (!above || !isReplaceable(above)) {
            event.cancel = true;
        }
        else {
            //place door above, instantly
            let myPerm = event.permutationToPlace;
            //check if it has a door next to it with same lower or upper
            const myDir = getADirectionState(myPerm);
            const blockWise = getCounterClockwiseDir(myDir);
            const neighbor = offsetPos(block, blockWise);
            if (neighbor && isDoor(neighbor.permutation) && getDoubleBlockHalf(neighbor.permutation) == getDoubleBlockHalf(myPerm)) {
                myPerm = setFlippedHinge(myPerm, true);
                event.permutationToPlace = myPerm;
            }
            const abovePerm = setDoubleBlockHalf(myPerm, Direction.Up);
            system.run(() => {
                block.dimension.setBlockPermutation(above.location, abovePerm);
            });
        }
    }
};
function breakIfInvalid(block, otherHalf) {
    if (!otherHalf || otherHalf.typeId != block.typeId ||
        otherHalf.permutation.getState(SuppStates.Open) != block.permutation.getState(SuppStates.Open) ||
        otherHalf.permutation.getState(SuppStates.UpperBlock) == block.permutation.getState(SuppStates.UpperBlock) ||
        otherHalf.permutation.getState(McStates.HorizontalDirection) != block.permutation.getState(McStates.HorizontalDirection)) {
        breakBlock(block);
    }
}
suppEvents.subscribeOnNeighborChanged((event) => {
    const block = event.block;
    if (block.typeId == "razz_sup:gold_door" /* SuppBlocks.GoldDoor */) {
        const dir = getDoubleBlockHalf(block.permutation);
        if (event.fromDir == flipDir(dir)) {
            breakIfInvalid(block, event.neighborBlock);
        }
        else if (event.fromDir == Direction.Down) {
            if (event.neighborBlock.isAir) {
                const above = block.above();
                if (above && above.typeId == block.typeId) {
                    breakBlock(above);
                }
                breakBlock(block);
            }
        }
    }
});
suppEvents.subscribeOnBlockCreativeBroken((event) => {
    const block = event.block;
    if (event.brokenBlockPermutation.type.id == "razz_sup:gold_door" /* SuppBlocks.GoldDoor */) {
        const dir = getDoubleBlockHalf(event.brokenBlockPermutation);
        const otherHalf = offsetPos(block, flipDir(dir));
        if (otherHalf && otherHalf.typeId == event.brokenBlockPermutation.type.id) {
            otherHalf.setType(McBlocks.Air);
        }
    }
});
