import * as mc from "@minecraft/server";
import * as ui from "@minecraft/server-ui";

const VERSION = "1.1";
const SOUND_TURN_PAGE = "item.book.page_turn";
const SOUND_OPTIONS = { pitch: 1.0, volume: 5.0, };

const MENU_MAIN = new ui.ActionFormData();
const MENU_ABOUT = new ui.ActionFormData();
const BLOCKS_LIST = [
    "Redstone Station",

    "Conveyor",
    "Item Teleporter",
    "Item Filter",

    "Custom Repeater",
    "Redstone Counter",
    "Redstone Randomizer",
    "Wireless Redstone",
    "Redstone Display",
    "Redstone Looper",

    "Entity Sensor",
    "Rain Sensor",

    "Spike",
    "Lava Spike",
    "XP Tank",
    "Entity Teleporter",
    "Breeder",
    "Bucket Refiller",

    "Block Dispenser",
    "Redstone Saw",
    "Redstone Drill",

    "Remote Redstone",

    "Elevator",

    "Hopper Dropper",
    "Fan",
    "Item Magnet",

    "Transplanter",

    "Redstone Wrench",

    "Super Smelter",
    "Ore Refiner",
    "Ore Detector",
    "Grinder",

    "Fertilizer",
    "Auto Composter",
    "Harvester",

    "Portable Drill",
    "Portable Dropper",
    "Portable Block Dispenser",
    "Portable Magnet",
    "Rail Placer",
    "Quarry Machine"
]
const BLOCKS_ICONS_LIST = [
    "red_station",

    "red_conveyor",
    "red_conveyor",
    "red_conveyor",

    "red_device",
    "red_device",
    "red_device",
    "red_device",
    "red_device",
    "red_device",

    "red_sensor",
    "red_sensor",

    "red_mobs",
    "red_mobs",
    "red_mobs",
    "red_mobs",
    "red_mobs",
    "red_mobs",

    "red_blocks",
    "red_blocks",
    "red_blocks",

    "red_wireless",

    "red_elevator",

    "red_misc",
    "red_misc",
    "red_misc",
    "red_misc",

    "red_wrench_frame",

    "red_refining",
    "red_refining",
    "red_refining",
    "red_refining",

    "red_farming",
    "red_farming",
    "red_farming",

    "red_mining",
    "red_mining",
    "red_mining",
    "red_mining",
    "red_mining",
    "red_mining",
]

