import { world, system, EquipmentSlot, ItemStack, EntityInventoryComponent } from "@minecraft/server";

const stackableItems = ["nv_city:television_spawn_egg", "nv_city:pc_spawn_egg", "nv_city:modern_plant_spawn_egg", "nv_city:microwave_spawn_egg"];
const stackableOn = ["nv_city:table", "nv_city:bookshelf", "nv_city:tv_desk", "nv_city:glass_table", "nv_city:desk"];

let lodMain = world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" })[0]; //on world initialise

world.afterEvents.itemUse.subscribe(result => {
    stackableItems.forEach(item => {
        if (result.itemStack.typeId === item) {
            const player = result.source;
            const item = result.itemStack;
            const entity = player.getEntitiesFromViewDirection({ maxDistance: 5, families: ["nvcity_furniture"] })[0]?.entity;

            if (entity) {
                stackableOn.forEach(furniture => {
                    if (entity.typeId === furniture) {
                        let spawnOffset;

                        switch (entity.typeId.substring(entity.typeId.indexOf(":") + 1)) {
                            case "table": spawnOffset = 1.16; break;
                            case "bookshelf": spawnOffset = 1.5; break;
                            case "tv_desk": spawnOffset = 0.8; break;
                            case "desk": spawnOffset = 1.05; break;
                            case "glass_table": spawnOffset = 0.56; break;
                            default: spawnOffset = 1;
                        }

                        const distanceOffset = spawnOffset;

                        const distance = Math.round(distanceFormula(entity.location, player.location));

                        const testSpawnVector = {
                            x: player.location.x + player.getViewDirection().x * distance,
                            y: entity.location.y + spawnOffset,
                            z: player.location.z + player.getViewDirection().z * distance
                        }

                        const leftPosition = {
                            x: entity.location.x - entity.getViewDirection().z * distanceOffset,
                            y: entity.location.y + spawnOffset,
                            z: entity.location.z + entity.getViewDirection().x * distanceOffset
                        }

                        const rightPosition = {
                            x: entity.location.x + entity.getViewDirection().z * distanceOffset,
                            y: entity.location.y + spawnOffset,
                            z: entity.location.z - entity.getViewDirection().x * distanceOffset
                        }

                        const spawnLocation = {
                            x: entity.location.x,
                            y: entity.location.y + spawnOffset,
                            z: entity.location.z
                        }

                        let finalSpawnLocation;

                        if (distanceFormula(spawnLocation, testSpawnVector) <= distanceOffset / 2) finalSpawnLocation = spawnLocation;
                        else if (distanceFormula(leftPosition, testSpawnVector) < distanceFormula(rightPosition, testSpawnVector)) finalSpawnLocation = leftPosition;
                        else finalSpawnLocation = rightPosition;

                        if (player.dimension.getEntities({ families: ["nvcity_furniture"], excludeTypes: [entity.typeId], location: finalSpawnLocation, maxDistance: 0.02 }).length === 0) {
                            if (player.matches({ excludeGameModes: ["creative"] })) player.runCommand(`clear @s ${item.typeId} 0 1`);
                            entity.runCommand(`summon ${item.typeId.substring(0, item.typeId.indexOf("_spawn_egg"))} ${finalSpawnLocation.x} ${finalSpawnLocation.y} ${finalSpawnLocation.z} ${entity.getRotation().y} ${entity.getRotation().x}`);
                        }
                    }
                })
            }
        }
    })
})

const lodMin = 50;
const lodMinLater = lodMin - 5;

