package eu.mhsl.minenet.minigames.instance.game.stateless;

import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.message.Countdown;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
import eu.mhsl.minenet.minigames.score.Score;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.Task;
import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType;

import java.time.Duration;
import java.util.concurrent.CompletableFuture;

public class StatelessGame extends Game {
    private final String name;
    private final Score score;
    private Task timeLimitTask;

    private int timeLimit = 0;
    private int timePlayed = 0;

    public StatelessGame(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
        super(dimensionType);
        this.score = score;
        this.name = gameName;
    }

    public Score getScore() {
        return this.score;
    }

    public String getName() {
        return name;
    }

    public void setTimeLimit(int limit) {
        this.timeLimit = limit;
        if(this.timeLimitTask != null) {
            this.timeLimitTask.cancel();
            this.timePlayed = 0;
        }
        if(this.timeLimit > 0) {
            this.timeLimitTask = scheduler().submitTask(() -> {
                if(!isRunning || timeLimit == 0) return TaskSchedule.stop();
                if(timeLimit <= timePlayed) {
                    stop();
                    return TaskSchedule.stop();
                }

                int timeLeft = timeLimit - timePlayed;
                switch (timeLeft) {
                    case 90, 60, 30, 10, 5, 4, 3, 2, 1 ->
                        new ChatMessage(Icon.SCIENCE).appendStatic("Noch " + timeLeft + " Sekunden!").send(getPlayers());
                }

                timePlayed++;

                return TaskSchedule.seconds(1);
            }, ExecutionType.TICK_START);
        }
    }

    @Override
    public void load() {
        super.load();
    }

    /**
     * Displays countdown and starts the game
     * When overriding make sure to call this::start after countdown!
     */
    protected CompletableFuture<Void> countdownStart() {
        return new Countdown(TitleMessage.class)
                .countdown(Audience.audience(getPlayers()), 5, countdownModifier -> countdownModifier.message = new TitleMessage(Duration.ofMillis(300), Duration.ofMillis(700))
                        .subtitle(subtitleMessage -> subtitleMessage.appendStatic(Component.text("in ", NamedTextColor.DARK_GREEN))
                                    .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN))
                                    .appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN))));
    }


    public void startAccessor() {
        this.start();
    }
    @Override
    protected void start() {
        score.setInstance(this);
        score.attachListeners();

        countdownStart().thenRun(super::start);
    }

    @Override
    public void stop() {
        isRunning = false;
        this.onStop();
        getScore().insertRemainingPlayers(getPlayers());
        this.publishScore(getScore());

        countdownUnload();
    }

    private void countdownUnload() {
        new TitleMessage(Duration.ofSeconds(1)).appendTranslated("score#done").send(getPlayers());
        scheduler().scheduleTask(this::unload, TaskSchedule.seconds(5), TaskSchedule.stop());
    }
}
