/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.core;

import de.steamwar.command.SWCommand;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.sql.UserConfig;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.type.Light;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.meta.BlockDataMeta;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.*;

public class WorldEditRendererCUIEditor implements Listener {

    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent event) {
        for (Type type : Type.values()) {
            type.materialCache.remove(event.getPlayer());
            type.widthCache.remove(event.getPlayer());
        }
    }

    @EventHandler
    public void onCRIUSleep(CRIUSleepEvent event) {
        for (Type type : Type.values()) {
            type.materialCache.clear();
            type.widthCache.clear();
        }
    }


    @AllArgsConstructor
    public enum Type {
        SELECTION("cui_selection_material", "cui_selection_width", Material.PURPLE_CONCRETE, Width.MEDIUM),
        CLIPBOARD("cui_clipboard_material", "cui_clipboard_width", Material.LIME_CONCRETE, Width.SLIM),
        ;

        private final Map<Player, Material> materialCache = new HashMap<>();
        private final Map<Player, Width> widthCache = new HashMap<>();

        private final String configMaterial;
        private final String configWidth;
        private final Material defaultMaterial;
        private final Width defaultWidth;

        public Material getMaterial(Player player) {
            return materialCache.computeIfAbsent(player, p -> {
                String material = UserConfig.getConfig(p.getUniqueId(), configMaterial);
                if (material == null) {
                    return defaultMaterial;
                } else {
                    return Material.valueOf(material);
                }
            });
        }

        public void setMaterial(Player player, Material material) {
            materialCache.put(player, material);
            UserConfig.updatePlayerConfig(player.getUniqueId(), configMaterial, material.name());
        }

        public Width getWidth(Player player) {
            return widthCache.computeIfAbsent(player, p -> {
                String width = UserConfig.getConfig(p.getUniqueId(), configWidth);
                if (width == null) {
                    return defaultWidth;
                } else {
                    return Width.valueOf(width);
                }
            });
        }

        public void setWidth(Player player, Width width) {
            widthCache.put(player, width);
            UserConfig.updatePlayerConfig(player.getUniqueId(), configWidth, width.name());
        }
    }

    @AllArgsConstructor
    public enum Width {
        HUGE(15, "WORLDEDIT_CUI_WIDTH_HUGE", 2 / 16f),
        LARGE(8, "WORLDEDIT_CUI_WIDTH_LARGE", 1 / 16f),
        MEDIUM(4, "WORLDEDIT_CUI_WIDTH_MEDIUM", 1 / 32f),
        SLIM(0, "WORLDEDIT_CUI_WIDTH_SLIM", 1 / 64f);

        public final int lightLevel;
        public final String name;
        public final float value;
    }

    public WorldEditRendererCUIEditor() {
        Bukkit.getPluginManager().registerEvents(this, Core.getInstance());
        new Command();
    }

    private static class Command extends SWCommand {

        public Command() {
            super("cui");
        }

        @Register
        public void cuiEditor(Player player) {
            SWInventory inv = new SWInventory(player, 9 * 2, Core.MESSAGE.parse("WORLDEDIT_CUI_TITLE", player));
            setElement(inv, player, 3, "WORLDEDIT_CUI_SELECTION", Type.SELECTION);
            setElement(inv, player, 5, "WORLDEDIT_CUI_CLIPBOARD", Type.CLIPBOARD);
            inv.open();
        }

        private void setElement(SWInventory inv, Player player, int index, String uiName, Type type) {
            Material material = type.getMaterial(player);
            Width width = type.getWidth(player);

            inv.setItem(index, new SWItem(material, Core.MESSAGE.parse("WORLDEDIT_CUI_MATERIAL_NAME", player, Core.MESSAGE.parse(uiName, player)), Arrays.asList(Core.MESSAGE.parse("WORLDEDIT_CUI_MATERIAL_CLICK", player)), false, click -> {
                cuiMaterial(player, uiName, type, material);
            }));

            List<String> lore = new ArrayList<>();
            lore.add(Core.MESSAGE.parse("WORLDEDIT_CUI_WIDTH_CLICK", player));
            lore.add("");
            for (Width value : Width.values()) {
                if (value == width) {
                    lore.add(Core.MESSAGE.parse("WORLDEDIT_CUI_WIDTH_LORE_SELECTED", player, Core.MESSAGE.parse(value.name, player)));
                } else {
                    lore.add(Core.MESSAGE.parse("WORLDEDIT_CUI_WIDTH_LORE", player, Core.MESSAGE.parse(value.name, player)));
                }
            }
            SWItem lightItem = new SWItem(Material.LIGHT, Core.MESSAGE.parse("WORLDEDIT_CUI_WIDTH_NAME", player, Core.MESSAGE.parse(uiName, player)), lore, false, click -> {
                type.setWidth(player, Width.values()[(width.ordinal() + 1) % Width.values().length]);
                setElement(inv, player, index, uiName, type);
            });
            ItemMeta itemMeta = lightItem.getItemMeta();
            Light light = (Light) Material.LIGHT.createBlockData();
            light.setLevel(width.lightLevel);
            ((BlockDataMeta) itemMeta).setBlockData(light);
            lightItem.setItemMeta(itemMeta);
            inv.setItem(index + 9, lightItem);
        }

        private final Material[] materials = {Material.WHITE_CONCRETE, Material.LIGHT_GRAY_CONCRETE, Material.GRAY_CONCRETE, Material.BLACK_CONCRETE, Material.BROWN_CONCRETE, Material.RED_CONCRETE, Material.ORANGE_CONCRETE, Material.YELLOW_CONCRETE, Material.LIME_CONCRETE, Material.GREEN_CONCRETE, Material.CYAN_CONCRETE, Material.LIGHT_BLUE_CONCRETE, Material.BLUE_CONCRETE, Material.PURPLE_CONCRETE, Material.MAGENTA_CONCRETE, Material.PINK_CONCRETE, null, Material.BARRIER};

        private void cuiMaterial(Player player, String subMenu, Type type, Material currentSelection) {
            SWInventory inv = new SWInventory(player, 9 * 2, Core.MESSAGE.parse("WORLDEDIT_CUI_TITLE_SUBMENU", player, Core.MESSAGE.parse(subMenu, player)));
            for (int i = 0; i < materials.length; i++) {
                Material material = materials[i];
                if (material == null) continue;
                inv.setItem(i, new SWItem(material, "", Collections.emptyList(), material == currentSelection, click -> {
                    type.setMaterial(player, material);
                    cuiEditor(player);
                }));
            }
            inv.open();
        }
    }
}