world.afterEvents.dataDrivenEntityTrigger.subscribe(result => {
    if (result.eventId === "neverland:on") {
        result.entity.runCommand("playanimation @s animation.nv_city.excavator.action_1");

        system.runTimeout(() => result.entity.runCommand("particle minecraft:ice_evaporation_emitter ^-1 ^ ^7"), 1.7 * 20);
        system.runTimeout(() => result.entity.runCommand("particle minecraft:ice_evaporation_emitter ^ ^ ^7"), 1.7 * 20);
        system.runTimeout(() => result.entity.runCommand("particle minecraft:ice_evaporation_emitter ^1 ^ ^7"), 1.7 * 20);

        // system.runTimeout(() => result.entity.runCommand("fill ~4 ~ ~-1 ~5 ~-1 ~1 air"), 2 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^-1 ^ ^7 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^-1 ^1 ^7 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^-1 ^ ^8 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^-1 ^1 ^8 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^ ^ ^7 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^ ^1 ^7 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^ ^ ^8 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^ ^1 ^8 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^1 ^ ^7 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^1 ^1 ^7 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^1 ^ ^8 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);
        system.runTimeout(() => result.entity.runCommand("execute as @s positioned ^1 ^1 ^8 unless block ~~~ bedrock run fill ~~~ ~~~ air destroy"), 2.5 * 20);

        system.runTimeout(() => result.entity.triggerEvent("neverland:off"), 3 * 20);
    }

    if (result.eventId === "nv_city:sleep") {
        const player = result.entity.dimension.getPlayers({ location: result.entity.location, closest: 1 })[0];

        player.runCommand(`ride @s start_riding @e[c=1, type=${result.entity.typeId}] teleport_rider if_group_fits`);

        system.runTimeout(() => {
            if (player.dimension.getBlock({ x: player.location.x, y: player.location.y - 0.1, z: player.location.z }).isAir && world.getTimeOfDay() >= 12542) {
                player.runCommand(`camera @s fade time 5 0 0.1`);

                let time = 0;
                const interval = system.runInterval(() => {
                    if (!player.dimension.getBlock({ x: player.location.x, y: player.location.y - 0.1, z: player.location.z }).isAir) {
                        player.camera.clear();
                        system.clearRun(interval);
                    }

                    if (time >= 100) {
                        world.setTimeOfDay(0);
                        player.runCommand(`ride @s stop_riding`);
                        system.clearRun(interval);
                    }

                    player.onScreenDisplay.setActionBar("Sleeping through this night");
                    time++;
                })
            }
        }, 40);
    }

    if (result.eventId.substring(0, 13) === "nv_city:color") {
        system.runTimeout(() => {
            if (result.entity?.isValid) {
                result.getModifiers().forEach(modifier => {
                    modifier.addedComponentGroups.forEach(added => {
                        try {
                            result.entity?.getTags().forEach(tag => {
                                if (tag.startsWith("nv_city:color")) result.entity?.removeTag(tag);
                            })
                            result.entity?.addTag(added);
                        }
                        catch (error) {
                            //world.sendMessage(`${error}`);
                        }
                    })
                })
            }
        }, 1)
    }

    if (result.eventId === "nv_city:lamppost") {
        // Sound
        result.entity.dimension.playSound("random.click", result.entity.location, { pitch: Math.random() * 0.3 + 0.8 });

        // Place light block
        const placeBlockLocationArr = [
            { x: result.entity.location.x, y: result.entity.location.y + 5, z: result.entity.location.z }
        ];
        const isTurnedOn = result.entity.getDynamicProperty("nv_city:toggled") !== undefined;
        const currentLightBlocksArr = JSON.parse(result.entity.getDynamicProperty("nv_city:light_blocks") ?? "[]");

        if (!isTurnedOn) {
            for (const location of placeBlockLocationArr) {
                const block = result.entity.dimension.getBlock(location);
                if (!block.isAir) continue;
                result.entity.dimension.setBlockType(location, "minecraft:light_block_15");
                currentLightBlocksArr.push(location);

                result.entity.setDynamicProperty("nv_city:toggled", true);
            }
        }
        else {
            result.entity.setDynamicProperty("nv_city:toggled");

            for (const location of currentLightBlocksArr) {
                const block = result.entity.dimension.getBlock(location);
                if (!block) continue;
                result.entity.dimension.setBlockType(location, "minecraft:air");
            }

            currentLightBlocksArr.splice(0, currentLightBlocksArr.length);
        }
        result.entity.setDynamicProperty("nv_city:light_blocks", JSON.stringify(currentLightBlocksArr));
    }

    if (result.eventId === "nv_city:remove" && result.entity?.typeId === "nv_city:lampost") {
        // Place light block
        const placeBlockLocationArr = [
            { x: result.entity.location.x, y: result.entity.location.y + 5, z: result.entity.location.z }
        ];
        for (const location of placeBlockLocationArr) {
            const block = result.entity.dimension.getBlock(location);
            if (!block) continue;
            if (!block.typeId.startsWith("minecraft:light_block_")) continue;

            result.entity.dimension.setBlockType(location, "minecraft:air");
        }

        result.entity.remove();
    }
})

