/*
 *   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.velocitycore.commands;

import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.Mod;
import de.steamwar.sql.UserPerm;
import de.steamwar.velocitycore.inventory.SWInventory;
import de.steamwar.velocitycore.inventory.SWItem;
import de.steamwar.velocitycore.inventory.SWListInv;
import de.steamwar.velocitycore.inventory.SWStreamInv;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;

@Linked
public class ModCommand extends SWCommand {

    public ModCommand() {
        super("mod", UserPerm.MODERATION, "mods");
    }

    public static final Map<UUID, Mod.ModType> playerFilterType = new HashMap<>();

    @Register
    public void mods(PlayerChatter sender) {
        playerFilterType.putIfAbsent(sender.getPlayer().getUniqueId(), Mod.ModType.UNKLASSIFIED);
        openGui(sender);
    }

    private void openGui(PlayerChatter player) {
        SWStreamInv<Mod> swStreamInv = new SWStreamInv<>(player, new Message("MOD_COMMAND_GUI_TITLE"), (click, mod) -> openTypeGUI(player, "MOD_COMMAND_CLASSICIATION_GUI", type -> {
            mod.setModType(type);
            SWInventory.close(player);
            openGui(player);
        }), page -> {
            Mod.ModType filtertype = playerFilterType.get(player.user().getUUID());
            return Mod.getAllModsFiltered(page, 45, filtertype).stream().map(mod -> new SWListInv.SWListEntry<>(new SWItem("NAME_TAG", new Message("PLAIN_STRING", mod.getModName())).addLore(new Message("PLAIN_STRING", mod.getPlatform().name())), mod)).toList();
        });

        swStreamInv.addItem(52, new SWItem("NAME_TAG", new Message("MOD_TITLE_FILTER")), click -> {
            swStreamInv.close();
            openTypeGUI(player, "MOD_TITLE_FILTER", type -> playerFilterType.replace(player.user().getUUID(), type));
        });

        swStreamInv.open();
    }

    private void openTypeGUI(PlayerChatter player, String title, Consumer<Mod.ModType> function) {
        SWInventory inv = new SWInventory(player, 9, new Message(title));

        inv.addItem(1, new SWItem("GRAY_DYE", new Message("MOD_UNCLASSIFIED")), click -> function.accept(Mod.ModType.UNKLASSIFIED));
        inv.addItem(2, new SWItem("GREEN_DYE", new Message("MOD_ALLOWED")), click -> function.accept(Mod.ModType.GREEN));
        inv.addItem(3, new SWItem("YELLOW_DYE", new Message("MOD_FORBIDDEN")), click -> function.accept(Mod.ModType.YELLOW));
        inv.addItem(4, new SWItem("RED_DYE", new Message("MOD_AUTOBAN")), click -> function.accept(Mod.ModType.RED));
        inv.addItem(5, new SWItem("MAGENTA_DYE", new Message("MOD_YT")), click -> function.accept(Mod.ModType.YOUTUBER_ONLY));

        inv.addItem(8, new SWItem("ARROW", new Message("MOD_ITEM_BACK")), click -> {
            inv.close();
            openGui(player);
        });

        inv.open();
    }

    @Register(value = {"set"}, description = "MOD_COMMAND_SET_USAGE")
    public void set(Chatter sender, String modName, Mod.Platform platform, Mod.ModType newModType) {
        Mod mod = Mod.get(modName, platform);
        if (mod == null) {
            sender.system("MOD_COMMAND_NOT_FOUND_IN_DATABASE", modName, platform.name());
            return;
        }

        mod.setModType(newModType);
        sender.system("MOD_CHANGED_TYPE", modName, platform.name(), newModType.name());
    }

    @Register(value = {"get"}, description = "MOD_COMMAND_GET_USAGE")
    public void get(Chatter sender, String modName, Mod.Platform platform) {
        Mod mod = Mod.get(modName, platform);
        if (mod == null) {
            sender.system("MOD_COMMAND_NOT_FOUND_IN_DATABASE", modName, platform.name());
            return;
        }

        sender.system("MOD_COMMAND_INFO", modName, platform.name(), mod.getModType().name());
    }

    @Register(value = {"next"})
    public void next(Chatter sender) {
        Mod mod = Mod.findFirstMod();
        if (mod == null) {
            sender.system("MOD_NO_MORE_UNCLASSIFIED_MODS");
            return;
        }

        sender.system("MOD_FOUND_NEXT_MOD", mod.getModName(), mod.getPlatform().name());
    }
}
