import { ItemStack, world } from "@minecraft/server";
import { getchanceOfMonsterGettingAHat } from './spawnConfigUI.js';

const rarities = ["common", "uncommon", "rare", "epic"];

/** @type {Object.<string, string[]>} */
const hatRarity = {
    common: [
        "just:bandana",
        "just:baseball_hat",
        "just:beanie",
        "just:bicorne",
        "just:big_brain",
        "just:big_eyes",
        "just:bowler",
        "just:brown_brick",
        "just:burger_hat",
        "just:caddy_cap",
        "just:cartoon_egg",
        "just:cheese_slice",
        "just:chefs_hat",
        "just:chicken_head",
        "just:cowboy",
        "just:crown",
        "just:cyclops_eye",
        "just:dairy_queen_lips",
        "just:dangeresque",
        "just:double_take",
        "just:elf_hat",
        "just:explorers_hat",
        "just:eye_patch",
        "just:fro",
        "just:goggles",
        "just:grandma_disguise",
        "just:halo",
        "just:headshot",
        "just:horse_mask",
        "just:large_horns",
        "just:lil_bow",
        "just:mohawk",
        "just:neko_ears",
        "just:party_hat",
        "just:paper_bag",
        "just:pig_head",
        "just:pog",
        "just:police_bucket",
        "just:poofball_hat",
        "just:pope_hat",
        "just:ranahat",
        "just:rubber_nipple",
        "just:sausage",
        "just:sheep_hat",
        "just:sombrero",
        "just:burger_cap",
        "just:sprout",
        "just:summer_hat",
        "just:swimmer",
        "just:top_hat",
        "just:triangle_shades",
        "just:tricorne",
        "just:ushanka",
        "just:villager_nose",
        "just:acorn_hat",
        "just:bucket_cap",
        "just:chalk_stick",
        "just:fez",
        "just:pom_moog",
        "just:scouter",
        "just:sleepy_eye_mask",
        "just:alien_antennae_hat",
        "just:astronaut_helmet",
        "just:binky",
        "just:cardboard_box",
        "just:gnome",
        "just:right_hand_hat",
        "just:round_wig",
        "just:stuck_lollipop",
        "just:tick_on_head",
        "just:toast_hat",
        "just:udder_hat",
        "just:worm_hat",
        "just:cucumber_eyes",
        "just:front_thorns"
    ],
    uncommon: [
        "just:big_crown",
        "just:mango_hat",
        "just:mango_on_head",
        "just:big_ribbon",
        "just:big_steve_head",
        "just:bread_hat",
        "just:camera_beard",
        "just:carrot_on_stick",
        "just:chicken_on_head",
        "just:cuphead",
        "just:dimma",
        "just:doctor_hat",
        "just:dork",
        "just:dragon_hat",
        "just:dragon_skull",
        "just:drinking_hat",
        "just:dum_hat",
        "just:dwarf_miner_beard",
        "just:finn_hat",
        "just:flies",
        "just:frozen_head",
        "just:full_iron_helm",
        "just:ice_dragon_skull",
        "just:jester_hat",
        "just:megaman",
        "just:monkey_king",
        "just:monocle",
        "just:more_eyes",
        "just:penguin_hat",
        "just:questbook",
        "just:red_stache",
        "just:rock_hat",
        "just:shrek_ears",
        "just:shroom_cap",
        "just:springer",
        "just:spy_zombie",
        "just:tinker_hat",
        "just:top_top_hat_hat",
        "just:unicorn_horn",
        "just:angry_mask",
        "just:antlers",
        "just:apple_hat",
        "just:beret_ribbon",
        "just:chi_ears",
        "just:long_fox_ears",
        "just:orange_hat",
        "just:sport_sunglasses",
        "just:strawberry_hat",
        "just:toy_story_alien",
        "just:worms_mine",
        "just:beetle_on_head",
        "just:cat_hat",
        "just:dipper",
        "just:druid_antlers",
        "just:eevee_ears",
        "just:dark_eye_of_the_holder",
        "just:evil_eye_of_the_holder",
        "just:gnome_clover_wig",
        "just:greaser",
        "just:ladybug_on_head",
        "just:mimic_head",
        "just:pika_ears",
        "just:tanuki_leaf"
    ],
    rare: [
        "just:camera",
        "just:wizard_hat",
        "just:cake_hat",
        "just:candle_on_head",
        "just:demon_eyes",
        "just:demon_horns",
        "just:digger",
        "just:dragon_skull_ender",
        "just:fake_fire",
        "just:fish_on_head",
        "just:floating_hearts",
        "just:floating_star",
        "just:flower_crown",
        "just:flower_on_head",
        "just:fox_on_head",
        "just:holy_head",
        "just:host_hat",
        "just:mad_scientist",
        "just:magikarp",
        "just:paypay",
        "just:baby_penguin",
        "just:police_siren",
        "just:propel_hat",
        "just:rabbit_on_head",
        "just:red_eyes",
        "just:sims_gem",
        "just:smoking_pipe",
        "just:snowman_baby",
        "just:sonic_hood",
        "just:spade_soldier",
        "just:stress",
        "just:sunglasses",
        "just:big_sunglasses",
        "just:super_sand_hat",
        "just:top_cat_hat",
        "just:viking_hat_beard",
        "just:wing_hat",
        "just:aegis_hat",
        "just:alien_phil_hat",
        "just:azumanga_hat",
        "just:dejiko",
        "just:lightning_eyes",
        "just:milady_doll",
        "just:peppino",
        "just:puchiko",
        "just:rabi_en_rose",
        "just:the_noise",
        "just:baby_crewmate",
        "just:bee_on_head",
        "just:cat_on_head",
        "just:caterpillar_on_head",
        "just:chocolate_sauced",
        "just:warm_eye_of_the_holder",
        "just:hat_of_discipline",
        "just:lil_bows",
        "just:medusa",
        "just:mimic_head_dark",
        "just:mindflayer",
        "just:slime_head",
        "just:toilet_hat",
        "just:traffic_cone",
        "just:clockface",
        "just:duck_hat"
    ],
    epic: [
        "just:baby_turtle",
        "just:bandana_rgb",
        "just:baseball_hat_rgb",
        "just:beanie_rgb",
        "just:bee_hat",
        "just:disco_ball",
        "just:fake_blight",
        "just:green_birb",
        "just:headphones_blue",
        "just:shiny_magikarp",
        "just:pohatoe",
        "just:poofball_hat_rgb",
        "just:potions_head",
        "just:rainbow_orbiters",
        "just:big_ribbon_rgb",
        "just:bowler_rgb",
        "just:dragon_skull_rgb",
        "just:drinking_hat_rgb",
        "just:easter_head_rgb",
        "just:full_helm_rgb",
        "just:party_hat_rgb",
        "just:small_bowler_rgb",
        "just:sunglasses_rgb",
        "just:top_top_hat_hat_rgb",
        "just:ushanka_rgb",
        "just:tv_head",
        "just:amalgalich_hat",
        "just:artsy_mask",
        "just:baby_dolphin",
        "just:burning_bison",
        "just:fishing_hat",
        "just:nyan_doll",
        "just:rain_cloud",
        "just:angel_and_devil_hat",
        "just:axolotl_on_head",
        "just:crystal_horns",
        "just:druid_antlers_rare",
        "just:eye_of_the_bee_holder",
        "just:xanath_eye_of_the_holder",
        "just:lil_termagant",
        "just:mimic_head_gold",
        "just:mindflayer_alhoon",
        "just:octodad",
        "just:slime_cube_dnd",
        "just:stinky_cheese_man",
        "just:the_noisier",
        "just:thumb_nail",
        "just:tomato_splats",
        "just:peepo",
        "just:cowboy_rgb",
        "just:kirby_mouthful",
        "just:crab_on_head",
        "just:player_jockey",
        "just:brick_head",
        "just:just_ducke"
    ]
};