const BLOCK_PRESENTATION_TEXT = [
    "The Redstone Station is a special §bcrafting station§r where all §bnew blocks§r are crafted.",
    "Conveyors can transport §bitems§r and §bentities§r along their track.",
    "These devices can §bteleport§r items between each other.",
    "Item Filters can set §bitems§r onto different conveyor tracks.",
    "A more customizable §brepeater§r.",
    "§bOutputs§r a signal after a §bcustomizable number§r of §binput signals§r.",
    "Sends a §bredstone signal§r to a §brandom§r direction.",
    "Sends §blong-distance redstone signals§r to matching colors.",
    "Displays the §bredstone signal strength§r of its strongest input.",
    "Sends §bredstone signals§r at configurable tick intervals.",
    "Sends a §bredstone signal§r if it detects nearby §bentities§r.",
    "Sends a §bredstone signal§r if it rains.",
    "Hurts mobs and makes them drop §bXP§r.",
    "Hurts mobs and makes them drop §bXP§r and §bcooks§r their meat.",
    "Stores XP Points.",
    "Teleports mobs & players between teleporters.",
    "Automatically makes applicable mobs breed with each other.",
    "Fills empty buckets with available §bwater§r, §blava§r, §bmilk§r, or §baquatic mobs§r.",
    "Places blocks.",
    "Destroys §bTrees§r and drops their item.",
    "Destroys §bany block§r and drops its item (if possible).",
    "Triggers a §bredstone signal§r via a §bremote controller§r.",
    "Sends platforms up or down a shaft of §bElevator Rails§r.",
    "A §bHopper§r with faster output.",
    "Creates a §bwind current§r that blows §bitems§r and §bentities§r.",
    "Creates a §bmagnetic field§r that pulls in items towards it",
    "Places §bseeds§r from atop a §bminecart§r.",
    "§bRotates§r, §bmanipulates§r or shows §binformation§r about certain blocks.",
    "Smelts passing §bitems§r in a conveyor structure.",
    "Transforms §bores§r into other §bores§r.",
    "Detects nearby §bores§r of a specified type.",
    "Grinds §bstones§r & §bother sediments§r into more valuable items.",
    "Automatically fertilizes an area.",
    "Automatically composts organic material.",
    "Farms §bcrops§r from atop a §bminecraft§r.",
    "Minecart-compatible Drill.",
    "Minecart-compatible Dropper.",
    "Minecart-compatible Block Dispenser.",
    "Minecraft-compatible Item Magnet.",
    "Automatically places rails in front while on a railtrack.",
    "Combines the §bPortable Drill§r, §bPortable Block Dispenser§r & §bRail-Placer§r into a single machine."

]
const BLOCK_HOWITWORK_TEXT = [
    "Apart from only being used for §bcertain recipes§r it works like a §bcrafting table§r.",
    "Place the conveyors in a track and they will §brun automatically§r.\n\nBuild §bslopes§r and §bturns§r by placing them at different heights and angles.",
    "When connected to §bconveyors§r, they will teleport items that flow into them from an §binput§r to an §boutput§r teleporter.\n\nActivate them to switch between §binput§r and §boutput§r.",
    "The filter will §breject§r any item that's inside a §bchest§r placed directly above.\n\nPressing the §bbutton§r on its backside will switch it to only §baccept§r items from the §bchest§r instead.",
    "Activate the §bCustom Repeater§r to open its §bsettings§r and set a delay between\n§b1 Tick§r and §b60 Seconds§r.",
    "Activate the §bRedstone Counter§r to open its §bsettings§r and set the number of §binputs§r it needs before it sends a signal.",
    "Will choose §brandomly§r from 1 of the 3 possible directions to send a §bsignal§r everytime it receives an §binput signal§r",
    "A §btransmitter§r will send a wireless signal to a §breceiver§r. Activate to switch between them.",
    "Gets powered like a §bblock§r, so it can detect inputs from any direction.",
    "Activate the §bLooper§r to select between §b5§r different §binterval speeds§r.",
    "Activate to configure which §rentities§r, and in which §bradius§r the sensor should search. It will only send a §bsignal§r if both criteria are met.\n\nYou can also search for §bplayer names§r instead.",
    "Simply place it. The sensor will send a §bsignal§r as long as it rains.",
    "Any mobs that touch the spikes will continuously take §bdamage§r.\n\nMobs that die from this damage will §bdrop XP§r.",
    "Any mobs that touch the spikes will continuously take §bdamage§r.\n\nMobs that die from this damage will §bdrop XP§r & a §bcooked meat§r if they can drop it.",
    "Sneak + interact with the §bXP Tank§r to §bdeposit§r or §bwithdraw§r XP.\n\nInteract with a filled tank to quickly withdraw §b500 XP§r.\n\nWill automatically collect §bXP§r from mobs killed by §bSpikes§r if placed directly underneath.",
    "Any entity that steps on it will be §bteleported§r to another teleporter that have the same color. Teleporters need to be §bmarked with §bdye§r to function.",
    "While an appropriate §bbreeding item§r is stored in a §bchest§r on the §bBreeder's§r backside, §bbreedable mobs§r that step into the input are temporarily stored.\n\nIf another mob of the same species enters, §bbreeding items§r are consumed and a §bbaby§r of that species is sent out the §bfront output§r, while both §bmobs§r are sent out the §bright output§r.",
    "Takes §bempty buckets or glass bottles§r from a §bchest§r above it and tries to fill it with something in front of its §bgrated input§r, then drops the filled items into a §bchest§r below it.\n\nActivating it will switch it to refuse filling §bwater§r, so that aquatic mobs can be taken easily.\n\n§bCows§r in front of the input will be §bmilked§r if they can be.",
    "Takes blocks from a §bchest§r above or behind it and places them in front of it when given a §bredstone signal§r.",
    "When powered by §bredstone§r, the saw will spin and destroy §bLogs§r placed in front of it.\n\nWill also destroy other logs §bdirectly above§r the destroyed log, allowing it to cut entire §btrees§r.\n\nChange between 3 cutting modes: §bNormal§r, §bStrip§r & §bLeaves§r to cut logs regularly or stripped or to also cut the §bleaves§r.\n\nCan be upgraded to also §bdrop leaves§r in §BLeaves Mode§r by feeding it an §bEnchanted Book§r with §bSilk Touch§r.",
    "When powered by §bredstone§r, the drill will spin and destroy §bblocks§r placed in front of it.\n\nIf it breaks an §bore§r, it will also break any connected §bore blocks§r.\n\nCan be upgraded to §bspin faster§r, §bdrop more ore§r or §bdrop raw blocks§r by feeding it §bEnchanted Books§r with §bEfficiency§r, §bFortune§r or §bSilk Touch§r respectively.",
    "Requires a §bRemote Controlled Redstone§b block and §bRemote Controller§r.\n\nActivating the remote will switch the block to send a continuous §bredstone signal§r until turned off again.\n\n§bSneak + Activating§r the remote will open a menu to turn it to a different color channel.",
    "Requires an §bElevator Rail§r, §bElevator Control Rail§r and §bElevator Platform§r.\n\n§bElevators§r can be placed on §bElevator Control Rails§r.\n\nWhen a control rail receives a §bredstone signal§r on its §bright side§r, it will send the §bElevator§r up for as long as there are §bElevator Rails§r above it.\n\nSimilarly, a §bredstone signal§r on its §bleft side§r will send it down.\n\nIf there is another §bElevator Control Rail§r at its destination, it will stop there, otherwise, it will turn around.",
    "Pulls entire stacks of items out of a §bchest/hopper/entity§r above it or dropped into it and drops it below itself or into a §Bchest§r or §bentity§r below it.\n\nCan be turned upside down to transport items up.\n\nCan be locked when powered with redstone.",
    "Blows its §bwind current§r up to 5 blocks in front of it when activated by a §bredstone signal§r.\n\nActivate it to switch between §bpush§r and §bpull§r.",
    "When activated by a §bredstone signal§r, it will start pulling items towards itself.",
    "Can be placed inside a §bminecart§r on rails and will cover the §b3 blocks§r left and right to the rails.\n\nThese blocks must be §btilled§r and §bwatered§r soil and be placed §b1 block§r below the block that the §brails§r are on in order to receive §bseeds§r\n\nActivate the §bTransplanter§r to open its inventory and place the §bseeds§r you want to plant inside.\n\nA §bHopper§r placed above the §bTransplanter§r can also fill it automatically.",
    "Interacting with §bConveyor Blocks§r and most §bRedstone Devices§r while holding the §bRedstone Wrench§r will rotate them.\n\nInteracting with §bRedstone§r will show its current power level.\n\nInteracting with §bDrills§r will show its upgrade level.\n\nInteracting with §bElevator Platforms§r will remove them from the elevator.",
    "Pulls §bcoal§r from a chest placed above it to §bsmelt§r or §bcook§r anything that passes through its conveyor.",
    "Pulls §bsmelted ores§r from a chest placed above it to turn them into a §bhigher quantity§r of a less valuable ore, or a §blower quantity§r of a more valuable ore.\n\nTo select the §bmaterial§r it converts into, activate the §bore refiner§r with the desired item in hand.",
    "Activate the Detector with any §bmined & smelted ore§r in hand, and it will tell you whether ore of this type is in a §b10 block radius§r of itself.",
    "Pulls a variety of underground blocks from a chest placed above it to grind into more valuable materials with a chance to get even more valuable materials out of it.\n\nGrinder need to be powered by §bredstone§r to work.",
    "Pulls §bbone meal§r from a chest placed above it to fertilize §bgrass§r, §bcrops§r or §btrees§r in the highlighted area. Also compatible with 2x2 trees.\nUse §bbone blocks§r to increase the area up to 2 times.",
    "Pulls any §borganic materials§r from a chest placed above it and turns them into §bbone meal§r.",
    "Can be placed inside a §bminecart§r and will cover the §b3 blocks§r left and right to the rails.\n\nWill automatically farm fully grown §bcrops§r from this area and place them into its inventory.\n\nThe soil that the crops grow and must be placed §b1 block§r below the block that the §brails§r are on in order to harvest them.\n\nPlacing a §bHopper§r or §bHopper Dropper§r underneath the Minecart tracks will empty its inventory.",
    "Works like the §bRedstone Drill§r.\n\nCan be upgraded just like it & has its own inventory.\n\nThe §bBig Drill§r variant mines a 3x3 area in front of it.",
    "Can be placed inside a §bminecart§r.\n\nWill drop its inventory toward the output direction if it goes over a §bdetector rail§r.",
    "Can be placed inside a §bminecart§r.\n\nWill place a block from its inventory at its placer frame if it goes over a §bdetector rail§r.",
    "Can be placed inside a §bminecart§r.\n\nWill automatically attract items within a §b10 block radius§r into its inventory.\n\nRadius can be increased by feeding it §benchanted books§r with efficiency.",
    "Rides along a Minecart track autonomously and places §brails§r from its inventory in front of itself.\n\nRequires §bcoal§r in the furnace slot to go and requires §brail§r in the chest slot to place them.",
    "When §bfully equipped§r with all needed items it will automatically ride along a track drill out a §b3x3§r area in front of it and place new §bblocks & rails§r to continue going."
]
const BLOCK_SPECIFICATIONS_TEXT = [
    "To learn its §bcrafting recipe§r, you need to find §bredstone§r",
    "Connects to §bItem Teleporters§r, §bItem Filter§r, §bBreeders§r, and feeds into §bHoppers§r placed below an end.",
    "Can be §bmarked§r with §bdye§r.\nOnly matching colors connect.\n\nCan select a §bkey channel§r with §bWrench§r.\nOnly matching keys connect.",
    "§aBack:   §bButton\n§aLeft:    §bInput\n§aRight:   §bOutput (Accept)\n§aFront:  §bOutput (Reject)",
    "Simple Redstone Device\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Simple Redstone Device\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Simple Redstone Device\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Can be §bmarked§r with §bdye§r\nOnly matching colors connect.\n\nCan select a §bkey channel§r with §bWrench§r.\nOnly matching keys connect.\n\nNeeds a §bRepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Simple Redstone Device\nOnly accepts §bRedstone Wire§r signals.",
    "Simple Redstone Device\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Simple Redstone Device\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Simple Redstone Device\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Does not hurt players.\nAn §bXp Tank§r can be placed directly below to collect killed mob's XP.",
    "Does not hurt players.\nAn §bXp Tank§r can be placed directly below to collect killed mob's XP.",
    "Stores up to §b10.000 XP§r\nRoughly equivalent to §b63 Levels§r.",
    "Can be §bmarked with §bdye§r.\nOnly matching colors connect.\n\nCan select a §bkey channel§r with §bWrench§r.\nOnly matching keys connect.\n\nWorks at §bany range§r and across §bdimensions§r but you can limit/disable it in the customization settings of the guidebook.",
    "Connects to §bConveyors§r\nConsumes §b10 items§r per breed.\n§aBack:   §bChest\n§aLeft:    §bInput\n§aRight:   §bOutput (Baby)\n§aFront:  §bOutput (Mob)",
    "§aFront:   §bInput (Content)§r\n§aTop:      §bInput (Empty Buckets)\n§aBottom:   §bOutput (Filled Buckets)",
    "Continuously places blocks while powered by §bredstone§r.",
    "Block Destroying Device\nUse §bRedstone Wrench§r to change modes",
    "Block Destroying Device",
    "Default color channel is §bblack§r.\nBlock can be §bmarked§r with dye to switch which channel it reacts to.\n\nCan select a §bkey channel§r with §bWrench§r.\nOnly matching keys connect.\n\nNeeds a §brepeater§r to read the output.\n\n§7Note: Make sure to place a second repeater after the output repeater to stabilize the redstone signal and prevent any glitches.",
    "Interact with the §bPlatform§r to sit.\nSneak + Interact to open §bInventory.§r\nHas §b8 Seats§r.\nTo break the platform, break the §bControl Rail§r it rests on or use the §bRedstone Wrench§r on it.",
    "Use §bRedstone Wrench§r to turn it upside down.",
    "Strength of the §bcurrent§r is determined by the strength of the §bredstone signal§r.\nFlows through non-solid blocks.",
    "Radius of the §bmagnetic field§r is determined by the strength of the §bredstone signal§r.",
    "Works with any §bseeds§r or §bplantable food items§r.",
    "Can rotate §bPistons§r & §bObservers§r",
    "Takes §b1 Coal§r per smelting process.",
    "Conversion Points:\n§c§l[§r§b0001§c§l]§r - Coal\n§c§l[§r§b0002§c§l]§r - Lapis Lazuli\n§c§l[§r§b0002§c§l]§r - Redstone\n§c§l[§r§b0006§c§l]§r - Copper Ingot\n§c§l[§r§b0008§c§l]§r - Iron Ingot\n§c§l[§r§b0012§c§l]§r - Gold Ingot\n§c§l[§r§b0012§c§l]§r - Emerald\n§c§l[§r§b0128§c§l]§r - Diamond\n§c§l[§r§b2048§c§l]§r - Netherite Scrap",
    "Accepts: Coal, Iron Ingot, Copper Ingot, Gold Ingot, Redstone, Emerald, Lapis Lazuli, Diamond, Gold Nugget, Quartz, Ancient Debris",
    "Use a §bRedstone Wrench§r on it to see all avaible blocks to grind.",
    "Needs §b16§r bone blocks for the 1st & §b32§r bone blocks for the second area upgrade.\n\nUse a §bRedstone Wrench§r on it to toggle the §barea particles§r.",
    "Drops the §bbone meal§r in front of it.\n\nEach organic item prodcues 1/10th of a §bbonemeal§r.",
    "Harvests §bcrops§r and §bseeds§r if available.",
    "Use a §bRedstone Wrench§r on it to change the drill's facing direction.",
    "Use a §bRedstone Wrench§r on it to change the output's facing direction.",
    "Use a §bRedstone Wrench§r on it to change the placer frame's facing direction.",
    "Minecart Device",
    "Takes §b1 Coal§r per block travelled.\n\nUse a §bRedstone Wrench§r on it change its facing direction.",
    "\nSlots from back to front:\n§c[§rFurnace Slot§c]§r\n§c[§rRail Slot§c]§r\n§c[§rBlock Placer Slot§c]§r\n§c[§rDrill Inventory Slot§c]§r"
]





