import { Direction, ItemStack, Player, system, world } from "@minecraft/server";
import { stripColorFromId } from "./util/colorUtils";
import { giveItemToPlayer, splitRes } from "./util/miscUtils";
import { SuppItems } from "./reg/suppItems";
import { configs } from "./configs";
import { ConfigPage, UIBuilder } from "./util/uiBuilder";
import { EnumEntry } from "./util/configsUtils";
import { addonRes } from "./main";
export const GuideBookComponent = {
    onUse(event) {
        const player = event.source;
        openBookIfNotAlreadyOpened(player);
    }
};
const aliases = new Map([
    ["gold_trapdoor", "gold_door"],
    ["lapis_bricks", "gem_bricks"],
    ["emerald_bricks", "gem_bricks"],
    ["diamond_bricks", "gem_bricks"],
    ["redstone_bricks", "gem_bricks"],
    ["amethyst_bricks", "gem_bricks"],
]);
function getPageNameFromBlock(block) {
    const [namespace, path] = splitRes(block.typeId);
    return stripColorFromId(path);
}
function findPage(block) {
    const blockId = block.typeId;
    const [namespace, path] = splitRes(blockId);
    for (const page of bookUI.walkPages()) {
        const blockIdOrAlias = aliases.get(path) ?? path;
        if (blockIdOrAlias.includes(page.name)) {
            return page.id; // Return the first matching page
        }
    }
    return undefined; // Return null if no match was found
}
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
    if (!event.isFirstEvent)
        return;
    const item = event.itemStack;
    if (item && item.typeId == SuppItems.GuideBook) {
        const block = event.block;
        const player = event.player;
        const pageId = findPage(block);
        event.cancel = true;
        system.run(() => {
            openBookIfNotAlreadyOpened(player, pageId);
        });
    }
});
const openingPlayers = new Set();
function openBookIfNotAlreadyOpened(player, pageId) {
    if (openingPlayers.has(player.id)) {
        return;
    }
    if (pageId) {
        bookUI.openPage(pageId, player, true);
    }
    else {
        bookUI.open(player);
    }
    openingPlayers.add(player.id);
    system.run(() => {
        openingPlayers.delete(player.id);
    });
}
world.afterEvents.playerJoin.subscribe((event) => {
    const player = world.getEntity(event.playerId);
    if (player instanceof Player) {
        if (!guideBookMemory.hasBookBeenGranted(player, bookUI)) {
            let itemStack = new ItemStack(SuppItems.GuideBook);
            itemStack.setLore(["§7By John Supplementaries"]);
            giveItemToPlayer(player, itemStack);
            guideBookMemory.setHasBookBeenGranted(player, bookUI, true);
        }
    }
    else {
        console.warn("Player not found");
    }
});
class GuideBookMemory {
    hasViewedPage(page, player, ui) {
        if (page instanceof ConfigPage)
            return true;
        let saveData = this.getSaveData(player, ui.uiID);
        return saveData.viewedPages.includes(page.id);
    }
    markPageViewed(page, player, ui) {
        const data = this.getSaveData(player, ui.uiID);
        const pageId = page.id;
        if (!data.viewedPages.includes(pageId)) {
            data.viewedPages.push(pageId);
            this.setSaveData(player, ui.uiID, data);
        }
    }
    getSaveData(player, id) {
        const raw = player.getDynamicProperty(addonRes(id));
        if (raw) {
            const data = JSON.parse(raw);
            return {
                givenBook: data.givenBook ?? false,
                viewedPages: data.viewedPages ?? []
            };
        }
        return { givenBook: false, viewedPages: [] };
    }
    setSaveData(player, id, data) {
        player.setDynamicProperty(addonRes(id), JSON.stringify(data));
    }
    hasBookBeenGranted(player, ui) {
        return this.getSaveData(player, ui.uiID).givenBook;
    }
    setHasBookBeenGranted(player, ui, granted) {
        const data = this.getSaveData(player, ui.uiID);
        data.givenBook = granted;
        this.setSaveData(player, ui.uiID, data);
    }
}
const guideBookMemory = new GuideBookMemory();
const configOn = p => {
    return configs.configsInBook.getValue() && isOp(p);
};
const isOp = (p) => {
    const ap = p;
    try {
        return ap.isOp();
    }
    catch (e) {
    }
    //check permission level here once its added //TODO
    return true;
};
// @formatter:off
export const bookUI = UIBuilder.create('guide_book')
    .buttonsPage()
    .setPageMemory(guideBookMemory)
    .setOpenSound("item.book.page_turn")
    .noBody()
    .pushConfig("test")
    .value(new EnumEntry("test_enum", Direction, Direction.North))
    .pop()
    .pushSection("redstone")
    .noBody()
    .entry("turn_table")
    .entry("bellows")
    .entry("pulley")
    .entry("faucet")
    .entry("speaker_block")
    .entry("ram_block")
    .entry("flint_block")
    .entry("gold_door")
    .pop()
    .pushSection("functional")
    .noBody()
    .entry("bamboo_spikes")
    .entry("present")
    .entry("jar")
    .entry("pumice")
    .entry("iron_gate")
    .entry("flax")
    .entry("cushion")
    .entry("urn")
    .entry("hat_stand")
    .entry("globe")
    .entry("clock_block")
    .entry("soap_block")
    .pop()
    .pushSection('building')
    .noBody()
    .entry("chalk")
    .entry('awning')
    .entry('gem_bricks')
    .entry('flower_box')
    .entry('ceramic_tiles')
    .entry('candle_holder')
    .entry("rope")
    .entry('ash')
    .entry('sconce')
    .entry('fine_wood')
    .entry('pedestal')
    .entry('thatch')
    .entry('daub')
    .entry('stone_tile')
    .entry('stone_lamp')
    .entry('feather_block')
    .pop()
    .pushSection("tools")
    .noBody()
    .entry("wrench")
    .entry("bomb")
    .entry("slingshot")
    .entry("soap")
    .entry("bubble_blower")
    .pop()
    .pushSection("food")
    .noBody()
    .entry("candy")
    .entry("cheese")
    .entry("pancakes")
    .entry("chocolate")
    .pop()
    .pushSection("tweaks")
    .noBody()
    .toggleableEntry("clock_and_compass", configs.clockAndCompassEnabled, configOn)
    .toggleableEntry("wall_lantern", configs.wallLanternsEnabled, configOn)
    .toggleableEntry("book", configs.placeableBooksEnabled, configOn)
    .toggleableEntry("raked_gravel", configs.rakedGravelEnabled, configOn)
    .pop()
    .entry("socials")
    .build();
// @formatter:on
