package moe.oko.opennaw.util;

import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import moe.oko.opennaw.model.Nation;
import moe.oko.opennaw.model.type.CityType;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang.enums.EnumUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.janboerman.guilib.api.menu.CycleButton;
import xyz.janboerman.guilib.api.menu.ItemButton;
import xyz.janboerman.guilib.api.menu.MenuHolder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class GuiHelper {
    public static MenuHolder<OpenNAW> getJoinMenu() {
        var menu = new MenuHolder<>(OpenNAW.getInstance(), 9, "Join a Nation!");

        int i = 9;
        int s = 0;
        for(var nation : OpenNAW.getInstance().getNationHandler().getNationList()) {
            var is = new ItemStack(Material.getMaterial(nation.getColour() + "_WOOL"));
            var meta = is.getItemMeta();
            meta.setDisplayName(ChatColor.valueOf(nation.getColour()) + nation.getName());
            is.setItemMeta(meta);
            menu.setButton(s, new ItemButton<>(is) {
                @Override
                public void onClick(MenuHolder<?> menu, InventoryClickEvent event) {
                    if(event.getClick().equals(ClickType.LEFT)) {
                        //Left click, run join logic.
                        var viewer = event.getViewers().get(0);
                        if(!(viewer instanceof Player)) { return; } //fugged
                        var player = (Player) viewer;

                        nation.getPlayerMap().put(player.getUniqueId(), player);
                        OpenNAW.getInstance().getGroupHandler().addPlayerToGroup(player, nation.getGroup());

                        player.sendMessage(ChatColor.GREEN + "Joined " + nation.getName() + " successfully.");
                        event.getView().close(); //Close inv.
                    }
                }
            });
            s++;
        }
        return menu;
    }

    public static MenuHolder<OpenNAW> getNationModMenu(Nation nation) {
        var menu = new MenuHolder<>(OpenNAW.getInstance(), 9, nation.getName() + " Modification");

        var colour = new ItemStack(Material.valueOf(nation.getColour() + "_WOOL"));
        var meta = colour.getItemMeta();
        meta.setDisplayName(colour.getType().name().replace("_WOOL", "").toUpperCase());
        colour.setItemMeta(meta);
        var woolCollection = new ArrayList<>();
        for(var mat : Material.values()) {
            var material = (Material) mat;
            if (material.name().contains("_WOOL")) {
                woolCollection.add(new ItemStack(material));
            }
        }
        /*
        Colour Selection Button
         */
        menu.setButton(0, new CycleButton<>(colour, woolCollection, 0) {
            @Override
            public void updateStateForwards(MenuHolder<?> menu, InventoryClickEvent event) {
                incrementCursor();
                var i = getCursor();
                var player = (Player) event.getViewers().get(0);
                var is = (ItemStack) woolCollection.get(i);
                var meta = is.getItemMeta();
                meta.setDisplayName(is.getType().name().replace("_WOOL", "").toUpperCase());
                is.setItemMeta(meta);
                setIcon(is);
                nation.setColour(this.getIcon().getType().name().replace("_WOOL", ""));
                player.sendMessage(ChatColor.GREEN + "Colour for this nation was changed to " + nation.getColour());
            }

            @Override
            public void updateStateBackwards(MenuHolder<?> menu, InventoryClickEvent event) {
                decrementCursor();
                var i = getCursor();
                var player = (Player) event.getViewers().get(0);
                var is = (ItemStack) woolCollection.get(i);
                var meta = is.getItemMeta();
                meta.setDisplayName(is.getType().name().replace("_WOOL", "").toUpperCase());
                is.setItemMeta(meta);
                setIcon(is);
                nation.setColour(this.getIcon().getType().name().replace("_WOOL", ""));
                player.sendMessage(ChatColor.GREEN + "Colour for this nation was changed to " + nation.getColour());
            }
        });

        /**
         * Spawn Setting
         */
        var is = new ItemStack(Material.BARRIER);
        var meta1 = is.getItemMeta();
        meta1.setDisplayName("Spawn Location");
        var lore = new ArrayList<String>();
        lore.add(ChatColor.GRAY + "Click to set your current location as the spawn for this nation.");
        meta1.setLore(lore);
        is.setItemMeta(meta1);
        menu.setButton(1, new ItemButton<>(is) {
            @Override
           public void onClick(MenuHolder<?> menu, InventoryClickEvent event) {
                var player = (Player) event.getViewers().get(0);
                nation.setSpawn(player.getLocation());
                player.sendMessage(ChatColor.GREEN + "Successfully set new spawn location for " + nation.getName() + " to " + player.getLocation());
                player.closeInventory();
            }
        });
        return menu;
    }
    public static MenuHolder<OpenNAW> getCityModMenu(City city) {
        var menu = new MenuHolder<>(OpenNAW.getInstance(), 9,  city.getName() + " Modification");
        var map = new HashMap<CityType, Material>();
        map.put(CityType.CAPITAL, Material.RED_BANNER);
        map.put(CityType.NORMAL, Material.SPONGE);
        map.put(CityType.PORT, Material.OAK_BOAT);

        var typeis = new ItemStack(map.get(city.getType()));
        var typemeta = typeis.getItemMeta();
        typemeta.setDisplayName(city.getType().name());
        List<String> list = new ArrayList<>();
        list.add(city.getType().getDescription());
        typemeta.setLore(list);
        typeis.setItemMeta(typemeta);
        menu.setButton(0, new CycleButton<>(typeis, map.keySet().stream().toList(), 0) {
            @Override
            public void updateStateBackwards(MenuHolder<?> menuHolder, InventoryClickEvent event) {
                decrementCursor();
                var i = getCursor();
                var player = (Player) event.getViewers().get(0);
                var typeis = new ItemStack(map.get(map.keySet().stream().toList().get(i)));
                var typemeta = typeis.getItemMeta();
                typemeta.setDisplayName(map.keySet().stream().toList().get(i).name());
                List<String> list = new ArrayList<>();
                list.add(map.keySet().stream().toList().get(i).getDescription());
                typemeta.setLore(list);
                typeis.setItemMeta(typemeta);
                setIcon(typeis);
                city.setType(map.keySet().stream().toList().get(i));
                player.sendMessage(ChatColor.GREEN + "Successfully set city type to " + city.getType() + "!");
            }

            @Override
            public void updateStateForwards(MenuHolder<?> menuHolder, InventoryClickEvent event) {
                incrementCursor();
                var i = getCursor();
                var player = (Player) event.getViewers().get(0);
                var typeis = new ItemStack(map.get(map.keySet().stream().toList().get(i)));
                var typemeta = typeis.getItemMeta();
                typemeta.setDisplayName(map.keySet().stream().toList().get(i).name());
                List<String> list = new ArrayList<>();
                list.add(map.keySet().stream().toList().get(i).getDescription());
                typemeta.setLore(list);
                typeis.setItemMeta(typemeta);
                setIcon(typeis);
                city.setType(map.keySet().stream().toList().get(i));
                player.sendMessage(ChatColor.GREEN + "Successfully set city type to " + city.getType() + "!");
            }
        });

        var nameis = new ItemStack(Material.OAK_SIGN);
        var namemeta = nameis.getItemMeta();
        namemeta.setDisplayName("Set City Name");
        nameis.setItemMeta(namemeta);
        menu.setButton(1, new ItemButton<>(nameis) {
            @Override
            public void onClick(MenuHolder<?> holder, InventoryClickEvent event) {
                var player = (Player) event.getViewers().get(0);
                player.closeInventory();
                //Make our string prompt which has multiple hhhhh
                var namePrompt = new StringPrompt() {
                    @Override
                    public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) {
                        return ChatColor.GOLD + "Please enter the name you would like to set the city name (less than 50 char) to within 15 seconds." +
                                "\n" + ChatColor.YELLOW + "Type CANCEL if you would like to cancel this prompt.";
                    }

                    @Override
                    public @Nullable Prompt acceptInput(@NotNull ConversationContext conversationContext, @Nullable String s) {
                        conversationContext.getForWhom().sendRawMessage(ChatColor.GREEN + "Successfully set the city name to " + s);
                        city.setName(s);
                        return END_OF_CONVERSATION;
                    }
                };
                var factory = new ConversationFactory(OpenNAW.getInstance()).withFirstPrompt(namePrompt)
                        .withEscapeSequence("CANCEL").withTimeout(15).thatExcludesNonPlayersWithMessage("no console");
                factory.buildConversation(player).begin();
            }
        });
        return menu;
    }
}
