/*
 *   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.bausystem.features.slaves.laufbau;

import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.data.CMDs;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.*;

public class LaufbauSettings {

    private static Map<Pair<Material, String>, List<BlockBoundingBox>> groupMap = new LinkedHashMap<>();

    static {
        BlockBoundingBox.elements.forEach(blockBoundingBox -> {
            if (blockBoundingBox.getSwItem() == null) return;
            String displayName = blockBoundingBox.getSwItem().getItemMeta().getDisplayName();
            groupMap.computeIfAbsent(new Pair<>(blockBoundingBox.getSwItem().getItemStack().getType(), displayName), k -> new ArrayList<>()).add(blockBoundingBox);
        });
    }

    private Player p;

    public LaufbauSettings(Player p) {
        this.p = p;
        open();
    }

    public void open() {
        List<SWListInv.SWListEntry<Map.Entry<Pair<Material, String>, List<BlockBoundingBox>>>> list = new ArrayList<>();
        for (Map.Entry<Pair<Material, String>, List<BlockBoundingBox>> entry : groupMap.entrySet()) {
            SWItem swItem = createItem(entry.getKey().getKey(), entry.getKey().getValue(), entry.getValue());
            list.add(new SWListInv.SWListEntry<>(swItem, entry));
        }
        SWListInv<Map.Entry<Pair<Material, String>, List<BlockBoundingBox>>> inv = new SWListInv<>(p, BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_GUI_NAME", p), false, list, (clickType, entry) -> {
            if (entry.getValue().size() == 1) {
                LaufbauUtils.toggle(p, entry.getValue().get(0));
                open();
                return;
            }
            if (clickType.isLeftClick()) {
                open(entry.getKey());
                return;
            }
            toggle(entry.getValue());
            open();
        });
        inv.open();
    }

    public void open(Pair<Material, String> key) {
        List<BlockBoundingBox> blockBoundingBoxes = groupMap.get(key);
        List<SWListInv.SWListEntry<BlockBoundingBox>> list = new ArrayList<>();
        for (BlockBoundingBox bb : blockBoundingBoxes) {
            SWItem swItem = LaufbauUtils.translateItem(bb.getSwItem(), p);
            ItemMeta itemMeta = swItem.getItemMeta();
            List<String> lore = new ArrayList<>();
            if (itemMeta.getLore() != null) {
                lore = itemMeta.getLore();
            }
            lore.add("");
            lore.add(BauSystem.MESSAGE.parse(LaufbauUtils.isDeactivated(p, bb) ? "LAUFBAU_SETTINGS_INACTIVE" : "LAUFBAU_SETTINGS_ACTIVE", p));
            itemMeta.setLore(lore);
            swItem.setItemMeta(itemMeta);
            list.add(new SWListInv.SWListEntry<>(swItem, bb));
        }
        SWListInv<BlockBoundingBox> inv = new SWListInv<>(p, BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_GUI_NAME", p), false, list, (clickType, blockBoundingBox) -> {
            LaufbauUtils.toggle(p, blockBoundingBox);
            open(key);
        });
        inv.setItem(49, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_GUI_BACK", p), clickType -> {
            open();
        }).setCustomModelData(CMDs.BACK));
        inv.open();
    }

    public SWItem createItem(Material material, String group, List<BlockBoundingBox> blockBoundingBoxes) {
        if (blockBoundingBoxes.size() == 1) {
            BlockBoundingBox bb = blockBoundingBoxes.get(0);
            SWItem swItem = LaufbauUtils.translateItem(bb.getSwItem(), p);
            ItemMeta itemMeta = swItem.getItemMeta();
            List<String> lore = new ArrayList<>();
            if (itemMeta.getLore() != null) {
                lore = itemMeta.getLore();
            }
            lore.add("");
            lore.add(BauSystem.MESSAGE.parse(LaufbauUtils.isDeactivated(p, bb) ? "LAUFBAU_SETTINGS_INACTIVE" : "LAUFBAU_SETTINGS_ACTIVE", p));
            lore.add("");
            lore.add(BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p));
            itemMeta.setLore(lore);
            swItem.setItemMeta(itemMeta);
            return swItem;
        } else {
            long count = blockBoundingBoxes.stream().filter(bb -> LaufbauUtils.isDeactivated(p, bb)).count();
            if (count == 0) {
                return new SWItem(material, BauSystem.MESSAGE.parse(group, p), Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ACTIVE", p), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {
                });
            }
            if (count == blockBoundingBoxes.size()) {
                return new SWItem(material, BauSystem.MESSAGE.parse(group, p), Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_INACTIVE", p), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {
                });
            }
            return new SWItem(material, BauSystem.MESSAGE.parse(group, p), Arrays.asList("", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_MIXED", p, blockBoundingBoxes.size() - count, blockBoundingBoxes.size()), "", BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_ADVANCED", p), BauSystem.MESSAGE.parse("LAUFBAU_SETTINGS_TOGGLE", p)), false, clickType -> {
            });
        }
    }

    public void toggle(List<BlockBoundingBox> blockBoundingBoxes) {
        long count = blockBoundingBoxes.stream().filter(bb -> LaufbauUtils.isDeactivated(p, bb)).count();
        if (count != blockBoundingBoxes.size()) {
            blockBoundingBoxes.forEach(bb -> {
                if (!LaufbauUtils.isDeactivated(p, bb)) {
                    LaufbauUtils.toggle(p, bb);
                }
            });
        } else {
            blockBoundingBoxes.forEach(bb -> {
                LaufbauUtils.toggle(p, bb);
            });
        }
    }
}