world.afterEvents.worldInitialize.subscribe(result => {
    if (!world.scoreboard.getObjective("nv_city plane_tilt")) world.scoreboard.addObjective("nv_city plane_tilt");
    if (!world.scoreboard.getObjective("nv_city plane_yvelocity")) world.scoreboard.addObjective("nv_city plane_yvelocity");
    if (!world.scoreboard.getObjective("nv_city thisoneTAG")) world.scoreboard.addObjective("nv_city thisoneTAG");

    system.runTimeout(() => {
        system.runInterval(() => {
            world.getPlayers({ excludeTags: ["nv_city startedGame"] }).forEach(player => {
                player.addTag("nv_city startedGame");
                player.getComponent(`minecraft:inventory`).container.addItem(new ItemStack(`nv_city:furniture_inventory_spawn_egg`, 1));
                world.structureManager.place(`nv_city:book`, player.dimension, player.location, { includeBlocks: false, includeEntities: true });
            })

            lodMain = world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" })[0];
            if (world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" }).length === 0) {
                try { lodMain = world.getDimension(`overworld`).spawnEntity("nv_city:lod", { x: world.getPlayers()[0].location.x, y: 200, z: world.getPlayers()[0].location.z }); }
                catch (error) { }
            }

            if (world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" }).length > 1) {
                let tagArr = [];

                for (let x = 0; x < world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" }).length; x++) {
                    const entity = world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" })[x];

                    entity.getTags().forEach(tag => {
                        if (!tagArr.includes(tag)) tagArr.push(tag);
                    });
                }

                world.getDimension(`overworld`).getEntities({ type: "nv_city:lod" }).forEach(entity => entity.remove());

                lodMain = world.getDimension(`overworld`).spawnEntity("nv_city:lod", { x: world.getPlayers()[0].location.x, y: 200, z: world.getPlayers()[0].location.z });

                tagArr.forEach(tag => {
                    lodMain.addTag(tag);
                })
            }

            world.getPlayers().forEach(player => {
                player.dimension.getEntities({ location: player.location, minDistance: lodMinLater - 1, families: ["nvcity_furniture"] }).forEach(entity => {
                    if (entity.typeId === "nv_city:lampost") return; // Lamposts should not be despawned
                    let despawnEarly = false;
                    stackableItems.forEach(name => {
                        if (entity.typeId === name.substring(0, name.indexOf('_spawn_egg'))) despawnEarly = true;
                    })

                    if ((despawnEarly && entity.dimension.getPlayers({ location: entity.location, maxDistance: lodMinLater }).length === 0) || (!despawnEarly && entity.dimension.getPlayers({ location: entity.location, maxDistance: lodMin }).length === 0)) {
                        const colour = entity.getTags().find(element => /^nv_city:color(?!1)/.test(element)) ? entity.getTags().find(element => /^nv_city:color(?!1)/.test(element)) : "nv_city:color1";

                        const tagName = `nv_city furniture ${entity.typeId}§x${entity.location.x.toFixed(2)}§y${entity.location.y.toFixed(2)}§z${entity.location.z.toFixed(2)}§r${entity.getRotation().y}§c${colour}§d${entity.dimension.id}`;
                        lodMain.addTag(tagName);
                        entity.remove();
                    }
                })

                const entity = player.getEntitiesFromViewDirection({ maxDistance: 5, families: ["nvcity_furniture"] })[0]?.entity;

                if (entity) {
                    stackableOn.forEach(furniture => {
                        if (entity.typeId === furniture) {
                            stackableItems.forEach(item => {
                                if (player.getComponent(`minecraft:equippable`).getEquipment(EquipmentSlot.Mainhand)?.typeId === item) {
                                    let spawnOffset;

                                    switch (entity.typeId.substring(entity.typeId.indexOf(":") + 1)) {
                                        case "table": spawnOffset = 1.15; break;
                                        case "bookshelf": spawnOffset = 1.5; break;
                                        case "tv_desk": spawnOffset = 0.80; break;
                                        case "desk": spawnOffset = 1.05; break;
                                        case "glass_table": spawnOffset = 0.56; break;
                                        default: spawnOffset = 1;
                                    }

                                    const distanceOffset = spawnOffset;

                                    const distance = Math.round(distanceFormula(entity.location, player.location)) / 1;

                                    const testSpawnVector = {
                                        x: player.location.x + player.getViewDirection().x * distance,
                                        y: entity.location.y + spawnOffset,
                                        z: player.location.z + player.getViewDirection().z * distance
                                    }

                                    const leftPosition = {
                                        x: entity.location.x - entity.getViewDirection().z * distanceOffset,
                                        y: entity.location.y + spawnOffset,
                                        z: entity.location.z + entity.getViewDirection().x * distanceOffset
                                    }

                                    const rightPosition = {
                                        x: entity.location.x + entity.getViewDirection().z * distanceOffset,
                                        y: entity.location.y + spawnOffset,
                                        z: entity.location.z - entity.getViewDirection().x * distanceOffset
                                    }

                                    const spawnLocation = {
                                        x: entity.location.x,
                                        y: entity.location.y + spawnOffset,
                                        z: entity.location.z
                                    }

                                    let finalSpawnLocation;

                                    if (distanceFormula(spawnLocation, testSpawnVector) <= distanceOffset / 2) finalSpawnLocation = spawnLocation;
                                    else if (distanceFormula(leftPosition, testSpawnVector) < distanceFormula(rightPosition, testSpawnVector)) finalSpawnLocation = leftPosition;
                                    else finalSpawnLocation = rightPosition;

                                    if (player.dimension.getEntities({ families: ["nvcity_furniture"], excludeTypes: [entity.typeId], location: finalSpawnLocation, maxDistance: 0.02 }).length === 0) player.dimension.spawnParticle(`nv_city:placement`, finalSpawnLocation);
                                }
                            })
                        }
                    })
                }
            })

            lodMain?.getTags().filter(element => element.startsWith(`nv_city furniture `)).forEach(tag => {
                const typeId = tag.substring(tag.indexOf('e ') + 2, tag.indexOf('§x'));
                const spawnLocation = {
                    x: Number(tag.substring(tag.indexOf('§x') + 2, tag.indexOf('§y'))),
                    y: Number(tag.substring(tag.indexOf('§y') + 2, tag.indexOf('§z'))),
                    z: Number(tag.substring(tag.indexOf('§z') + 2, tag.indexOf('§r')))
                };
                const rotation = Number(tag.substring(tag.indexOf('§r') + 2, tag.indexOf('§c')));
                const colour = tag.substring(tag.indexOf('§c') + 2, tag.indexOf('§d'));
                const dimension = tag.substring(tag.indexOf('§d') + 2);

                let spawnLater = false;

                stackableItems.forEach(name => {
                    if (typeId === name.substring(0, name.indexOf('_spawn_egg'))) spawnLater = true;
                })

                if (world.getDimension(dimension).getPlayers({ location: spawnLocation, maxDistance: lodMin }).length > 0) {
                    if (spawnLater && world.getDimension(dimension).getPlayers({ location: spawnLocation, maxDistance: lodMinLater }).length > 0) {
                        lodMain.removeTag(tag);

                        lodMain.runCommand(`execute in ${dimension.substring(10)} run summon ${typeId} ${spawnLocation.x} ${spawnLocation.y} ${spawnLocation.z} ${rotation} 0 ${colour}`);
                    }
                    else if (!spawnLater) {
                        lodMain.removeTag(tag);

                        lodMain.runCommand(`execute in ${dimension.substring(10)} run summon ${typeId} ${spawnLocation.x} ${spawnLocation.y} ${spawnLocation.z} ${rotation} 0 ${colour}`);
                    }
                }
            })
        }, 2)
    }, 20)
})

function distanceFormula(one, two) {
    return Math.sqrt(Math.pow(one.x - two.x, 2) + Math.pow(one.y - two.y, 2) + Math.pow(one.z - two.z, 2));
}

//////////////////////////////////////
////////////////////////////////////// PLAYER JSON FUNCTIONALITY FIXES
//////////////////////////////////////

