package de.fanta.challenges.guis.savegui;

import de.fanta.challenges.Challenges;
import de.fanta.challenges.SaveSlot;
import de.fanta.challenges.ServerType;
import de.fanta.challenges.utils.ChatUtil;
import de.fanta.challenges.utils.SaveWorldUtils;
import de.fanta.challenges.utils.guiutils.AbstractWindow;
import de.fanta.challenges.utils.guiutils.GUIUtils;
import de.iani.cubesideutils.StringUtil;
import de.iani.playerUUIDCache.CachedPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;

public class ChallengeSaveGui extends AbstractWindow {
    private static final Challenges plugin = Challenges.getPlugin();
    private static final int SAVE_1_INDEX = 1;
    private static final int SAVE_2_INDEX = 3;
    private static final int SAVE_3_INDEX = 5;
    private static final int SAVE_AUTO_INDEX = 7;
    private static final int WINDOW_SIZE = 9;
    private static final HashMap<UUID, UUID> savePlayerList = new HashMap<>();

    public ChallengeSaveGui(Player player, CachedPlayer savePlayer) {
        super(player, Bukkit.createInventory(null, WINDOW_SIZE, plugin.getGUIPREFIX() + " >> Map speichern"));
        savePlayerList.put(player.getUniqueId(), savePlayer.getUniqueId());
    }

    @Override
    protected void rebuildInventory() {
        Player player = getPlayer();
        UUID savePlayerID = savePlayerList.get(player.getUniqueId());
        File save1;
        File save2;
        File save3;
        File saveAuto;
        if (plugin.getServerType() != ServerType.ADVENTURE) {
            save1 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/1");
            save2 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/2");
            save3 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/3");
            saveAuto = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/autosave");
        } else {
            save1 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/1");
            save2 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/2");
            save3 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/3");
            saveAuto = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/autosave");
        }

        for (int i = 0; i < WINDOW_SIZE; i++) {
            ItemStack item;
            switch (i) {
                case SAVE_1_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_1, save1);
                case SAVE_2_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_2, save2);
                case SAVE_3_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_3, save3);
                case SAVE_AUTO_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_AUTO, saveAuto);
                default -> item = GUIUtils.EMPTY_ICON;
            }
            this.getInventory().setItem(i, item);
        }
    }

    @Override
    public void onItemClicked(InventoryClickEvent event) {
        Player player = getPlayer();
        if (!mayAffectThisInventory(event)) {
            return;
        }

        event.setCancelled(true);
        if (!getInventory().equals(event.getClickedInventory())) {
            return;
        }

        Player p = getPlayer();
        UUID savePlayerID = savePlayerList.get(p.getUniqueId());
        File save1;
        File save2;
        File save3;
        if (plugin.getServerType() != ServerType.ADVENTURE) {
            save1 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/1");
            save2 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/2");
            save3 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/3");
        } else {
            save1 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/1");
            save2 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/2");
            save3 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/3");
        }

        int slot = event.getSlot();
        switch (slot) {
            case SAVE_1_INDEX -> {
                if (!p.hasPermission("challenge.save.slot1")) {
                    ChatUtil.sendErrorMessage(p, "Für diesen Slot hast du keine Rechte!");
                    return;
                }
                if (!save1.isDirectory()) {
                    player.closeInventory();
                    SaveWorldUtils.saveWorld(player, savePlayerID.toString(), SaveSlot.SLOT_1);
                    return;
                }
                new ChallengeSaveConfirmGui(player, savePlayerID, SaveSlot.SLOT_1, event.getCurrentItem()).open();
            }
            case SAVE_2_INDEX -> {
                if (!p.hasPermission("challenge.save.slot2")) {
                    ChatUtil.sendErrorMessage(p, "Für diesen Slot brauchst du VIP!");
                    return;
                }
                if (!save2.isDirectory()) {
                    player.closeInventory();
                    SaveWorldUtils.saveWorld(player, savePlayerID.toString(), SaveSlot.SLOT_2);
                    return;
                }
                new ChallengeSaveConfirmGui(player, savePlayerID, SaveSlot.SLOT_2, event.getCurrentItem()).open();
            }
            case SAVE_3_INDEX -> {
                if (!p.hasPermission("challenge.save.slot3")) {
                    ChatUtil.sendErrorMessage(p, "Für diesen Slot brauchst du VIP!");
                    return;
                }
                if (!save3.isDirectory()) {
                    player.closeInventory();
                    SaveWorldUtils.saveWorld(player, savePlayerID.toString(), SaveSlot.SLOT_3);
                    return;
                }
                new ChallengeSaveConfirmGui(player, savePlayerID, SaveSlot.SLOT_3, event.getCurrentItem()).open();
            }
            default -> {
            }
        }
    }

    private static String getFileDate(File file) {
        FileTime fileTime;
        try {
            BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
            fileTime = attr.creationTime();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return StringUtil.formatDate(fileTime.toMillis());
    }

    private static ItemStack getDisplayItem(Player player, SaveSlot saveSlot, File save) {
        ItemStack item;
        if (player.hasPermission(saveSlot.getPermission())) {
            if (save.isDirectory()) {
                File mapConfig = new File(save, "/Challenges/serverconfig.yml");
                Material displayItem = null;
                String displayName = null;
                try {
                    YamlConfiguration serverConfig = new YamlConfiguration();
                    serverConfig.load(mapConfig);
                    String itemType = serverConfig.getString("displayItem.item");
                    String itemName = serverConfig.getString("displayItem.name");
                    if (itemType != null) {
                        try {
                            displayItem = Material.valueOf(itemType);
                        } catch (IllegalArgumentException ignore) {
                        }
                    }
                    if (itemName != null) {
                        displayName = itemName;
                    }
                } catch (IOException | InvalidConfigurationException ex) {
                    plugin.getLogger().log(Level.SEVERE, "Fehler beim laden der config", ex);
                }

                ItemStack stack = new ItemStack(displayItem != null ? displayItem : Material.MAP);
                ItemMeta meta = stack.getItemMeta();
                meta.setDisplayName(displayName != null ? displayName : ChatUtil.GREEN + "Save " + saveSlot.getSlot());

                if (saveSlot == SaveSlot.SLOT_AUTO) {
                    meta.setLore(List.of(ChatUtil.RED + "AutoSave kann nicht überschrieben werden!", ChatUtil.GREEN + "Gespeichert am " + getFileDate(save)));
                } else {
                    meta.setLore(List.of(ChatUtil.GREEN + "Gespeichert am " + getFileDate(save)));
                }

                stack.setItemMeta(meta);
                item = stack;


            } else {
                item = GUIUtils.createGuiItem(Material.LIME_STAINED_GLASS_PANE, ChatUtil.GREEN + "Frei");
            }
        } else {
            item = GUIUtils.createGuiItem(Material.BARRIER, ChatUtil.RED + "Für diesen Slot brauchst du VIP");
        }
        return item;
    }
}
