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

import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.utils.FightUI;
import de.steamwar.fightsystem.utils.Message;
import de.steamwar.fightsystem.utils.SWSound;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;

import java.util.ArrayList;
import java.util.List;

public abstract class Countdown {

    private static final List<Countdown> currentCountdowns = new ArrayList<>();

    protected final Message appendix;

    private final int totalTime;
    protected final Sound sound;
    private final boolean level;

    protected int time;
    private BukkitTask task = null;

    public abstract void countdownFinished();

    protected Countdown(int time, Message appendix, SWSound sound, boolean level) {
        this.totalTime = time;
        this.time = time;
        this.appendix = appendix;
        this.sound = sound != null ? sound.getSound() : null;
        this.level = level;
    }

    public void enable() {
        time = totalTime;
        task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::count, 20, 20);
        currentCountdowns.add(this);
        show();
    }

    public void disable() {
        if(task != null){
            task.cancel();
            currentCountdowns.remove(this);
            task = null;
        }
    }

    public static void skip(){
        if(currentCountdowns.isEmpty())
            return;

        int smallestTime = currentCountdowns.get(0).time;
        for(Countdown countdown : currentCountdowns){
            if(countdown.time < smallestTime)
                smallestTime = countdown.time;
        }

        for(Countdown countdown : new ArrayList<>(currentCountdowns)) {
            countdown.time -= smallestTime;
            countdown.show();
        }

        FightUI.addSubtitle("UI_SKIP");
    }

    public static void sendCountdownMessage(Player p, String message, int displaytime, Message appendix) {
        FightSystem.getMessage().sendPrefixless(message, p, ChatMessageType.ACTION_BAR, displaytime, FightSystem.getMessage().parse(appendix.getMsg(), p, appendix.getParams()));
    }

    protected void broadcast(String message, int divisor){
        if(this.sound != null && divisor == 1)
            Fight.playSound(this.sound, 100.0F, 1.0F);

        GlobalRecorder.getInstance().countdown(message, time / divisor, appendix);
        Bukkit.getOnlinePlayers().forEach(p -> sendCountdownMessage(p, message, time / divisor, appendix));
    }

    public int getTimeLeft(){
        return time;
    }

    private void count() {
        time--;
        show();
    }

    private void show(){
        switch (time) {
            case 900: case 600: case 300: case 180: case 120:
                broadcast("COUNTDOWN_MINUTES", 60);
                break;
            case 60: case 30: case 20: case 15: case 10: case 5: case 4: case 3: case 2:
                broadcast("COUNTDOWN_SECONDS", 1);
                break;
            case 1:
                broadcast("COUNTDOWN_SECOND", 1);
                break;
            case 0:
                if(this.sound != null)
                    Fight.playSound(this.sound, 100.0F, 2.0F);

                disable();
                countdownFinished();
                break;
            default:
        }

        if(this.level)
            Bukkit.getServer().getOnlinePlayers().forEach(player -> player.setLevel(time));
    }
}
