import { ItemStack, Player, system, world } from "@minecraft/server";
import { stripColorFromId } from "./util/colorUtils";
import { giveItemToPlayer, isOp, splitRes, translate } from "./util/miscUtils";
import { SuppItems } from "./reg/suppItems";
import { configs } from "./configs";
import { ConfigPage, Page, UIBuilder } from "./util/uiBuilder";
import { addonRes } from "./main";
export const GuideBookComponent = {
    onUse(event) {
        const player = event.source;
        openBookIfNotAlreadyOpened(player);
    }
};
const aliases = new Map([
    ["gold_trapdoor", "gold_door"],
    ["milk_cauldron", "cheese"],
    ["lapis_bricks", "gem_bricks"],
    ["glowstone_bricks", "gem_bricks"],
    ["deepslate_lamp", "stone_lamp"],
    ["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;
    }
    const firstOpen = !guideBookMemory.hasViewedPage("start", player, introPage);
    const uiToOpen = firstOpen ? introPage : bookUI;
    if (pageId) {
        uiToOpen.openPage(pageId, player);
    }
    else {
        uiToOpen.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);
            player.sendMessage(translate("message", "welcome"));
        }
    }
    else {
        console.warn("Player not found");
    }
});
class GuideBookMemory {
    hasViewedPage(page, player, ui) {
        if (page instanceof ConfigPage)
            return true;
        const pageId = page instanceof Page ? page?.id : page;
        let saveData = this.getSaveData(player, ui.uiID);
        return saveData.viewedPages.includes(pageId);
    }
    markPageViewed(page, player, ui) {
        const data = this.getSaveData(player, ui.uiID);
        const pageId = page instanceof Page ? page?.id : page;
        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);
};
// @formatter:off
export const bookUI = UIBuilder.create('guide_book')
    .buttonsPage()
    .setPageMemory(guideBookMemory)
    .setOpenSound("item.book.page_turn")
    .noBody()
    .pushSection("redstone")
    .noBody()
    .section("turn_table")
    .section("bellows")
    .section("pulley")
    .sectionWithConfig("faucet", configs.faucetIrrigate, configOn)
    .sectionWithConfigs("speaker_block", [configs.speakerMaxRange, configs.speakerPrefix, configs.speakerCensor], configOn)
    .section("ram_block")
    .section("flint_block")
    .section("gold_door")
    .pop()
    .pushSection("functional")
    .noBody()
    .section("bamboo_spikes")
    .section("present")
    .section("jar")
    .section("pumice")
    .section("iron_gate")
    .sectionWithConfig('flax', configs.flaxDropChance, configOn)
    .sectionWithConfig("cushion", configs.cushionLockRotation, configOn)
    .section("urn")
    .section("hat_stand")
    .section("globe")
    .sectionWithConfig("rope", configs.ropeInteraction, configOn)
    .section("clock_block")
    .sectionWithConfig("soap_block", configs.soapSlip, configOn)
    .pop()
    .pushSection('building')
    .noBody()
    .section("chalk")
    .section('awning')
    .section('gem_bricks')
    .section('flower_box')
    .section('ceramic_roofs')
    .section('candle_holder')
    .sectionWithConfig('ash', configs.ashFromMobsChance, configOn)
    .section('sconce')
    .section('fine_wood')
    .section('brazier')
    .section('sugar_cube')
    .section('pedestal')
    .section('thatch')
    .section('daub')
    .section('stone_tile')
    .section('stone_lamp')
    .section('feather_block')
    .pop()
    .pushSection("tools")
    .noBody()
    .sectionWithConfig("wrench", configs.wrenchUp, configOn)
    .section("bomb")
    .sectionWithConfig("slingshot", configs.slingshotScalar, configOn)
    .sectionWithConfigs("confetti_popper", [configs.confettiAmount, configs.placeableConfetti], configOn)
    .section("soap")
    .section("bubble_blower")
    .pop()
    .pushSection("food")
    .noBody()
    .sectionWithConfig("candy", configs.nausea, configOn)
    .section("cheese")
    .section("pancakes")
    .section("chocolate")
    .pop()
    .pushSection("tweaks")
    .noBody()
    .sectionWithConfig("clock_and_compass", configs.clockAndCompassEnabled, configOn)
    .sectionWithConfig("wall_lantern", configs.wallLanternsEnabled, configOn)
    .sectionWithConfig("book", configs.placeableBooksEnabled, configOn)
    .sectionWithConfig("placeable_stick", configs.placeableStick, configOn)
    .sectionWithConfig("raked_gravel", configs.rakedGravelEnabled, configOn)
    .pop()
    .pushSection("about")
    .section("socials")
    .pushSection("changelogs")
    .noBody()
    .section("changelog_1")
    .pop()
    .section("credits")
    .pop()
    .build();
// @formatter:on
export const introPage = UIBuilder.create('guide_book_intro')
    .buttonsPage()
    .setOpenSound("item.book.page_turn")
    .actionButton("start", context => {
    guideBookMemory.markPageViewed("start", context.player, introPage);
    return bookUI;
})
    .build();
