package info.faceland.loot.items;

import info.faceland.hilt.HiltItemStack;
import info.faceland.loot.LootPlugin;
import info.faceland.loot.api.groups.ItemGroup;
import info.faceland.loot.api.items.ItemBuilder;
import info.faceland.loot.api.items.ItemGenerationReason;
import info.faceland.loot.api.tier.Tier;
import info.faceland.loot.math.LootRandom;
import info.faceland.utils.TextUtils;
import org.bukkit.Material;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public final class LootItemBuilder implements ItemBuilder {

    private final LootPlugin plugin;
    private boolean built = false;
    private Tier tier;
    private Material material;
    private ItemGenerationReason itemGenerationReason;
    private LootRandom random;

    public LootItemBuilder(LootPlugin plugin) {
        this.plugin = plugin;
        this.random = new LootRandom(System.currentTimeMillis());
    }

    private String randomFromSet(Set<ItemGroup> itemGroups) {
        ItemGroup[] array = itemGroups.toArray(new ItemGroup[itemGroups.size()]);
        return array[random.nextInt(array.length)].getName().toUpperCase();
    }

    @Override
    public boolean isBuilt() {
        return built;
    }

    @Override
    public HiltItemStack build() {
        if (isBuilt()) {
            throw new IllegalStateException("already built");
        }
        built = true;
        HiltItemStack hiltItemStack;
        if (material == null) {
            if (tier == null) {
                tier = plugin.getTierManager().getRandomTier(false);
            }
            Set<Material> set = tier.getAllowedMaterials();
            Material[] array = set.toArray(new Material[set.size()]);
            if (array.length == 0) {
                throw new RuntimeException("array length is 0 for tier: " + tier.getName());
            }
            material = array[random.nextInt(array.length)];
        }
        if (tier == null) {
            List<Tier> tiers = getMatchingTiers(material);
            tier = tiers.get(random.nextInt(tiers.size()));
        }
        hiltItemStack = new HiltItemStack(material);
        hiltItemStack.setName(tier.getDisplayColor() + plugin.getNameManager().getRandomPrefix() + " " + plugin
                .getNameManager().getRandomSuffix() + tier.getIdentificationColor());
        List<String> lore = new ArrayList<>(tier.getBaseLore());
        lore.addAll(plugin.getSettings().getStringList("corestats." + material.name(),
                                                       new ArrayList<String>()));
        for (int i = 0; i < random.nextIntRange(tier.getMinimumBonusLore(), tier.getMaximumBonusLore()); i++) {
            lore.add(tier.getBonusLore().get(random.nextInt(tier.getBonusLore().size())));
        }
        if (tier.isEnchantable()) {
            lore.add("<blue>(Enchantable)");
        }
        for (int i = 0; i < random.nextIntRange(tier.getMinimumSockets(), tier.getMaximumSockets()); i++) {
            lore.add("<yellow>(Socket)");
        }
        if (random.nextDouble() < tier.getExtendableChance()) {
            lore.add("<gold>(+)");
        }
        hiltItemStack.setLore(TextUtils.color(lore));
        return hiltItemStack;
    }

    @Override
    public ItemBuilder withTier(Tier t) {
        tier = t;
        return this;
    }

    @Override
    public ItemBuilder withMaterial(Material m) {
        material = m;
        return this;
    }

    @Override
    public ItemBuilder withItemGenerationReason(ItemGenerationReason reason) {
        itemGenerationReason = reason;
        return this;
    }

    private List<Tier> getMatchingTiers(Material m) {
        List<Tier> tiers = new ArrayList<>();
        for (Tier t : plugin.getTierManager().getLoadedTiers()) {
            if (t.getAllowedMaterials().contains(m)) {
                tiers.add(t);
            }
        }
        return tiers;
    }

}

@@ -723,26 +723,57 @@
 rationReason
+ = ItemGenerationReason.MONSTER
 ;%0A
-
     private 
@@ -1533,58 +1533,19 @@
     
-tier = plugin.getTierManager().getRandomTier(false
+chooseTier(
 );%0A 
@@ -2004,55 +2004,951 @@
     
-tier = tiers.get(random.nextInt(tiers.size()));
+double totalWeight = 0D;%0A            for (Tier t : tiers) %7B%0A                if (itemGenerationReason == ItemGenerationReason.IDENTIFYING) %7B%0A                    totalWeight += t.getIdentifyWeight();%0A                %7D else %7B%0A                    totalWeight += t.getSpawnWeight();%0A                %7D%0A            %7D%0A            double chosenWeight = random.nextDouble() * totalWeight;%0A            double currentWeight = 0D;%0A            for (Tier t : tiers) %7B%0A                if (itemGenerationReason == ItemGenerationReason.IDENTIFYING) %7B%0A                    currentWeight += t.getIdentifyWeight();%0A                %7D else %7B%0A                    currentWeight += t.getSpawnWeight();%0A                %7D%0A                if (currentWeight %3E= chosenWeight) %7B%0A                    tier = t;%0A                    break;%0A                %7D%0A            %7D%0A            if (tier == null) %7B%0A                throw new RuntimeException(%22cannot identify%22);%0A            %7D
 %0A   
@@ -4746,32 +4746,32 @@
     %7D%0A        %7D%0A
-
         return t
@@ -4783,10 +4783,740 @@
 %0A    %7D%0A%0A
+    private Tier chooseTier() %7B%0A        if (itemGenerationReason == ItemGenerationReason.IDENTIFYING) %7B%0A            double totalWeight = 0D;%0A            for (Tier t : plugin.getTierManager().getLoadedTiers()) %7B%0A                totalWeight += t.getIdentifyWeight();%0A            %7D%0A            double chosenWeight = random.nextDouble() * totalWeight;%0A            double currentWeight = 0D;%0A            for (Tier t : plugin.getTierManager().getLoadedTiers()) %7B%0A                currentWeight += t.getIdentifyWeight();%0A                if (currentWeight %3E= chosenWeight) %7B%0A                    return t;%0A                %7D%0A            %7D%0A            return null;%0A        %7D%0A        return plugin.getTierManager().getRandomTier(true);%0A    %7D%0A%0A
 %7D%0A

use identifying weight for identifying