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

import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.LoginEvent;
import com.velocitypowered.api.proxy.Player;
import de.steamwar.linkage.Linked;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.sql.BannedUserIPs;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.velocitycore.commands.PunishmentCommand;
import net.kyori.adventure.text.event.ClickEvent;

import java.sql.Timestamp;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Linked
public class BanListener extends BasicListener {

    @Subscribe
    public void onLogin(LoginEvent event) {
        Player player = event.getPlayer();
        SteamwarUser user = SteamwarUser.get(player.getUniqueId());
        String ip = IPSanitizer.getTrueAddress(player).getHostAddress();
        if (user.isPunished(Punishment.PunishmentType.Ban)) {
            BannedUserIPs.banIP(user.getId(), ip);
            Chatter.of(event).system(PunishmentCommand.punishmentMessage(user, Punishment.PunishmentType.Ban));
            return;
        }

        List<BannedUserIPs> ips = BannedUserIPs.get(ip);
        if(!ips.isEmpty()){
            Timestamp highestBan = ips.get(0).getTimestamp();
            boolean perma = false;
            for(BannedUserIPs banned : ips) {
                SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
                if (bannedUser.isPunished(Punishment.PunishmentType.Ban)) {
                    Punishment ban = bannedUser.getPunishment(Punishment.PunishmentType.Ban);
                    if(ban.isPerma()) {
                        perma = true;
                        break;
                    }
                    if(ban.getEndTime().after(highestBan))
                        highestBan = ban.getEndTime();
                }
            }
            ClickEvent clickEvent = ClickEvent.runCommand("/ban " + user.getUserName() + " "
                    + (perma ? "perma" : highestBan.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy_HH:mm")))
                    + " Ban Evasion - Bannumgehung");

            Chatter.serverteam().system(
                    "BAN_AVOIDING_ALERT",
                    new Message("BAN_AVOIDING_BAN_HOVER"),
                    clickEvent,
                    user.getUserName(),
                    (Function<Chatter, String>) ((Chatter sender) -> ips.stream().map(banned -> {
                        SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
                        return sender.parseToLegacy("BAN_AVOIDING_LIST", bannedUser.getUserName(),
                                banned.getTimestamp().toLocalDateTime().format(DateTimeFormatter.ofPattern(sender.parseToPlain("TIMEFORMAT"))));
                    }).collect(Collectors.joining(" ")))
            );
        }
    }
}