// UPDATES
const UPDATES_VERSIONS_TITLE = [
    "Version 1.0.1",
    "Version 1.1: Mining & Farming"
]

const UPDATES_VERSIONS_CHANGELOG = [
    "§cVersion 1.0.1 Changelog:§r\n\n- Added §cRedstone Wrench§r with many functionalities. See its own §ctutorial page§r for more infos.§r\n\n- §cElevator Platforms§r can now be removed with the §bRedstone Wrench§r.\n\n- Updated §cRedstone Drill§r to accept §bSilk Touch§r upgrade and fixed several bugs with it.\n\n- §cHopper Dropper§r now supports most containers and floating items and can be placed upside down to §bmove items upward§r.\n\n- Overall increased container compatibility for many blocks.\n\n- §cRedstone Saw§r now has 3 modes and accepts §bSilk Touch§r as an upgrade to farm leaves.\n\n- §cBucket Refiller§r now works with §bGlass Bottles§r.\n\n- And several smaller bug fixes.",
    "§b§lUpdate Version 1.1 Changelog\n§r§6Mining & Farming:§r\n\n§cNew Content§r:\n- Added 4 new §bore-processing§r blocks\n- Added 3 new §bfarming§r devices\n- Added 6 new §bportable§r mining devices\n\nSee their §btutorial§r pages for more info.\n\n§cUpdates & Fixes:§r\n- §bHopper dropper§r can now be locked with redstone, take from & place into §bentities§r & will no longer drop items on top of full chests.\n\n- Added customization setting to guidebook to limit or disable the §bentity teleporter§r.\n\n- §bPermission tags§r are now required to access customization options.\n\n- Blocks that use §bcolor channels§r can now have an additional §bkey channel§r selected with the §cRedstone Wrench§r. Both need to match for blocks to connect. If no §bkey channel§r is selected, the block will only regard the §bcolor channel§r\n\n- Added chest open sounds to entities.\n\n- Item Filters now filter §bitem names§r\n\n- Added a new alternative to the §bElevator Platform§r, the §bElevator Cabin§r.\n\n- Fixed §bbreeder§r spawning non-persistent entities & several other small issues with it.\n\n- Added §Bpale tree§r compatibility to §bsaw§r.\n\n- Fixed §bentitiy teleporter§r bug that teleported to old locations. Can now try to place a new teleporter at the bugged location to remove it.",

]


