package de.hessj.environmentex;

import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import net.kyori.adventure.text.Component;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.RecipeChoice.MaterialChoice;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
import org.bukkit.persistence.PersistentDataType;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class App extends JavaPlugin {
    public static de.hessj.helper.Helper helper = new de.hessj.helper.Helper();
    public static App main;
    public ItemStack backPack;
    public ItemStack backPack2;
    public ItemStack backPack3;
    public ItemStack backPack4;
    public ItemStack zombieLeather;
    public ItemStack bulb = new ItemStack(Material.LIGHT);
    public NamespacedKey nsk;
    public NamespacedKey nsk2;
    public NamespacedKey nsk3;
    public NamespacedKey nsk4;
    public NamespacedKey nskEmptyExpBottle;
    public NamespacedKey nskGlow;
    public ItemMeta meta;
    public ItemMeta meta2;
    public ItemStack eBottle;
    public final List<NamespacedKey> recipeKeys = new ArrayList<>();

    public static boolean coordinateRunner = false;
    public PluginManager pM = Bukkit.getPluginManager();
    public HashMap<Player, Boolean> hmActionbar = new HashMap<Player, Boolean>();
    public File tpYml = new File(this.getDataFolder() + "/texturepack.yml");
    public FileConfiguration tpConfig = YamlConfiguration.loadConfiguration(tpYml);

    @Override
    public void onEnable() {
        tpConfig.addDefault("url", "https://mc.hessj.de/texturepack/CUSTOM.zip");
        tpConfig.addDefault("sha1", "a7f7bde9e54279b502d65435877d251aa522cabc");

        // Copy defaults and save if the file doesn't have these values
        tpConfig.options().copyDefaults(true);
        try {
            tpConfig.save(tpYml);
        } catch (IOException e) {
            e.printStackTrace();
        }

        getServer().recipeIterator().forEachRemaining(recipe -> {
            if (recipe instanceof ShapelessRecipe) {
                ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe;
                recipeKeys.add(shapelessRecipe.getKey());
            } else if (recipe instanceof ShapedRecipe) {
                ShapedRecipe shapedRecipe = (ShapedRecipe) recipe;
                recipeKeys.add(shapedRecipe.getKey());
            }
        });

        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
            public void run() {
                MobBurner.tryBurning();
            }

        }, 1000 * 20 / 1000, 1000 * 20 / 1000);

        getLogger().info("Plugin enabled!");
        main = this;

        
       // if(App.main.getServer().getPort() == 25588){
        CustomMusicDiscs cmd = new CustomMusicDiscs();
        cmd.createDiscs(App.main);
    //}

        backPack = new ItemStack(Material.BARRIER, 1);
        ItemMeta im = backPack.getItemMeta();
        im.displayName(Component.translatable(ChatColor.WHITE + "Kleiner Rucksack"));
        im.setCustomModelData(1000012);

        CustomModelDataComponent cmdc = im.getCustomModelDataComponent();
        List<String> list = Arrays.asList("backpack_1");
        cmdc.setStrings(list);
        im.setCustomModelDataComponent(cmdc);

        nsk = new NamespacedKey(App.main, "key" + "R3SLeatherBackpack");
        im.getPersistentDataContainer().set(nsk, PersistentDataType.STRING, "R3S_kleiner_Rucksack");
        backPack.setItemMeta(im);
        ShapedRecipe backpackRecipe = new ShapedRecipe(nsk, backPack);
        backpackRecipe.shape("***", "*T*", "***");
        backpackRecipe.setIngredient('*', Material.LEATHER);
        backpackRecipe.setIngredient('T', Material.CHEST);
        if (getServer().getRecipe(nsk) == null) {
            App.main.getServer().addRecipe(backpackRecipe);
            App.main.recipeKeys.add(backpackRecipe.getKey());
        }

        backPack2 = new ItemStack(Material.BARRIER, 1);
        ItemMeta im2 = backPack2.getItemMeta();
        im2.displayName(Component.translatable(ChatColor.WHITE + "Rucksack"));
        im2.setCustomModelData(1000013);
        CustomModelDataComponent cmdc2 = im2.getCustomModelDataComponent();
        List<String> list2 = Arrays.asList("backpack_2");
        cmdc2.setStrings(list2);
        im2.setCustomModelDataComponent(cmdc2);
        nsk2 = new NamespacedKey(App.main, "key" + "R3SBackpack");
        im2.getPersistentDataContainer().set(nsk2, PersistentDataType.STRING, "R3S_Rucksack");
        backPack2.setItemMeta(im2);

        ShapedRecipe safechestRecipe2 = new ShapedRecipe(nsk2, backPack2);
        safechestRecipe2.shape("***", "*T*", "***");
        safechestRecipe2.setIngredient('*', Material.IRON_INGOT);
        safechestRecipe2.setIngredient('T', backPack);
        if (getServer().getRecipe(nsk2) == null) {
            App.main.getServer().addRecipe(safechestRecipe2);
            App.main.recipeKeys.add(safechestRecipe2.getKey());
        }

        backPack3 = new ItemStack(Material.BARRIER, 1);
        ItemMeta im3 = backPack3.getItemMeta();
        im3.displayName(Component.translatable(ChatColor.WHITE + "Großer Rucksack"));
        im3.setCustomModelData(1000014);
        CustomModelDataComponent cmdc3 = im3.getCustomModelDataComponent();
        List<String> list3 = Arrays.asList("backpack_3");
        cmdc3.setStrings(list3);
        im3.setCustomModelDataComponent(cmdc3);
        nsk3 = new NamespacedKey(App.main, "key" + "R3SGoldBackpack");
        im3.getPersistentDataContainer().set(nsk3, PersistentDataType.STRING, "R3S_großer_Rucksack");
        backPack3.setItemMeta(im3);
        ShapedRecipe safechestRecipe3 = new ShapedRecipe(nsk3, backPack3);
        safechestRecipe3.shape("***", "*T*", "***");
        safechestRecipe3.setIngredient('*', Material.GOLD_INGOT);
        safechestRecipe3.setIngredient('T', backPack);
        if (getServer().getRecipe(nsk3) == null) {
            App.main.getServer().addRecipe(safechestRecipe3);
            App.main.recipeKeys.add(safechestRecipe3.getKey());
        }
        backPack4 = new ItemStack(Material.BARRIER, 1);
        ItemMeta im4 = backPack4.getItemMeta();
        im4.displayName(Component.translatable(ChatColor.WHITE + "Riesiger Rucksack"));
        im4.setCustomModelData(1000015);
        CustomModelDataComponent cmdc4 = im4.getCustomModelDataComponent();
        List<String> list4 = Arrays.asList("backpack_4");
        cmdc4.setStrings(list4);
        im4.setCustomModelDataComponent(cmdc4);
        nsk4 = new NamespacedKey(App.main, "key" + "R3SDiamondBackpack");
        im4.getPersistentDataContainer().set(nsk4, PersistentDataType.STRING, "R3S_riesiger_Rucksack");
        backPack4.setItemMeta(im4);
        ShapedRecipe safechestRecipe4 = new ShapedRecipe(nsk4, backPack4);
        safechestRecipe4.shape("***", "*T*", "***");
        safechestRecipe4.setIngredient('*', Material.DIAMOND);
        safechestRecipe4.setIngredient('T', backPack);
        if (getServer().getRecipe(nsk4) == null) {
            App.main.getServer().addRecipe(safechestRecipe4);
            App.main.recipeKeys.add(safechestRecipe4.getKey());
        }
        NamespacedKey nskiR = new NamespacedKey(App.main, "key" + "R3SInvRahmen");
        ItemStack item = new ItemStack(Material.ITEM_FRAME, 1);
        meta = item.getItemMeta();
        meta.displayName(Component.translatable(ChatColor.WHITE + "Unsichtbarer Rahmen"));
        meta.getPersistentDataContainer().set(InvisibleFrame.nsk, PersistentDataType.BYTE, (byte) 1);
        item.setItemMeta(meta);
        ShapelessRecipe invRahmenShapeless = new ShapelessRecipe(nskiR, item);
        invRahmenShapeless.addIngredient(new ItemStack(Material.ITEM_FRAME, 1));
        invRahmenShapeless.addIngredient(new ItemStack(Material.GOLDEN_CARROT, 1));
        invRahmenShapeless.addIngredient(new ItemStack(Material.FERMENTED_SPIDER_EYE, 1));
        if (getServer().getRecipe(nskiR) == null) {
            App.main.getServer().addRecipe(invRahmenShapeless);
            App.main.recipeKeys.add(invRahmenShapeless.getKey());
        }
        NamespacedKey nskigR = new NamespacedKey(App.main, "key" + "R3SInvGlowRahmen");

        ItemStack item2 = new ItemStack(Material.GLOW_ITEM_FRAME, 1);
        meta2 = item2.getItemMeta();
        meta2.displayName(Component.translatable(ChatColor.WHITE + "Unsichtbarer Leuchtrahmen"));
        meta2.getPersistentDataContainer().set(InvisibleFrame.nsk, PersistentDataType.BYTE, (byte) 1);
        item2.setItemMeta(meta2);
        ShapelessRecipe invRahmenShapeless2 = new ShapelessRecipe(nskigR, item2);
        invRahmenShapeless2.addIngredient(new ItemStack(Material.GLOW_ITEM_FRAME, 1));
        invRahmenShapeless2.addIngredient(new ItemStack(Material.GOLDEN_CARROT, 1));
        invRahmenShapeless2.addIngredient(new ItemStack(Material.FERMENTED_SPIDER_EYE, 1));
        if (getServer().getRecipe(nskigR) == null) {
            App.main.getServer().addRecipe(invRahmenShapeless2);
            App.main.recipeKeys.add(invRahmenShapeless2.getKey());
        }
        NamespacedKey nskBulb = new NamespacedKey(App.main, "key" + "R3SLightBulb");
        ItemMeta bulbmeta = bulb.getItemMeta();
        bulbmeta.displayName(Component.translatable(ChatColor.WHITE + "Lichtquelle"));
        bulb.setItemMeta(bulbmeta);
        ShapedRecipe bulbShape = new ShapedRecipe(nskBulb, bulb);
        bulbShape.shape("GGG", "GTG", "GIG");
        bulbShape.setIngredient('G', Material.GLASS);
        bulbShape.setIngredient('T', Material.TORCH);
        bulbShape.setIngredient('I', Material.IRON_NUGGET);
        if (getServer().getRecipe(nskBulb) == null) {
            App.main.getServer().addRecipe(bulbShape);
            App.main.recipeKeys.add(bulbShape.getKey());
        }
        nskEmptyExpBottle = new NamespacedKey(App.main, "key" + "R3SEmptyExpBottle");
        eBottle = new ItemStack(Material.GLASS_BOTTLE, 1);
        ItemMeta eBottleMeta = eBottle.getItemMeta();
        nskGlow = new NamespacedKey(App.main, "key" + "R3SExpBottleEXP_GLOW");
        eBottleMeta.displayName(Component.translatable(ChatColor.AQUA + "Leeres Erfahrungsfläschchen"));
        eBottleMeta.getPersistentDataContainer().set(nskEmptyExpBottle, PersistentDataType.STRING,
                "R3S_Empty_ExpBottle");
        eBottle.setItemMeta(eBottleMeta);
        ShapedRecipe eBottleShape = new ShapedRecipe(nskEmptyExpBottle, eBottle);
        eBottleShape.shape("GGG", "GBG", "GGG");
        eBottleShape.setIngredient('G', Material.GOLD_NUGGET);
        eBottleShape.setIngredient('B', Material.GLASS_BOTTLE);
        if (getServer().getRecipe(nskEmptyExpBottle) == null) {
            App.main.getServer().addRecipe(eBottleShape);
            App.main.recipeKeys.add(eBottleShape.getKey());
        }

        zombieLeather = new ItemStack(Material.LEATHER);
        NamespacedKey nskZombieLeather = new NamespacedKey(App.main, "R3S_RECIPE_ZOMBIE_LEATHER");
        NamespacedKey nskZombieLeatherRecipe = new NamespacedKey(App.main, "R3S_RECIPE_ZOMBIE_LEATHER");
        ItemMeta mzombieLeather = zombieLeather.getItemMeta();
        mzombieLeather.setCustomModelData(1000018);
        mzombieLeather.displayName(Component.text(ChatColor.WHITE + "Zombieleder"));
        mzombieLeather.getPersistentDataContainer().set(nskZombieLeather, PersistentDataType.STRING,
                "R3S_ZOMBIE_LEATHER");
        zombieLeather.setItemMeta(mzombieLeather);
        ShapedRecipe zombieLeatherRecipe = new ShapedRecipe(nskZombieLeatherRecipe, zombieLeather);
        zombieLeatherRecipe.shape("***", "***", "***");
        zombieLeatherRecipe.setIngredient('*', Material.ROTTEN_FLESH);
        if (getServer().getRecipe(nskZombieLeatherRecipe) == null) {
            App.main.getServer().addRecipe(zombieLeatherRecipe);
            App.main.recipeKeys.add(zombieLeatherRecipe.getKey());
        }

        RecipeChoice rcZombieLeather = new RecipeChoice.ExactChoice(zombieLeather);
        NamespacedKey nskLeatherRecipe = new NamespacedKey(App.main, "R3S_RECIPE_LEATHER");
        ShapedRecipe leatherRecipe = new ShapedRecipe(nskLeatherRecipe, new ItemStack(Material.LEATHER));
        leatherRecipe.shape("***", "***", "***");
        leatherRecipe.setIngredient('*', rcZombieLeather);
        if (getServer().getRecipe(nskLeatherRecipe) == null) {
            App.main.getServer().addRecipe(leatherRecipe);
            App.main.recipeKeys.add(leatherRecipe.getKey());
        }

        Inventory playerInv = Bukkit.createInventory(null, InventoryType.PLAYER);
        playerInv.addItem(new ItemStack(Material.BIRCH_PLANKS, 24));
        playerInv.addItem(new ItemStack(Material.WARPED_PLANKS, 43));
        playerInv.addItem(new ItemStack(Material.BLUE_WOOL, 30));

        Bukkit.getWorlds().get(0).setGameRule(GameRule.SHOW_DEATH_MESSAGES, false);

        listenerRegistration();

        //////////////////////
        ItemStack desiredItem = new ItemStack(Material.CHEST, 1);
        Recipe r = Bukkit.getServer().getRecipe(desiredItem.getType().getKey());
        ShapedRecipe sr = (ShapedRecipe) r;
        HashMap<RecipeChoice, Integer> ingredients = new HashMap<RecipeChoice, Integer>();
        HashMap<Material, Integer> hmhelper = new HashMap<Material, Integer>();
        int reqItemsCount = 0;
        for (RecipeChoice rC : sr.getChoiceMap().values()) {
            if (rC != null) {
                if (ingredients.keySet().contains(rC)) {
                    ingredients.put(rC, ingredients.get(rC) + 1);
                } else {
                    ingredients.put(rC, 1);
                }
            }
        }
        for (Map.Entry<RecipeChoice, Integer> entry : ingredients.entrySet()) {
            RecipeChoice rrC = entry.getKey();
            Integer amount = entry.getValue();
            MaterialChoice mmC = (MaterialChoice) rrC;
            for (Material maat : mmC.getChoices()) {
                ItemStack is = new ItemStack(maat);
                if (playerInv.containsAtLeast(is, amount)) {
                    reqItemsCount++;
                    hmhelper.put(maat, amount);
                    break;
                } else {
                }
            }

        }
        if (reqItemsCount == ingredients.size()) {
            for (Map.Entry<Material, Integer> entry : hmhelper.entrySet()) {
                ItemStack is = new ItemStack(entry.getKey(), entry.getValue());
                playerInv.removeItem(is);
            }
        }
        reqItemsCount = 0;
        hmhelper = new HashMap<Material, Integer>();
        ingredients = new HashMap<RecipeChoice, Integer>();
        ////////////////////////

        Collection<? extends Player> onlinePlayer = Bukkit.getServer().getOnlinePlayers();
        for (Player p : onlinePlayer) {
            hmActionbar.put(p, true);
            AFKListener.createAFKTimer(p);
        }

        try {

            if (!coordinateRunner) {
                Bukkit.getScheduler().scheduleSyncRepeatingTask(App.main, new Runnable() {
                    @Override
                    public void run() {
                        for (Player p : Bukkit.getServer().getOnlinePlayers()) {

                            if (hmActionbar.get(p)) {
                                Location loc = p.getLocation();

                                p.sendActionBar(Component.text(
                                        "X: " + loc.getBlockX() + " Y: " + loc.getBlockY() + " Z: " + loc.getBlockZ()
                                                + "     " + parseTime((Bukkit.getServer().getWorlds().get(0).getTime()))
                                                + "Uhr      Wetter: "
                                                + getWeather(p)));
                            }

                        }
                    }
                }, 0, 1);
                coordinateRunner = true;
            }

        } catch (Exception ex) {

        }

    }

    public static String getWeather(Player p) {
        Boolean snow = false;
        Boolean desert = false;

        switch (Bukkit.getWorlds().get(0).getBiome(p.getLocation()).toString()) {
            case "DESERT":
                desert = true;
                break;
            case "FROZEN_PEAKS":
                snow = true;
                break;
            case "FROZEN_RIVER":
                snow = true;
                break;
            case "GROVE":
                snow = true;
                break;
            case "ICE_SPIKES":
                snow = true;
                break;
            case "JAGGED_PEAKS":
                snow = true;
                break;

            case "SNOWY_BEACH":
                snow = true;
                break;
            case "SNOWY_PLAINS":
                snow = true;
                break;
            case "SNOWY_SLOPES":
                snow = true;
                break;
            case "SNOWY_TAIGA":
                snow = true;
                break;
            default:
                break;

        }

        if (Bukkit.getWorlds().get(0).hasStorm() && Bukkit.getWorlds().get(0).isThundering()) {
            return "Gewitter";
        }

        else if (Bukkit.getWorlds().get(0).hasStorm() && !snow && !desert) {
            return "Regen";
        } else if (Bukkit.getWorlds().get(0).hasStorm() && snow && !desert) {
            return "Schnee";
        }

        return "Klar";
    }

    public static String parseTime(long time) {
        long gameTime = time;
        long hours = gameTime / 1000 + 6;
        long minutes = (gameTime % 1000) * 60 / 1000;

        if (hours >= 24) {
            hours -= 24;
        }
        if (hours >= 24) {
            hours -= 24;
        }

        String mm = "0" + minutes;
        mm = mm.substring(mm.length() - 2, mm.length());
        String hh = "0" + hours;
        hh = hh.substring(hh.length() - 2, hh.length());
        return hh + ":" + mm;
    }

    @Override
    public void onDisable() {
        getLogger().info("Plugin disabled!");
    }

    private void listenerRegistration() {

        pM.registerEvents(new LoginListener(), this);
        pM.registerEvents(new EnvironmentExListeners(), this);
        pM.registerEvents(new InvisibleFrame(), this);
        pM.registerEvents(new HealthBarListener(), this);
        pM.registerEvents(new DoubleDoorListener(), this);
        pM.registerEvents(new ExpBottleListener(), this);
        pM.registerEvents(new VillagerListener(), this);
        pM.registerEvents(new CustomItems(), this);
        pM.registerEvents(new Filter(), this);
        pM.registerEvents(new CustomRecipes(), this);
        pM.registerEvents(new MobHeads(), this);
        pM.registerEvents(new WorkbenchToGo(), this);
        pM.registerEvents(new MobBurner(), this);
        pM.registerEvents(new AutoCrafter(), this);
        pM.registerEvents(new AFKListener(), this);
        pM.registerEvents(new CauldronConcrete(), this);
        pM.registerEvents(new InfinityWaterBucket(), this);
        pM.registerEvents(new ArmoredElytra(), this);
        pM.registerEvents(new ShulkerPreview(), this);
        pM.registerEvents(new BetterTotems(), this);
        pM.registerEvents(new CustomMusicDiscs(), this);
        getCommand("test").setExecutor(new EnvironmentExCommands());
        getCommand("y").setExecutor(new EnvironmentExCommands());
        getCommand("n").setExecutor(new EnvironmentExCommands());
        getCommand("add").setExecutor(new EnvironmentExCommands());
        getCommand("afk").setExecutor(new EnvironmentExCommands());
        getCommand("pin").setExecutor(new EnvironmentExCommands());
        getCommand("pin").setTabCompleter(new PinFeature());
    }

    public void log(Object msg) {
        App.main.getLogger().info(msg.toString());
    }

    public static Boolean isDay() {

        // wenn zeit kleiner als 24000 && zeit größer gleich 12575
        World w = Bukkit.getServer().getWorlds().get(0);
        if (w.getTime() < 23675 && w.getTime() >= 12475) {
            return false;
        }

        return true;
    }
}