const entityTypes = [
    "minecraft:zombie",
    "minecraft:zombie_piglin",
    "minecraft:zombie_villager",
    "minecraft:husk",
    "minecraft:drowned",
    "minecraft:bogged",
    "minecraft:skeleton",
    "minecraft:wither_skeleton",
    "minecraft:stray",
    "minecraft:piglin_brute",
    "minecraft:piglin",
    "minecraft:enderman",
    "minecraft:villager",
    "minecraft:wandering_trader"
];

/** @type {Object.<string, number>} */
const rarityWeight = {
    common: 100,
    uncommon: 50,
    rare: 10,
    epic: 1
};

const chanceOfMonsterGettingAHat = getchanceOfMonsterGettingAHat()

/**
 * @template T
 * @param {T[]} array
 * @returns {T}
 */
function chooseRandomElement(array) {
    const index = Math.floor(Math.random() * array.length);
    return array[index];
}

world.afterEvents.entitySpawn.subscribe(({ entity }) => {
    if (!entityTypes.includes(entity.typeId))
        return;
    const chanceOfMonsterGettingAHat = getchanceOfMonsterGettingAHat()
    const random = Math.random();
    if (random < chanceOfMonsterGettingAHat) {

        let totalWeight = 0;
        for (const rarity of rarities) {
            const weight = rarityWeight[rarity];
            totalWeight += weight;
        }

        const random = Math.random() * totalWeight;

        let weightAddedSoFar = 0;
        for (const rarity of rarities) {
            const weight = rarityWeight[rarity];

            if (weightAddedSoFar <= random && random < weightAddedSoFar + weight) {
                const itemId = chooseRandomElement(hatRarity[rarity]);
                entity.runCommand(`replaceitem entity @s slot.armor.head 0 ${itemId}`);
                entity.setDynamicProperty("just_cosmetics_hat", itemId);
                return;
            }

            weightAddedSoFar += weight;
        }

    }
});

world.afterEvents.entityDie.subscribe(({ deadEntity }) => {
    if (!deadEntity.isValid() || !world.gameRules.doEntityDrops)
        return;

    /** @type {string} */
    const justCosmeticsHatTypeId = deadEntity.getDynamicProperty("just_cosmetics_hat");
    if (!justCosmeticsHatTypeId)
        return;

    /*
      remove the hat the monster sometimes drop
      if i didn't do this we'd sometimes have a monster dropping the same hat twice.
      Additionally the hat the monster drops by vanilla is usually very damaged,
      and that'd kinda suck for rare cosmetics
    */
    const nearbyItemEntities = deadEntity.dimension.getEntities({
        maxDistance: 1,
        location: deadEntity.location,
        type: "minecraft:item"
    });
    for (const itemEntity of nearbyItemEntities) {
        const item = itemEntity.getComponent("item").itemStack;
        if (
            item.typeId == justCosmeticsHatTypeId 
            //just to make sure we'll never delete anyone's enchanted cosmetic
            && !item.getComponent("enchantable")?.getEnchantments().length
        ) {
            itemEntity.remove();
            break;
        }
    }

    //spawn the hat item
    deadEntity.dimension.spawnItem(new ItemStack(justCosmeticsHatTypeId), deadEntity.location);
});