guideBookListeners();
setupStaticMenus();

//most of the menus don't ever change contents so we set them up once at the very start
function setupStaticMenus() {
    //GUIDEBOOK MAIN
    MENU_MAIN.title("Redstone Add-On");
    MENU_MAIN.body("Welcome to §c§lRedstone Add-On§r!\n\nRead about how the §bnew blocks§r work in the §4'§bTutorial§4'§r section,\n\nor change certain §bsettings§r about them in the §4'§bCustomization§4'§r section.");
    MENU_MAIN.button("Tutorial", "textures/pb/redstone/icons/red_tutorial");
    MENU_MAIN.button("Customization", "textures/pb/redstone/icons/red_customize");
    MENU_MAIN.button("About", "textures/pb/redstone/icons/red_about");
    //GUIDEBOOK ABOUT 
    MENU_ABOUT.title({ translate: "pb_red.menu_about_title" });
    MENU_ABOUT.body({ "rawtext": [{ "text": "Version: §a" + VERSION + "§f\n" }, { translate: "pb_red.menu_about_changelog", "with": ["\n"] }, { translate: "pb_red.menu_about_body", "with": ["\n"] }] });
    MENU_ABOUT.button("Update Log", "textures/pb/redstone/icons/red_update");
    MENU_ABOUT.button("Back", "textures/pb/redstone/icons/red_back");
}

