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

import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.utils.Message;
import de.steamwar.fightsystem.utils.SWSound;
import de.steamwar.linkage.Linked;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;

import java.util.HashMap;
import java.util.Map;

@Linked
public class WinconditionTimedDamageTechKO extends Wincondition implements PrintableWincondition, Listener {

    private final Map<FightTeam, TechKOCountdown> countdowns = new HashMap<>();

    public WinconditionTimedDamageTechKO() {
        super("TechKO");

        new StateDependentListener(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running, this);
        new StateDependent(Winconditions.TIMED_DAMAGE_TECH_KO, FightState.Running) {
            @Override
            public void enable() {
                Fight.teams().forEach(team -> {
                    TechKOCountdown countdown = new TechKOCountdown(team, Config.TechKoTime);
                    countdowns.put(team, countdown);
                    countdown.enable();
                });
            }

            @Override
            public void disable() {
                countdowns.values().forEach(Countdown::disable);
                countdowns.clear();
            }
        }.register();
    }

    @Override
    public Message getDisplay(FightTeam team) {
        return new Message("BAR_SECONDS", team.getPrefix() + countdowns.get(team).getTimeLeft());
    }

    @EventHandler
    public void onExplode(EntityExplodeEvent e) {
        if (e.getEntityType() != TrickyTrialsWrapper.impl.getTntEntityType())
            return;

        Location location = e.getLocation();
        TechKOCountdown countdown = null;
        FightTeam fightTeam = null;
        for (FightTeam team : Fight.teams()) {
            FightTeam current = Fight.getOpposite(team);
            if (current.getExtendRegion().inRegion(location)) {
                fightTeam = current;
                countdown = countdowns.get(team);
                break;
            }
        }
        if (fightTeam == null) {
            return;
        }

        FightTeam finalFightTeam = fightTeam;
        TechKOCountdown finalCountdown = countdown;
        e.blockList().forEach(block -> {
            if (block.isEmpty()) return;
            if (finalFightTeam.getExtendRegion().inRegion(block)) {
                finalCountdown.disable();
                finalCountdown.enable();
            }
        });
    }

    private class TechKOCountdown extends Countdown {
        private final FightTeam team;

        public TechKOCountdown(FightTeam team, int countdownTime) {
            super(countdownTime, new Message("TECHKO_COUNTDOWN", team.getColoredName()), SWSound.BLOCK_NOTE_PLING, false);
            this.team = team;
        }

        @Override
        public void countdownFinished() {
            win(Fight.getOpposite(team), "WIN_TECHKO", team.getColoredName());
        }
    }
}
