package de.hessj.environmentex;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Dispenser;
import org.bukkit.block.data.Directional;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.view.AnvilView;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.potion.PotionType;
import de.hessj.helper.Helper.Type;
import net.kyori.adventure.text.Component;
import net.md_5.bungee.api.ChatColor;

public class ExpBottleListener implements Listener {

    int lvl = 0;
    ItemStack expBottle = new ItemStack(Material.EXPERIENCE_BOTTLE, 1);
    ItemMeta itemMeta = expBottle.getItemMeta();
    NamespacedKey nskexpBottleEXP = new NamespacedKey(App.main, "key" + "R3SExpBottleEXP");
    public de.hessj.helper.Helper helper = new de.hessj.helper.Helper();

    @EventHandler
    public void on_prepare_anvil(PrepareAnvilEvent event) {
        AnvilView av = event.getView();
        av.setMaximumRepairCost(999999);
        if (av.getRepairCost() > 40) {
            av.setRepairCost(40);
        }
    }

    public long creationTime = 0;

    @EventHandler
    public void onUse(PlayerInteractEvent e) {
        ExperienceManager expMan = new ExperienceManager(e.getPlayer());
        if (e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK
                || (e.getAction() == Action.RIGHT_CLICK_BLOCK && App.helper.isInteractable(e.getClickedBlock()))) {
            return;
        }

        if (e.getPlayer().getInventory().getItemInMainHand() != null
                && e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.GLASS_BOTTLE)) {
            if (e.getPlayer().getInventory().getItemInMainHand().hasItemMeta() && e.getPlayer().getInventory()
                    .getItemInMainHand().getItemMeta().getPersistentDataContainer() != null) {
                if (e.getPlayer().getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer()
                        .has(App.main.nskEmptyExpBottle, PersistentDataType.STRING)) {
                    e.setUseItemInHand(Result.DENY);

                    lvl = e.getPlayer().getLevel();

                    if (lvl != 0) {
                        Boolean freeSpace = false;
                        e.getPlayer().getInventory().getItemInMainHand()
                                .setAmount(e.getPlayer().getInventory().getItemInMainHand().getAmount() - 1);
                        itemMeta.getPersistentDataContainer().set(nskexpBottleEXP, PersistentDataType.INTEGER,
                                expMan.getCurrentExp());
                        List<Component> lore = new ArrayList<Component>();
                        lore.add(Component.translatable(
                                String.format("%,d", expMan.getCurrentExp()) + " Erfahrungspunkte gespeichert"
                                        + convertToInvisibleString(UUID.randomUUID().toString())));

                        itemMeta.lore(lore);

                        expBottle.setItemMeta(itemMeta);

                        for (ItemStack i : e.getPlayer().getInventory().getStorageContents()) {
                            if (i != null && i == expBottle) {
                                if (i.getAmount() < 64) {
                                    i.setAmount(i.getAmount() + 1);
                                    break;
                                }
                            } else {
                                if (i == null) {
                                    freeSpace = true;
                                }
                            }
                        }

                        if (!freeSpace) {// ansonsten checken für free space
                            e.getPlayer().sendMessage(helper.R3SMessage(Type.ERROR,
                                    "[EnvironmentEx] Dein Inventar ist voll, dein Erfahrungsfläschchen wurde gedropped!"));
                            e.getPlayer().getWorld().dropItem(
                                    e.getPlayer().getLocation(), expBottle);
                        } else {
                            if (freeSpace) {
                                e.getPlayer().getInventory()
                                        .addItem(expBottle);
                            }
                        }

                        e.getPlayer().getWorld().playSound(e.getPlayer().getLocation(), Sound.ITEM_BOTTLE_FILL,
                                SoundCategory.PLAYERS, 1.0f, 2.0f);
                        e.getPlayer().getWorld().playSound(e.getPlayer().getLocation(),
                                Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.PLAYERS, 1.0f, 4.0f);
                        e.getPlayer().swingMainHand();

                        e.getPlayer().setLevel(0);
                        e.getPlayer().setExp(0);

                        creationTime = Instant.now().getEpochSecond();
                        Bukkit.getScheduler().scheduleSyncDelayedTask(App.main, new Runnable() {
                            public void run() {
                                creationTime = 0;
                                return;
                            }
                        }, 15);

                    }
                }
            }
        } else if (e.getPlayer().getInventory().getItemInMainHand() != null
                && e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.EXPERIENCE_BOTTLE)) {
            if (e.getPlayer().getInventory().getItemInMainHand().hasItemMeta() && e.getPlayer().getInventory()
                    .getItemInMainHand().getItemMeta().getPersistentDataContainer() != null) {
                if (e.getPlayer().getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer()
                        .has(nskexpBottleEXP, PersistentDataType.INTEGER) && creationTime == 0) {
                    e.setUseItemInHand(Result.DENY);

                    int storedEXP = e.getPlayer().getInventory().getItemInMainHand().getItemMeta()
                            .getPersistentDataContainer().get(nskexpBottleEXP, PersistentDataType.INTEGER);

                    int expOrbs = storedEXP;
                    World world = e.getPlayer().getWorld();
                    Location loc = e.getPlayer().getLocation();
                    loc = new Location(loc.getWorld(), loc.getX(), loc.getY() + 2, loc.getZ());
                    ((ExperienceOrb) world.spawn(loc, ExperienceOrb.class)).setExperience(expOrbs);

                    e.getPlayer().getInventory().getItemInMainHand()
                            .setAmount(e.getPlayer().getInventory().getItemInMainHand().getAmount() - 1);
                    e.getPlayer().getWorld().playSound(e.getPlayer().getLocation(),
                            Sound.ENTITY_PLAYER_BURP, SoundCategory.PLAYERS, 1.0f, 4.0f);
                    e.getPlayer().getWorld().playSound(e.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP,
                            SoundCategory.PLAYERS, 1.0f, 4.0f);
                    return;
                } else if (e.getPlayer().getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer()
                        .has(nskexpBottleEXP, PersistentDataType.INTEGER) && creationTime != 0) {
                    e.setCancelled(true);
                    return;
                }
            }
        }
    }

    public static String convertToInvisibleString(String s) {
        String hidden = "";
        for (char c : s.toCharArray())
            hidden += ChatColor.COLOR_CHAR + "" + c;
        return hidden;
    }

    @EventHandler
    public void onDispense(BlockDispenseEvent e) {
        if (e.getItem().getType() == Material.POTION && e.getBlock().getType() == Material.DISPENSER) {
            PotionMeta pm = (PotionMeta) e.getItem().getItemMeta();
            if (pm.getBasePotionType() == PotionType.WATER) {
                Location loc = e.getBlock().getLocation();

                Dispenser dis = (Dispenser) e.getBlock().getState();
                Directional d = (Directional) dis.getBlockData();

                switch (d.getFacing()) {
                    case EAST:
                        loc.setX(loc.getX() + 1);
                        break;
                    case NORTH:
                        loc.setZ(loc.getZ() - 1);
                        break;
                    case SOUTH:
                        loc.setZ(loc.getZ() + 1);
                        break;
                    case WEST:
                        loc.setX(loc.getX() - 1);
                        break;
                    case UP:
                        loc.setY(loc.getY() + 1);
                        break;
                    case DOWN:
                        loc.setY(loc.getY() - 1);
                        break;
                    default:
                        break;

                }
                Block b = e.getBlock().getWorld().getBlockAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
                if (b.getType() == Material.SPONGE) {
                    e.setCancelled(true);

                    Bukkit.getScheduler().runTaskLater(App.main, new Runnable() {

                        @Override
                        public void run() {
                            dis.getInventory().removeItem(e.getItem());

                            dis.getInventory().addItem(new ItemStack(Material.GLASS_BOTTLE, 1));

                        }

                    }, 4L);

                    dis.update();

                }

            }

        }
    }
}