world.afterEvents.itemUse.subscribe(result => {
    if (result.itemStack.typeId === "nv_city:parachute_black") {
        result.source.addTag(`norvale_parachute`)

        system.runTimeout(() => {
            if (result.source.getComponent(`minecraft:equippable`).getEquipment(EquipmentSlot.Head)) {
                result.source.getComponent(`minecraft:equippable`).setEquipment(EquipmentSlot.Mainhand, result.source.getComponent(`minecraft:equippable`).getEquipment(EquipmentSlot.Head));
            }
            else result.source.getComponent(`minecraft:equippable`).setEquipment(EquipmentSlot.Mainhand);
            result.source.runCommand(`replaceitem entity @s slot.armor.head 1 nv_city:parachute_black`);
            result.source.addEffect('levitation', 20, { amplifier: 3, showParticles: false });
            result.source.addEffect('slow_falling', 999999, { amplifier: 3, showParticles: false });
        }, 1)
    }
    if (result.itemStack.typeId === "nv_city:furniture_inventory_spawn_egg") {
        if (!world.scoreboard.getObjective("nv_city plane_tilt")) world.scoreboard.addObjective("nv_city plane_tilt");
        if (!world.scoreboard.getObjective("nv_city plane_yvelocity")) world.scoreboard.addObjective("nv_city plane_yvelocity");
        if (!world.scoreboard.getObjective("nv_city thisoneTAG")) world.scoreboard.addObjective("nv_city thisoneTAG");
    }
    if (result.itemStack.typeId === "nv_city:guidebook") {
        result.source.getComponent(`minecraft:equippable`).setEquipment(EquipmentSlot.Mainhand);
        system.runTimeout(() => { world.structureManager.place(`mystructure:nv_city_book`, result.source.dimension, result.source.location, { includeBlocks: false, includeEntities: true }) }, 1);
    }
})

system.runInterval(() => {
    world.getPlayers({ tags: ["norvale_parachute"] }).forEach(player => {
        if (player.isOnGround) {
            player.removeTag(`norvale_parachute`);
            player.removeEffect(`slow_falling`);
            player.runCommand("replaceitem entity @p slot.armor.head 1 air");
        }
    })
});

system.afterEvents.scriptEventReceive.subscribe((result) => {
    if (result.id === "nv_city:give_parachute") {
        const player = result.sourceEntity.dimension.getPlayers({ location: result.sourceEntity.location, closest: 1 })[0];
        /** @type {EntityInventoryComponent} */
        const inventory = player.getComponent(`minecraft:inventory`);

        let count = 0;
        let hasParachute = false;
        for (let i = 0; i < inventory.container.size; i++) {
            if (inventory.container.getItem(i) !== undefined) count++;
            if (inventory.container.getItem(i)?.typeId === "nv_city:parachute_black") hasParachute = true;
        }
        if (count < inventory.container.size || hasParachute) {
            player.sendMessage("You have been given a parachute, interact to deploy!")
            if (!hasParachute) inventory.container.addItem(new ItemStack("nv_city:parachute_black", 1));
        }
        else {
            player.sendMessage("§cUnable to give parachute because your inventory is full!");
        }

    }
});

//////////////////////////////////////
////////////////////////////////////// BOOK START
//////////////////////////////////////


const catalogueFurniture = ["nv_city:sofa_chair_spawn_egg", "nv_city:sofa2_spawn_egg", "nv_city:sofa_double_spawn_egg", "nv_city:sofa_spawn_egg", "nv_city:bench_spawn_egg", "nv_city:chair_game_spawn_egg", "nv_city:chair_spawn_egg", "nv_city:chair2_spawn_egg", "nv_city:chair3_spawn_egg", "nv_city:bar_chair_spawn_egg", "nv_city:beach_chair_spawn_egg", "nv_city:bed_new_spawn_egg", "nv_city:bed_double_spawn_egg", "nv_city:bed_spawn_egg", "nv_city:closet_spawn_egg", "nv_city:cabinate_spawn_egg", "nv_city:tv_desk_spawn_egg", "nv_city:glass_table_spawn_egg", "nv_city:table_spawn_egg", "nv_city:pingpong_spawn_egg", "nv_city:pooltable_spawn_egg", "nv_city:desk_spawn_egg", "nv_city:piano_spawn_egg", "nv_city:television_spawn_egg", "nv_city:jacuzzi_spawn_egg", "nv_city:fan_spawn_egg", "nv_city:modern_plant_spawn_egg", "nv_city:fridge_spawn_egg", "nv_city:freezer_spawn_egg", "nv_city:oven_spawn_egg", "nv_city:microwave_spawn_egg", "nv_city:pc_spawn_egg", "nv_city:telescope_spawn_egg", "nv_city:shower_spawn_egg", "nv_city:sink_spawn_egg", "nv_city:toilet_spawn_egg", "nv_city:chandelier_spawn_egg", "nv_city:ceiling_light_spawn_egg", "nv_city:bookshelf_spawn_egg", "nv_city:boat_control_spawn_egg", "nv_city:boat_control_rudder_spawn_egg", "nv_city:grill_spawn_egg", "nv_city:umbrella_spawn_egg", "nv_city:recycle_bin_spawn_egg", "nv_city:cone_spawn_egg", "nv_city:lampost_spawn_egg", "nv_city:washing_machine_spawn_egg", "nv_city:tank_spawn_egg"];
const catalogueVehicles = ["nv_city:bc_car_spawn_egg", "nv_city:pgt3_car_spawn_egg", "nv_city:ps_car_spawn_egg", "nv_city:mlp_car_spawn_egg", "nv_city:lf_car_spawn_egg", "nv_city:f488_car_spawn_egg", "nv_city:car_ff40_spawn_egg", "nv_city:las_car_spawn_egg", "nv_city:f1_car_spawn_egg", "nv_city:motosport_spawn_egg", "nv_city:motorbike_spawn_egg", "nv_city:quadbike_spawn_egg", "nv_city:hoverboard_spawn_egg", "nv_city:golf_cart_spawn_egg", "nv_city:police_car_spawn_egg", "nv_city:firetruck_spawn_egg", "nv_city:ambulance_spawn_egg", "nv_city:garbage_truck_spawn_egg", "nv_city:bus_spawn_egg", "nv_city:electric_tow_truck_spawn_egg", "nv_city:aircraft_tow_tractor_spawn_egg", "nv_city:excavator_car_spawn_egg", "nv_city:excavator_spawn_egg", "nv_city:truck_spawn_egg", "nv_city:forklift_spawn_egg", "nv_city:jeep_spawn_egg", "nv_city:aerobatics_plane_spawn_egg", "nv_city:f_jet_spawn_egg", "nv_city:helicopter15_spawn_egg", "nv_city:m_helicopter2_spawn_egg", "nv_city:m_helicopter3_spawn_egg", "nv_city:m_helicopter_spawn_egg", "nv_city:fire_helicopter_spawn_egg", "nv_city:police_helicopter_spawn_egg", "nv_city:passenger_plane_spawn_egg", "nv_city:plane_spawn_egg", "nv_city:submarine_spawn_egg", "nv_city:nice_black_boat_spawn_egg", "nv_city:luxury_boat_spawn_egg", "nv_city:sea_rescue_speedboat_spawn_egg", "nv_city:speedboat_spawn_egg", "nv_city:jetski_spawn_egg", "nv_city:sailboat_spawn_egg"];