function tutorialMenu(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);
    const MENU_TUTORIAL = new ui.ActionFormData();

    MENU_TUTORIAL.title("Tutorial Menu");
    MENU_TUTORIAL.body("§cSelect a device§r:");
    BLOCKS_LIST.forEach((block) => {
        MENU_TUTORIAL.button(block, `textures/pb/redstone/icons/${BLOCKS_ICONS_LIST[BLOCKS_LIST.indexOf(block)]}`);
    })
    MENU_TUTORIAL.button("Back", `textures/pb/redstone/icons/red_back`);
    MENU_TUTORIAL.show(player).then(result => {
        if (result.canceled) return;

        let response = result.selection;
        if (response < BLOCKS_LIST.length)
            blockTextGuideMenu(player, response)
        else
            menuMain(player)
    });
}

function blockTextGuideMenu(player, index) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);

    const block = BLOCKS_LIST[index]
    const presentation = BLOCK_PRESENTATION_TEXT[index]
    const howItWork = BLOCK_HOWITWORK_TEXT[index]
    const specifications = BLOCK_SPECIFICATIONS_TEXT[index]
    const guideText = presentation + "\n\n§c§lHow does it work?§r\n" + howItWork + "\n\n§c§lBlock Specification§r\n" + specifications
    const MENU_BLOCKS_INFO = new ui.ActionFormData();

    MENU_BLOCKS_INFO.title(block);
    MENU_BLOCKS_INFO.body(guideText)
    MENU_BLOCKS_INFO.button("Next Block", "textures/pb/redstone/icons/red_next")
    MENU_BLOCKS_INFO.button("Back", "textures/pb/redstone/icons/red_back")
    MENU_BLOCKS_INFO.show(player).then(result => {
        if (result.canceled) return;
        let response = result.selection;
        switch (response) {
            case 0: blockTextGuideMenu(player, (index + 1 < BLOCKS_LIST.length ? index + 1 : 0)); break;
            case 1: tutorialMenu(player); break;
        }
    });
}

