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

import com.velocitypowered.api.proxy.Player;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.Mod;
import de.steamwar.sql.Mod.ModType;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.commands.PunishmentCommand;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import net.kyori.adventure.text.Component;

import java.sql.Timestamp;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.stream.Collectors;

@UtilityClass
public class ModUtils {

    @Getter
    private static final Map<UUID, List<Mod>> playerModMap = new HashMap<>();

    public static boolean handleMods(Player player, List<Mod> mods) {
        return handleMods(player.getUniqueId(), Chatter.of(player).getLocale(), player::disconnect, mods);
    }

    public static boolean handleMods(UUID uuid, Locale locale, Consumer<Component> disconnect, List<Mod> mods) {
        Chatter sender = Chatter.of(uuid);
        SteamwarUser user = sender.user();
        playerModMap.put(uuid, new ArrayList<>(mods));
        VelocityCore.getLogger().log(Level.INFO, "%s declares mods: %s".formatted(user.getUserName(), mods.stream().map(mod -> mod.getPlatform() + ":" + mod.getModName()).collect(Collectors.joining(" "))));

        ModType max = ModType.YELLOW;
        Iterator<Mod> it = mods.iterator();
        while (it.hasNext()) {
            Mod mod = it.next();
            if (mod.getModType() == ModType.UNKLASSIFIED || mod.getModType() == ModType.GREEN || (mod.getModType() == ModType.YOUTUBER_ONLY && user.hasPerm(UserPerm.RESTRICTED_MODS))) {
                it.remove();
            } else if (mod.getModType() == ModType.RED) {
                max = ModType.RED;
            }
        }

        if (mods.isEmpty()) {
            return true;
        }


        ModType finalMax = max;
        String modList = mods.stream().filter(mod -> finalMax == ModType.YELLOW || mod.getModType() == ModType.RED).map(Mod::getModName).collect(Collectors.joining("\n"));
        String message;

        if (mods.size() == 1) {
            message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", modList);
        } else {
            message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", modList);
        }

        if (max == ModType.RED) {
            user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, -1, false);
            PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.byId(-1), false);
            VelocityCore.getLogger().log(Level.SEVERE, "%s %s wurde automatisch wegen der Mods %s gebannt.".formatted(user.getUserName(), user.getId(), modList));
        }

        disconnect.accept(Chatter.SERIALIZER.deserialize(message));
        return false;
    }
}