world.afterEvents.entitySpawn.subscribe(result => {
    if (result.entity.typeId === "nv_city:furniture_inventory") {
        const furnitureInven = result.entity;
        furnitureInven.nameTag = "City Pack Catalog";
        furnitureInven.addTag(`nv_city mainMenu`);

        const container = furnitureInven.getComponent(`minecraft:inventory`).container;

        inventoryMainMenu(container);
    }
})

world.afterEvents.entityHitEntity.subscribe(result => {
    if (result.hitEntity.typeId === "nv_city:furniture_inventory") {
        result.damagingEntity.getComponent(`minecraft:inventory`).container.addItem(new ItemStack(`nv_city:furniture_inventory_spawn_egg`, 1));
        result.damagingEntity.runCommand(`playsound random.pop @s ~~~ 1 ${Math.random() * 0.5 + 1.5}`);
        result.hitEntity.remove();
    }

    const removeToolFamillies = ["nvcity_furniture", "vehicles", "cars", "car", "boat"];

    for (const family of removeToolFamillies) {
        if (result.hitEntity?.isValid() && result.hitEntity.matches({ families: [family] })) {
            const lastHitTime = result.damagingEntity.getDynamicProperty("lastHitTime") ?? system.currentTick;
            const validInterval = 10;

            if (lastHitTime + validInterval > system.currentTick && result.damagingEntity.getComponent("equippable").getEquipment(EquipmentSlot.Mainhand)?.typeId !== "nv_city:rotate_tool") {
                result.damagingEntity.sendMessage(`§cYou need to use the removal tool to remove this.`);
            }

            result.damagingEntity.setDynamicProperty("lastHitTime", system.currentTick);
        }
    }
});