function menuMain(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);
    MENU_MAIN.show(player).then(result => {
        if (result.canceled) return;

        let response = result.selection;
        switch (response) {
            case 0: tutorialMenu(player); break;
            case 1:
                if (player.hasTag("pb_red:customization_perm")) {
                    filteredEntitiesGUIhandler(player);
                } else {
                    player.sendMessage("§cYou Don't have the permission to acces the Customization section. Ask an operator the permission to acces it.")
                }
                break;
            case 2: aboutMenu(player); break;
            default: break;
        }
    });
}

function aboutMenu(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);
    MENU_ABOUT.show(player).then(result => {
        if (result.canceled) return;

        let response = result.selection;
        switch (response) {
            case 0: updatesMenu(player); break;
            case 1: menuMain(player); break;
            default: break;
        }
    });
}

function updatesMenu(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);
    const MENU_UPDATES = new ui.ActionFormData();

    MENU_UPDATES.title("Updates Menu");
    MENU_UPDATES.body("§cSelect an update version§r:");
    UPDATES_VERSIONS_TITLE.forEach((version) => {
        MENU_UPDATES.button(version, "textures/pb/redstone/icons/red_version");
    })
    MENU_UPDATES.button("Back", `textures/pb/redstone/icons/red_back`);
    MENU_UPDATES.show(player).then(result => {
        if (result.canceled) return;

        let response = result.selection;
        if (response < UPDATES_VERSIONS_TITLE.length)
            updateChangelogMenu(player, response)
        else
            aboutMenu(player)
    });
}

function updateChangelogMenu(player, index) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);

    const changelog = UPDATES_VERSIONS_CHANGELOG[index]
    const MENU_CHANGELOG = new ui.ActionFormData();

    MENU_CHANGELOG.title(UPDATES_VERSIONS_TITLE[index]);
    MENU_CHANGELOG.body(changelog)
    MENU_CHANGELOG.button("Back", "textures/pb/redstone/icons/red_back")
    MENU_CHANGELOG.show(player).then(result => {
        if (result.canceled) return;
        let response = result.selection;
        switch (response) {
            case 0: updatesMenu(player); break;
        }
    });
}


function entityTeleporterSettings(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);

    const info = getEntityTeleporterSettingsInfo()

    const settingUI = new ui.ModalFormData()
        .title("Entity Teleporter Settings")
        .toggle("Enable Entity Teleporter", info.enable)
        .toggle("Cross Dimension Teleportation", info.crossDim)
        .toggle("Limit Teleportation Distance", info.distLimited)
        .slider("\nTeleportation Distance Limit\n(need to have 'Limit Teleportation Distance' ON)", 10, 15000, 10, info.range)
        .show(player).then((r) => {
            if (r.canceled) return;

            const newInfo = { enable: r.formValues[0], crossDim: r.formValues[1], distLimited: r.formValues[2], range: r.formValues[3] }
            mc.world.setDynamicProperty(`pb_red:entity_teleporter_settings`, JSON.stringify(newInfo));

            filteredEntitiesGUIhandler(player)
        })

}

function getEntityTeleporterSettingsInfo() {
    const info = mc.world.getDynamicProperty(`pb_red:entity_teleporter_settings`) || null;
    if (info) {
        return JSON.parse(info)
    } else {
        return { enable: true, crossDim: true, distLimited: false, range: 10000 };
    }
}


