package eu.mhsl.minenet.minigames.score.tournament;

import eu.mhsl.minenet.minigames.score.Score;
import net.minestom.server.entity.Player;

import java.util.*;

public class Tournament {
    private final List<Score> gameScores = new ArrayList<>();
    private RewardConfiguration rewardConfiguration;
    private MemorialConfiguration memorialConfiguration;

    public void addScore(Score score) {
        this.gameScores.add(score);
    }

    public int getScoreCount() {
        return this.gameScores.size();
    }

    public void reset() {
        this.gameScores.clear();
    }


    public Map<Player, Integer> getGameScores() {
        Map<Player, Integer> data = new HashMap<>();
        gameScores.forEach(game -> {
            int count = 0;
            for (Set<Player> players : game.getScores()) {
                count++;
                for (Player player : players) {
                    int points = (game.getScores().size() - count) + boost(count, game.getScores().size());

                    data.computeIfPresent(player, (existingPlayer, existingPoints) -> existingPoints + points);
                    data.computeIfAbsent(player, newPlayer -> points);
                }
            }
        });
        return data;
    }

    public Rewards getRewards() {
        Map<UUID, Integer> itemCount = new HashMap<>();
        int count = 0;
        for (Player player : getPlaces()) {
            if(count >= this.rewardConfiguration.rewardCount().size()) break;
            itemCount.put(player.getUuid(), this.rewardConfiguration.rewardCount().get(count));
            count++;
        }

        return new Rewards(
                this.memorialConfiguration.memorialMaterial().namespace().value(),
                this.memorialConfiguration.memorialTitle(),
                this.memorialConfiguration.memorialLore(),
                getPlaces().stream().map(Player::getUuid).toList(),
                this.rewardConfiguration.item().namespace().value(),
                itemCount
        );
    }

    public List<Player> getPlaces() {
        List<Player> players = new ArrayList<>(
                getGameScores().entrySet().stream()
                    .sorted(Map.Entry.comparingByValue())
                    .map(Map.Entry::getKey)
                    .toList()
        );

        Collections.reverse(players);
        return players;
    }

    private int boost(int selfPlace, int placeCount) {
        return switch (selfPlace) {
            case 0 -> placeCount / 3;
            case 1 -> placeCount / 4;
            case 2 -> placeCount / 5;
            default -> 0;
        };
    }

    public void setRewardConfiguration(RewardConfiguration rewardConfiguration) {
        this.rewardConfiguration = rewardConfiguration;
    }

    public void setMemorialConfiguration(MemorialConfiguration memorialConfiguration) {
        this.memorialConfiguration = memorialConfiguration;
    }
}