system.runInterval(() => {
    world.getDimension(`overworld`).getEntities({ type: `nv_city:furniture_inventory` }).forEach(mainMenu => {
        const inven = mainMenu.getComponent(`minecraft:inventory`).container;

        ///////MAIN MENU
        if (mainMenu.hasTag("nv_city mainMenu")) {
            if (!inven.getItem(15)) {
                world.playSound(`block.click`, mainMenu.location);
                mainMenu.removeTag(`nv_city mainMenu`);
                mainMenu.addTag(`nv_city toolsMenu`);

                inventoryToolsMenu(inven);
                inventoryResetItems(mainMenu)
            }

            else if (!inven.getItem(13)) {
                world.playSound(`block.click`, mainMenu.location);
                mainMenu.removeTag(`nv_city mainMenu`);
                mainMenu.addTag(`nv_city vehiclesMenu`);

                inventoryVehiclesMenu(inven);
                inventoryResetItems(mainMenu)
            }

            else if (!inven.getItem(11)) {
                world.playSound(`block.click`, mainMenu.location);
                mainMenu.removeTag(`nv_city mainMenu`);
                mainMenu.addTag(`nv_city furnitureMenu`);

                inventoryFurnitureMenu(inven);
                inventoryResetItems(mainMenu)
            }
        }

        ///////// TOOLS MENU
        else if (mainMenu.hasTag("nv_city toolsMenu")) {
            if (!inven.getItem(15)) {
                inventoryToolsMenu(inven);
                inventoryResetItems(mainMenu)

                const player = mainMenu.dimension.getPlayers({ location: mainMenu.location, closest: 1 })[0];
                if (player?.getGameMode() === "creative") {
                    player?.playSound(`random.pop`, { volume: 0.5, pitch: 0.8 + Math.random() * 0.4 });
                    player?.getComponent(`minecraft:inventory`).container.addItem(new ItemStack(inven.getItem(15).typeId, 1));
                }
                else {
                    player?.playSound(`note.bassattack`, { volume: 0.2 });
                    player?.sendMessage(`§cYou can only grab catalog items in creative mode! See recipes in the crafting table recipe book.`);
                }
            }

            else if (!inven.getItem(13)) {
                inventoryToolsMenu(inven);
                inventoryResetItems(mainMenu)

                const player = mainMenu.dimension.getPlayers({ location: mainMenu.location, closest: 1 })[0];
                if (player?.getGameMode() === "creative") {
                    player?.playSound(`random.pop`, { volume: 0.5, pitch: 0.8 + Math.random() * 0.4 });
                    player?.getComponent(`minecraft:inventory`).container.addItem(new ItemStack(inven.getItem(13).typeId, 1));
                }
                else {
                    player?.playSound(`note.bassattack`, { volume: 0.2 });
                    player?.sendMessage(`§cYou can only grab catalog items in creative mode! See recipes in the crafting table recipe book.`);
                }
            }

            else if (!inven.getItem(11)) {
                inventoryToolsMenu(inven);
                inventoryResetItems(mainMenu)

                const player = mainMenu.dimension.getPlayers({ location: mainMenu.location, closest: 1 })[0];
                if (player?.getGameMode() === "creative") {
                    player?.playSound(`random.pop`, { volume: 0.5, pitch: 0.8 + Math.random() * 0.4 });
                    player?.getComponent(`minecraft:inventory`).container.addItem(new ItemStack(inven.getItem(11).typeId, 1));
                }
                else {
                    player?.playSound(`note.bassattack`, { volume: 0.2 });
                    player?.sendMessage(`§cYou can only grab catalog items in creative mode! See recipes in the crafting table recipe book.`);
                }
            }

            else if (!inven.getItem(18)) {
                world.playSound(`block.click`, mainMenu.location);
                mainMenu.removeTag(`nv_city toolsMenu`);
                mainMenu.addTag(`nv_city mainMenu`);

                inventoryMainMenu(inven);
                inventoryResetItems(mainMenu)
            }
        }

        ////////// VEHICLES MENU
        else if (mainMenu.hasTag("nv_city vehiclesMenu")) {
            if (!inven.getItem(18)) {
                world.playSound(`block.click`, mainMenu.location);
                mainMenu.removeTag(`nv_city vehiclesMenu`);
                mainMenu.addTag(`nv_city mainMenu`);

                inventoryMainMenu(inven);
                inventoryResetItems(mainMenu)
            }

            else if (!inven.getItem(26)) {
                world.playSound(`block.click`, mainMenu.location);

                inventoryVehiclesMenuNext(inven);
                inventoryResetItems(mainMenu)
            }

            else if (!inven.getItem(25)) {
                world.playSound(`block.click`, mainMenu.location);

                inventoryVehiclesMenuPrevious(inven);
                inventoryResetItems(mainMenu)
            }
        }

        ////////////FURNITURE MENU
        else if (mainMenu.hasTag("nv_city furnitureMenu")) {
            if (!inven.getItem(18)) {
                world.playSound(`block.click`, mainMenu.location);
                mainMenu.removeTag(`nv_city furnitureMenu`);
                mainMenu.addTag(`nv_city mainMenu`);

                inventoryMainMenu(inven);
                inventoryResetItems(mainMenu)
            }

            else if (!inven.getItem(26)) {
                world.playSound(`block.click`, mainMenu.location);

                inventoryFurnitureMenuNext(inven);
                inventoryResetItems(mainMenu)
            }

            else if (!inven.getItem(25)) {
                world.playSound(`block.click`, mainMenu.location);

                inventoryFurnitureMenuPrevious(inven);
                inventoryResetItems(mainMenu)
            }
        }

        if (mainMenu.hasTag("nv_city furnitureMenu") || mainMenu.hasTag("nv_city vehiclesMenu")) inventoryPreventStealing(mainMenu.getComponent(`minecraft:inventory`).container, mainMenu);

        const container = mainMenu.getComponent("minecraft:inventory").container;
        for (let x = 0; x < container.size; x++) {
            if (container.getItem(x) && !container.getItem(x).getLore()[0]?.match("Catalogue")) {
                mainMenu.dimension.getPlayers({ location: mainMenu.location, closest: 1 })[0].getComponent("minecraft:inventory").container.addItem(container.getItem(x));
                container.setItem(x);
            }
        }
    })
})

