import { randomInt } from "../util/mthUtils";
import { BlockPermutation, Direction, system, world } from "@minecraft/server";
import { flipDir, isAxisVertical, offsetPos, setADirectionState } from "../util/dirUtils";
import { McItems } from "../reg/mcItems";
import { isBlockSolid, shrinkIfInSurvival, transmuteBlock, } from "../util/miscUtils";
import { SuppStates } from "../reg/suppStates";
import { hasStrongClickAction } from "../util/blockProperties";
import { getPlacementPosition, replaceBlock } from "../util/placementUtils";
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
    if (!event.isFirstEvent)
        return;
    const item = event.itemStack;
    if (!item || event.itemStack.typeId !== McItems.Book)
        return;
    const block = event.block;
    const face = event.blockFace;
    const level = block.dimension;
    const player = event.player;
    let targetBlock = getPlacementPosition(block, face, isBook);
    if (targetBlock) {
        const books = getBookCount(targetBlock.permutation);
        if (books < 3) {
            event.cancel = true;
            //must run later to be in non read mode
            system.run(() => {
                //add next in line
                const next = getNextBook(targetBlock);
                targetBlock.setPermutation(transmuteBlock(targetBlock.permutation, next));
                level.playSound("item.book.put", targetBlock.center(), { volume: 0.8, pitch: 1 });
                shrinkIfInSurvival(player, item);
            });
            return;
        }
    }
    targetBlock = getPlacementPosition(block, face);
    //place new book
    if (targetBlock && (player.isSneaking || !hasStrongClickAction(block)) && isBlockSolid(offsetPos(targetBlock, Direction.Down), Direction.Up)) {
        event.cancel = true;
        system.run(() => {
            if (isAxisVertical(face)) {
                replaceBlock(targetBlock, BlockPermutation.resolve("razz_sup:vertical_placeable_book" /* SuppBlocks.PlaceableBookVertical1 */));
            }
            else {
                let permutation = BlockPermutation.resolve("razz_sup:placeable_book" /* SuppBlocks.PlaceableBookHorizontal1 */);
                permutation = setADirectionState(permutation, flipDir(face));
                replaceBlock(targetBlock, permutation);
            }
            level.playSound("item.book.put", targetBlock.center(), { pitch: 1, volume: 0.8 });
            shrinkIfInSurvival(player, item);
        });
    }
});
const horizontal = [
    "razz_sup:placeable_book" /* SuppBlocks.PlaceableBookHorizontal1 */,
    "razz_sup:book_set" /* SuppBlocks.PlaceableBookHorizontal2 */,
    "razz_sup:book_stack" /* SuppBlocks.PlaceableBookHorizontal3 */,
    "razz_sup:book_pile" /* SuppBlocks.PlaceableBookHorizontal4 */,
];
const vertical = [
    "razz_sup:vertical_placeable_book" /* SuppBlocks.PlaceableBookVertical1 */,
    "razz_sup:vertical_book_set" /* SuppBlocks.PlaceableBookVertical2 */,
    "razz_sup:vertical_book_stack" /* SuppBlocks.PlaceableBookVertical3 */,
    "razz_sup:vertical_book_pile" /* SuppBlocks.PlaceableBookVertical4 */,
];
function getBookCount(block) {
    //gets the index in the arrays
    const id = block.type.id;
    const index = horizontal.indexOf(id);
    if (index == -1) {
        return vertical.indexOf(id);
    }
    return index;
}
function getNextBook(block) {
    //get next in array
    const id = block.typeId;
    const index = horizontal.indexOf(id);
    if (index != -1) {
        return horizontal[(index + 1) % horizontal.length];
    }
    const index2 = vertical.indexOf(id);
    if (index2 != -1) {
        return vertical[(index2 + 1) % vertical.length];
    }
}
function isBook(block) {
    const id = block.typeId;
    return horizontal.includes(id) || vertical.includes(id);
}
function randomizeBooks(block, bookAmount) {
    switch (bookAmount) {
        default:
            return block.withState(SuppStates.BookInt1, randomInt(0, 8));
        case 2:
            return block.withState(SuppStates.BookInt1, randomInt(0, 12))
                .withState(SuppStates.BookInt2, randomInt(0, 2));
        case 3:
            return block.withState(SuppStates.BookInt1, randomInt(0, 13))
                .withState(SuppStates.BookInt2, randomInt(0, 5));
        case 4:
            return block.withState(SuppStates.BookInt1, randomInt(0, 15))
                .withState(SuppStates.BookInt2, randomInt(0, 7));
    }
}
//TODO:use this for vertical one and remove their directionality
export const BookPileComponent = {
    //also called when placed via scripting, aparently. Also when pushed by a piston
    onPlace(event) {
        const block = event.block;
        block.setPermutation(randomizeBooks(block.permutation, getBookCount(block.permutation)));
    },
    onPlayerInteract(event) {
        //just needed for animation
    },
    beforeOnPlayerPlace: (event) => {
        //mimic event placement for creative placement
        if (isAxisVertical(event.face)) {
            //get the equivalent vertical by array lookup
            const id = event.permutationToPlace.type.id;
            const index = horizontal.indexOf(id);
            if (index != -1) {
                event.permutationToPlace = BlockPermutation.resolve(vertical[index]);
            }
        }
        event.permutationToPlace = randomizeBooks(event.permutationToPlace, getBookCount(event.permutationToPlace));
    }
};
export function preventsPlacementOverride(targetBlock) {
    //since we rely on the item use first event we must block the placement if we find a block behind that would normally take priority. Usually inventories
    return false;
}