function guideBookListeners() {
    //drop guidebook on player first spawn only
    mc.world.afterEvents.playerSpawn.subscribe((eventData) => {
        if (!eventData.player.hasTag('pb_red_book')) {
            mc.world.getDimension(eventData.player.dimension.id).spawnItem(new mc.ItemStack("pb_red:redstone_guidebook", 1), eventData.player.location);
            eventData.player.addTag('pb_red_book');
            eventData.player.addTag('pb_red:customization_perm');

        } else {

            // if (!eventData.player.hasTag('pb_red_update_1.0.1_message')) {
            //     mc.world.getDimension(eventData.player.dimension.id).spawnItem(new mc.ItemStack("pb_red:redstone_guidebook", 1), eventData.player.location);
            //     eventData.player.sendMessage("§cRedstone Add-On§r has been §bupdated§r ! Check out the updated features in the §b'About'§r section of the §bRedstone Guidebook§r")
            //     eventData.player.addTag('pb_red_update_1.0.1_message');
            // }

            if (!eventData.player.hasTag('pb_red_update_1.1.0_message')) {
                mc.system.runTimeout(() => {
                    try {
                        mc.world.getDimension(eventData.player.dimension.id).spawnItem(new mc.ItemStack("pb_red:redstone_guidebook", 1), eventData.player.location);
                        eventData.player.addTag('pb_red_update_1.1.0_message');
                        eventData.player.addTag('pb_red:customization_perm');
                        eventData.player.playSound("random.toast")
                        eventData.player.sendMessage("§cRedstone Add-On§r has been §bupdated§r ! Check out the new 13+ features and complete changelog in the §b'About'§r section of the §bRedstone Guidebook§r")
                    } catch { }
                }, 100)

            }
        }
    })

    //guidebook activation listener
    mc.world.afterEvents.itemUse.subscribe((eventData) => {
        let player = eventData.source;
        let itemUse = eventData.itemStack;
        if (itemUse === undefined) return;
        if (itemUse.typeId == "pb_red:redstone_guidebook") menuMain(player);
    })
}



// CUSTOMIZE MENU

function filteredEntitiesBlockSelection(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);

    const blockList = ["Fan", "Conveyor", "Entity Teleporter", "Spike"]
    const filteredEntitiesBlockSelectGUI = new ui.ModalFormData()
        .title("Ignored Entities Block Selection")
        .dropdown("Select the block for which to manage §BIgnored Entities§r:", blockList, 0);

    filteredEntitiesBlockSelectGUI.show(player).then((selec) => {
        if (selec.canceled) {
            return;
        }
        manageFilteredEntities(player, blockList[selec.formValues[0]])
    });
}


function manageFilteredEntities(player, block) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);

    const allEntities = [
        "player", "creeper", "zombie", "skeleton", "spider", "enderman", "villager", "witch", "iron_golem", "wolf", "ocelot", "cow", "pig", "sheep", "chicken",
        "horse", "cat", "bee", "dolphin", "panda", "fox", "polar_bear", "phantom", "slime", "magma_cube", "ghast", "blaze", "wither_skeleton", "piglin", "hoglin",
        "stray", "husk", "drowned", "phantom", "ravager", "pillager", "vindicator", "evocation_illager", "vex", "shulker", "guardian", "elder_guardian",
        "ender_dragon", "wither", "bat", "cave_spider", "cod", "donkey", "fox", "goat", "glow_squid", "llama", "mooshroom", "mule", "parrot", "pufferfish",
        "rabbit", "salmon", "silverfish", "skeleton_horse", "snow_golem", "squid", "strider", "tropicalfish", "turtle", "wandering_trader", "zombie_horse",
        "zombie_villager", "zoglin",

        "armor_stand", "arrow", "boat", "minecart", "chest_minecart", "hopper_minecart", "furnace_minecart", "command_block_minecart", "end_crystal", "falling_block",
        "fireball", "fireworks_rocket", "fishing_hook", "item", "leash_knot", "lightning_bolt", "snowball", "splash_potion", "tnt", "tnt_minecart", "trident",
        "xp_bottle", "xp_orb", "ender_pearl", "shulker_bullet", "npc"
    ];

    const filteredEntities = loadFilteredEntities(block);
    const isItemsOnlyMode = loadItemsOnlyMode(block); // Charge l'état "Items Only Mode"

    // Si le mode "Items Only" est activé, les options de filtrage sont désactivées
    const availableEntitiesToAdd = isItemsOnlyMode ? ["Can't filter entities in Items Only Mode"] : ["none", ...allEntities.filter(entity => !filteredEntities.includes(entity))];
    const entitiesToRemove = isItemsOnlyMode ? ["Can't filter entities in Items Only Mode"] : ["none", ...filteredEntities];

    const filteredEntitiesManagerGUI = new ui.ModalFormData()
        .title("Ignore List Manager (" + block + ")")
        .dropdown("Entity to add to '§bIgnore List§r':", availableEntitiesToAdd, 0)
        .dropdown("Entity to remove from '§bIgnore List§r':", entitiesToRemove, 0);

    // Affiche le toggle "Items Only Mode" uniquement pour Conveyor et Fan
    if (block === "Conveyor" || block === "Fan") {
        filteredEntitiesManagerGUI.toggle("Items Only Mode", isItemsOnlyMode);
    }

    filteredEntitiesManagerGUI.show(player).then((selec) => {
        if (selec.canceled) {
            return;
        }

        // Mettre à jour le mode "Items Only" si le toggle est présent et sélectionné
        if ((block === "Conveyor" || block === "Fan") && selec.formValues.length > 2) {
            const itemsOnly = selec.formValues[2];
            saveItemsOnlyMode(block, itemsOnly); // Sauvegarde l'état du toggle
            if (itemsOnly) {
                player.sendMessage("Activated §bItems Only Mode")
                filteredEntitiesGUIhandler(player); // Recharge l'affichage
                return
            }
        }

        // Ajouter ou supprimer les entités uniquement si le mode "Items Only" n'est pas activé
        if (selec.formValues[0] !== 0 && !isItemsOnlyMode) {
            toggleFilteredEntity(availableEntitiesToAdd[selec.formValues[0]], "add", player, block);
        }
        if (selec.formValues[1] !== 0 && !isItemsOnlyMode) {

            toggleFilteredEntity(filteredEntities[selec.formValues[1] - 1], "remove", player, block);
        }

        filteredEntitiesGUIhandler(player); // Recharge l'affichage
    });
}