function inventoryPreventStealing(container, entity) {
    let arr = entity.hasTag("nv_city furnitureMenu") ? catalogueFurniture : catalogueVehicles;
    let itemSlot = (container.getItem(0) != undefined && container.getItem(0).getLore()[0]?.match("Catalogue")) ? container.getItem(0).typeId : container.getItem(1) != undefined ? arr[arr.findIndex(element => element.match(container.getItem(1).typeId)) - 1] : arr[arr.length - 1];

    if (arr.find(element => element.match(itemSlot)) != undefined) {
        let itemIndex;
        arr.forEach((value, index) => {
            if (value === itemSlot) itemIndex = index;
        })

        const itemNumbers = (arr.length - itemIndex < container.size * 2 / 3) ? arr.length - itemIndex : container.size * 2 / 3;

        for (let x = 0; x < itemNumbers; x++) {
            if (!container.getItem(x) || !container.getItem(x)?.getLore()[0]?.match("Catalogue")) {
                const player = entity.dimension.getPlayers({ location: entity.location, closest: 1 })[0];
                if (container.getItem(x) && !container.getItem(x).getLore()[0]?.match("Catalogue")) player?.getComponent(`minecraft:inventory`).container.addItem(container.getItem(x));

                inventoryResetItems(entity);

                for (let x = 0; x < container.size; x++) {
                    container.setItem(x);
                }

                for (let x = 0; x < itemNumbers; x++) {
                    const item = new ItemStack(arr[x + itemIndex], 1);
                    item.setLore(["Catalogue"]);
                    container.setItem(x, item);
                }

                // Give creative players item
                if (player?.getGameMode() === "creative") {
                    player?.playSound(`random.pop`, { volume: 0.5, pitch: 0.8 + Math.random() * 0.4 });
                    player?.getComponent(`minecraft:inventory`).container.addItem(new ItemStack(container.getItem(x).typeId, 1));
                }
                else {
                    player.playSound(`note.bassattack`, { volume: 0.2 });
                    player.sendMessage(`§cYou can only grab catalog items in creative mode! See recipes in the crafting table recipe book.`);
                }

                const back = new ItemStack(`nv_city:back_button`, 1);
                const next = new ItemStack(`nv_city:next_arrow`, 1);
                const previous = new ItemStack(`nv_city:previous_arrow`, 1);

                back.nameTag = "§cBack";
                next.nameTag = "§aNext"
                previous.nameTag = "§cPrevious"

                back.setLore(["Catalogue"]);
                next.setLore(["Catalogue"]);
                previous.setLore(["Catalogue"]);

                container.setItem(18, back);
                container.setItem(26, next);
                container.setItem(25, previous);
            }
        }
    }
}

function inventoryMainMenu(container) {
    for (let x = 0; x < container.size; x++) {
        container.setItem(x);
    }

    const tool = new ItemStack(`nv_city:rotate_tool`, 1)
    const vehicle = new ItemStack(`nv_city:f488_car_spawn_egg`, 1);
    const furniture = new ItemStack(`nv_city:sofa2_spawn_egg`, 1);

    tool.nameTag = "§6Tools§r";
    vehicle.nameTag = "§6Vehicles§r";
    furniture.nameTag = "§6Furniture§r";

    tool.setLore(["Catalogue"]);
    vehicle.setLore(["Catalogue"]);
    furniture.setLore(["Catalogue"]);

    container.setItem(15, tool);
    container.setItem(13, vehicle);
    container.setItem(11, furniture);
}

function inventoryToolsMenu(container) {
    for (let x = 0; x < container.size; x++) {
        container.setItem(x);
    }

    const rotate = new ItemStack(`nv_city:rotate_tool`, 1)
    const color = new ItemStack(`nv_city:color_tool`, 1);
    const removal = new ItemStack(`nv_city:removal_tool`, 1);
    const back = new ItemStack(`nv_city:back_button`, 1);

    rotate.nameTag = "Rotate Tool";
    color.nameTag = "Color Tool";
    removal.nameTag = "Removal Tool";
    back.nameTag = "§cBack";

    rotate.setLore(["Catalogue"]);
    color.setLore(["Catalogue"]);
    removal.setLore(["Catalogue"]);
    back.setLore(["Catalogue"]);

    container.setItem(15, rotate);
    container.setItem(13, color);
    container.setItem(11, removal);
    container.setItem(18, back);
}

function inventoryVehiclesMenu(container) {
    for (let x = 0; x < container.size; x++) {
        container.setItem(x);
    }

    for (let x = 0; x < container.size * 2 / 3; x++) {
        const item = new ItemStack(catalogueVehicles[x], 1);
        item.setLore(["Catalogue"]);
        container.setItem(x, item);
    }

    const back = new ItemStack(`nv_city:back_button`, 1);
    const next = new ItemStack(`nv_city:next_arrow`, 1);
    const previous = new ItemStack(`nv_city:previous_arrow`, 1);

    back.nameTag = "§cBack";
    next.nameTag = "§aNext"
    previous.nameTag = "§cPrevious"

    back.setLore(["Catalogue"]);
    next.setLore(["Catalogue"]);
    previous.setLore(["Catalogue"]);

    container.setItem(18, back);
    container.setItem(26, next);
    container.setItem(25, previous);
}

function inventoryFurnitureMenu(container) {
    for (let x = 0; x < container.size; x++) {
        container.setItem(x);
    }

    for (let x = 0; x < container.size * 2 / 3; x++) {
        const item = new ItemStack(catalogueFurniture[x], 1);
        item.setLore(["Catalogue"]);
        container.setItem(x, item);
    }

    const back = new ItemStack(`nv_city:back_button`, 1);
    const next = new ItemStack(`nv_city:next_arrow`, 1);
    const previous = new ItemStack(`nv_city:previous_arrow`, 1);

    back.nameTag = "§cBack";
    next.nameTag = "§aNext"
    previous.nameTag = "§cPrevious"

    back.setLore(["Catalogue"]);
    next.setLore(["Catalogue"]);
    previous.setLore(["Catalogue"]);

    container.setItem(18, back);
    container.setItem(26, next);
    container.setItem(25, previous);
}

function inventoryFurnitureMenuNext(container) {
    if (container.getItem(17)) {
        const find = catalogueFurniture.findIndex(element => element.match(container.getItem(17).typeId));

        for (let x = 0; x < container.size; x++) {
            container.setItem(x);
        }

        const nextIndex = (find != -1) ? find + 1 : 0;

        for (let x = 0; x < container.size * 2 / 3; x++) {
            if (catalogueFurniture[x + nextIndex]) {
                const item = new ItemStack(catalogueFurniture[x + nextIndex], 1);
                item.setLore(["Catalogue"]);
                container.setItem(x, item);
            } else container.setItem(x);
        }
    }

    const back = new ItemStack(`nv_city:back_button`, 1);
    const next = new ItemStack(`nv_city:next_arrow`, 1);
    const previous = new ItemStack(`nv_city:previous_arrow`, 1);

    back.nameTag = "§cBack";
    next.nameTag = "§aNext"
    previous.nameTag = "§cPrevious"

    back.setLore(["Catalogue"]);
    next.setLore(["Catalogue"]);
    previous.setLore(["Catalogue"]);

    container.setItem(18, back);
    container.setItem(26, next);
    container.setItem(25, previous);
}

