/*
    This file is a part of the SteamWar software.

    Copyright (C) 2022  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.fightsystem.fight;

import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.ClickEvent;
import org.bukkit.entity.Player;

import java.util.*;
import java.util.stream.Collectors;

public class JoinRequest {

    private static final Map<Player, JoinRequest> activeRequests = new HashMap<>();

    public static List<SWListInv.SWListEntry<Player>> openRequests(Player p, FightTeam team) {
        return activeRequests.values().stream().filter(
                request -> request.waitOnApproval.contains(team)
        ).map(request -> {
            SWItem item = SWItem.getPlayerSkull(request.player);
            item.setLore(Arrays.asList(
                    FightSystem.getMessage().parse("REQUESTS_LEFT_CLICK", p),
                    FightSystem.getMessage().parse("REQUESTS_RIGHT_CLICK", p)
            ));
            return new SWListInv.SWListEntry<>(item, request.player);
        }).collect(Collectors.toList());
    }

    public static void clearRequests() {
        activeRequests.clear();
    }

    public static JoinRequest get(Player player) {
        return activeRequests.get(player);
    }

    private final Player player;
    private final FightTeam team;
    private final Set<FightTeam> waitOnApproval;

    public JoinRequest(Player player, FightTeam team) {
        this.player = player;
        this.team = team;
        this.waitOnApproval = new HashSet<>(FightState.ingame() ? Fight.teams() : Collections.singleton(team));
        Set<FightTeam> alreadyAccepted = new HashSet<>();

        activeRequests.put(player, this);
        for(FightTeam t : waitOnApproval) {
            FightPlayer leader = t.getLeader();
            if(leader == null)
                continue;

            if(leader.getEntity() == null)
                continue;

            leader.ifPlayer(leaderPlayer -> FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_NOTIFICATION", leaderPlayer, "REQUESTS", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/requests"), player.getName(), team.getColoredName()));
            leader.ifAI(ai -> {
                if(ai.acceptJoinRequest(player, team))
                    alreadyAccepted.add(t);
            });
        }

        FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_CONFIRMATION", player, ChatMessageType.ACTION_BAR);
        alreadyAccepted.forEach(this::accept);
    }

    public boolean required(FightTeam decider) {
        return waitOnApproval.contains(decider);
    }

    public void accept(FightTeam acceptor) {
        waitOnApproval.remove(acceptor);

        if(waitOnApproval.isEmpty()) {
            team.addMember(player);
            activeRequests.remove(player);
        }
    }

    public void decline(FightTeam declinor) {
        FightSystem.getMessage().sendPrefixless("REQUEST_YOUR_DECLINED", player, ChatMessageType.ACTION_BAR);
        waitOnApproval.forEach(t -> t.broadcast("REQUEST_DECLINED", player.getName()));
        silentDecline();
    }

    public void silentDecline() {
        activeRequests.remove(player);
    }
}