function filteredEntitiesGUIhandler(player) {
    player.playSound(SOUND_TURN_PAGE, SOUND_OPTIONS);

    const fanFilteredEntities = loadFilteredEntities('Fan');
    const conveyorFilteredEntities = loadFilteredEntities('Conveyor');
    const entityTeleporterFilteredEntities = loadFilteredEntities('Entity Teleporter');
    const spikeFilteredEntities = loadFilteredEntities('Spike');

    const fanItemsOnly = loadItemsOnlyMode('Fan');
    const conveyorItemsOnly = loadItemsOnlyMode('Conveyor');

    // Affiche "Only works with items" si le mode "Items Only" est activé, sinon affiche la liste des entités ignorées
    let fanFilteredEntitiesString = fanItemsOnly ? "Only works with items" : formatEntityList(fanFilteredEntities);
    let conveyorFilteredEntitiesString = conveyorItemsOnly ? "Only works with items" : formatEntityList(conveyorFilteredEntities);
    let entityTeleporterFilteredEntitiesString = formatEntityList(entityTeleporterFilteredEntities);
    let spikeFilteredEntitiesString = formatEntityList(spikeFilteredEntities);

    const entityGUI = new ui.ActionFormData()
        .title("Ignored Entities Filter")
        .body(
            "§7If you are an operator of this world/realm and you want to restrain acces of the customization section to other player, remove the following permission tag to the players: 'pb_red:customization_perm' \n§7(/tag [player name] remove [tag])§r\n\n" +
            "Ignored entities per block:\n\n" +
            "§e§lFan :\n\n§r" + fanFilteredEntitiesString +
            "\n\n§e§lConveyor :\n\n§r" + conveyorFilteredEntitiesString +
            "\n\n§e§lEntity Teleporter :\n\n§r" + entityTeleporterFilteredEntitiesString +
            "\n\n§e§lSpike :\n\n§r" + spikeFilteredEntitiesString + "\n ")
        .button("Manage Ignored Entities", "textures/pb/redstone/icons/red_customize")
        .button("Entity Teleporter Settings", "textures/pb/redstone/icons/red_customize")
        .button("Back", "textures/pb/redstone/icons/red_back");

    entityGUI.show(player).then((selec) => {
        if (selec.canceled) {
            return;
        }
        if (selec.selection == 0) {
            filteredEntitiesBlockSelection(player);
        } else if (selec.selection == 1) {
            entityTeleporterSettings(player);
        } else {
            menuMain(player);
        }
    });
}

function formatEntityList(entityList) {
    return entityList.length === 0 ? "§cNo ignored entities" : entityList.join(", ");
}



function toggleFilteredEntity(name, action, player, block) {

    const filteredEntities = loadFilteredEntities(block);

    if (action === "remove") {
        const index = filteredEntities.indexOf(name);
        if (index > -1) {
            player.dimension.runCommand(`tellraw ${player.name} {"rawtext":[{"text":"§4Removed §e${name} §4from the §e${block} §4Ignored entities"}]}`);
            filteredEntities.splice(index, 1);
        }
    } else if (action === "add") {
        if (!filteredEntities.includes(name)) {
            player.dimension.runCommand(`tellraw ${player.name} {"rawtext":[{"text":"§2Added §e${name} §2to the §e${block} §2Ignored entities"}]}`);
            filteredEntities.push(name);
        }
    }

    saveFilteredEntities(block, filteredEntities);
}

function saveFilteredEntities(block, entities) {
    const data = JSON.stringify(entities);
    mc.world.setDynamicProperty(`pb_red:IgnoredEntities:${block}`, data);
}

function loadFilteredEntities(block) {
    const data = mc.world.getDynamicProperty(`pb_red:IgnoredEntities:${block}`);
    if (data) {
        return JSON.parse(data);
    }
    return [];
}

function saveItemsOnlyMode(block, isItemsOnly) {
    mc.world.setDynamicProperty(`pb_red:ItemsOnlyMode:${block}`, JSON.stringify(isItemsOnly));
}

function loadItemsOnlyMode(block) {
    const data = mc.world.getDynamicProperty(`pb_red:ItemsOnlyMode:${block}`);
    return data ? JSON.parse(data) : false;
}