function inventoryFurnitureMenuPrevious(container) {
    if (container.getItem(0)?.typeId !== catalogueFurniture[0]) {
        const find = catalogueFurniture.findIndex(element => element.match(container.getItem(0).typeId));

        for (let x = 0; x < container.size; x++) {
            container.setItem(x);
        }

        const nextIndex = (find != -1 || find != 0) ? find : 0;

        for (let x = 0; x < container.size * 2 / 3; x++) {
            if (catalogueFurniture[nextIndex + x - container.size * 2 / 3]) {
                const item = new ItemStack(catalogueFurniture[nextIndex + x - container.size * 2 / 3], 1);
                item.setLore(["Catalogue"]);
                container.setItem(x, item);
            }
            else container.setItem(x);
        }
    }

    const back = new ItemStack(`nv_city:back_button`, 1);
    const next = new ItemStack(`nv_city:next_arrow`, 1);
    const previous = new ItemStack(`nv_city:previous_arrow`, 1);

    back.nameTag = "§cBack";
    next.nameTag = "§aNext"
    previous.nameTag = "§cPrevious"

    back.setLore(["Catalogue"]);
    next.setLore(["Catalogue"]);
    previous.setLore(["Catalogue"]);

    container.setItem(18, back);
    container.setItem(26, next);
    container.setItem(25, previous);
}

function inventoryVehiclesMenuNext(container) {
    if (container.getItem(17)) {
        const find = catalogueVehicles.findIndex(element => element.match(container.getItem(17).typeId));

        for (let x = 0; x < container.size; x++) {
            container.setItem(x);
        }

        const nextIndex = (find != -1) ? find + 1 : 0;

        for (let x = 0; x < container.size * 2 / 3; x++) {
            if (catalogueVehicles[x + nextIndex]) {
                const item = new ItemStack(catalogueVehicles[x + nextIndex], 1);
                item.setLore(["Catalogue"]);
                container.setItem(x, item);
            }
            else container.setItem(x);
        }
    }

    const back = new ItemStack(`nv_city:back_button`, 1);
    const next = new ItemStack(`nv_city:next_arrow`, 1);
    const previous = new ItemStack(`nv_city:previous_arrow`, 1);

    back.nameTag = "§cBack";
    next.nameTag = "§aNext"
    previous.nameTag = "§cPrevious"

    back.setLore(["Catalogue"]);
    next.setLore(["Catalogue"]);
    previous.setLore(["Catalogue"]);

    container.setItem(18, back);
    container.setItem(26, next);
    container.setItem(25, previous);
}

function inventoryVehiclesMenuPrevious(container) {
    if (container.getItem(0)?.typeId !== catalogueVehicles[0]) {
        const find = catalogueVehicles.findIndex(element => element.match(container.getItem(0).typeId));

        for (let x = 0; x < container.size; x++) {
            container.setItem(x);
        }

        const nextIndex = (find != -1 || find != 0) ? find : 0;

        for (let x = 0; x < container.size * 2 / 3; x++) {
            if (catalogueVehicles[nextIndex + x - container.size * 2 / 3]) {
                const item = new ItemStack(catalogueVehicles[nextIndex + x - container.size * 2 / 3], 1);
                item.setLore(["Catalogue"]);
                container.setItem(x, item);
            }
            else container.setItem(x);
        }
    }

    const back = new ItemStack(`nv_city:back_button`, 1);
    const next = new ItemStack(`nv_city:next_arrow`, 1);
    const previous = new ItemStack(`nv_city:previous_arrow`, 1);

    back.nameTag = "§cBack";
    next.nameTag = "§aNext"
    previous.nameTag = "§cPrevious"

    back.setLore(["Catalogue"]);
    next.setLore(["Catalogue"]);
    previous.setLore(["Catalogue"]);

    container.setItem(18, back);
    container.setItem(26, next);
    container.setItem(25, previous);
}

function inventoryResetItems2(typeId) {
    world.getPlayers().forEach(player => {
        const array = [];

        for (let x = 0; x < player.getComponent(`minecraft:inventory`).container.size; x++) {
            const item = player.getComponent(`minecraft:inventory`).container.getItem(x);
            if (item?.typeId === typeId) {
                array.push(item);
                array.push(x);
            }
        }

        player.runCommand(`clear @s ${typeId}`);

        for (let x = 0; x < array.length; x += 2) {
            player.getComponent(`minecraft:inventory`).container.setItem(array[x + 1], array[x]);
        }
    })
}

function inventoryResetItems(entity) {
    world.getPlayers().forEach(player => {
        if (player.matches({ location: entity.location, maxDistance: 6 })) {
            let arr = [];
            const container = player.getComponent(`minecraft:inventory`).container;

            for (let x = 0; x < container.size; x++) {
                const item = container.getItem(x);
                if (item?.getLore()[0] === "Catalogue") {
                    container.setItem(x);
                }

                else if (item) arr.push(x, item);
            }

            player.runCommand(`clear @s`);

            for (let x = 0; x < arr.length; x += 2) {
                container.setItem(arr[x], arr[x + 1]);
            }
        }
    })
}

