/*
 *   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.PostLoginEvent;
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player;
import de.steamwar.linkage.EventMode;
import de.steamwar.linkage.Linked;
import de.steamwar.messages.Chatter;
import de.steamwar.persistent.Subserver;
import de.steamwar.sql.*;
import de.steamwar.velocitycore.EventStarter;
import de.steamwar.velocitycore.VelocityCore;
import net.kyori.adventure.key.Key;

import java.net.InetSocketAddress;
import java.util.List;

@Linked
@EventMode(true)
public class EventModeListener extends BasicListener {

    public static final Key EVENT_TO_SPECTATE_KEY = Key.key("sw", "event_to_spectate");

    @Subscribe
    public void onPostLogin(PostLoginEvent e) {
        Player player = e.getPlayer();
        SteamwarUser user = SteamwarUser.get(player.getUniqueId());
        Chatter sender = Chatter.disconnect(player);

        Event event = Event.get();
        if (event == null) {
            if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_5)) {
                sender.system("EVENTMODE_KICK");
            } else {
                player.transferToHost(new InetSocketAddress("steamwar.de", 25565));
            }
            return;
        }

        if (TeamTeilnahme.nimmtTeil(user.getTeam(), event.getEventID())) {
            if (player.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_20_5) && VelocityCore.getProxy().getAllPlayers().stream().map(p -> SteamwarUser.get(p.getUniqueId())).filter(u -> u.getTeam() == user.getTeam()).count() > event.getMaximumTeamMembers()) {
                player.storeCookie(EVENT_TO_SPECTATE_KEY, "TRUE".getBytes());
                player.transferToHost(new InetSocketAddress("steamwar.de", 25565));
                return;
            }

            Subserver server = EventStarter.getEventServer().get(user.getTeam());

            if (server != null) {
                server.sendPlayer(player);
            }

            return;
        }

        if (Referee.get(event.getEventID()).contains(user.getId())) return;

        if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_5)) {
            sender.system("EVENTMODE_KICK");
        } else {
            player.transferToHost(new InetSocketAddress("steamwar.de", 25565));
        }
    }

    @Subscribe
    public void onLobby(ServerConnectedEvent e) {
        Player player = e.getPlayer();

        if (player.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_5)) {
            return;
        }

        SteamwarUser user = SteamwarUser.get(player.getUniqueId());
        Event event = Event.get();
        if (event != null && Referee.get(event.getEventID()).contains(user.getId())) return;

        List<EventFight> activeFights = EventFight.getActiveFights();

        if (activeFights.stream()
                .noneMatch(fight -> fight.getTeamRed() == user.getTeam() || fight.getTeamBlue() == user.getTeam())) {
            player.transferToHost(new InetSocketAddress("steamwar.de", 25565));
        }
    }
}
