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

import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import de.steamwar.bausystem.utils.tps.TPSFreezeUtils;
import de.steamwar.bausystem.utils.tps.TPSLimitUtils;
import de.steamwar.core.TPSWarpUtils;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class TickManager15 implements TickManager, Listener {

    private static float currentTPSLimit = 20;
    private boolean currentlyStepping = false;
    private float currentLimit;
    private int stepsTotal;
    private int stepsLeft;

    @Override
    public boolean canFreeze() {
        return TPSFreezeUtils.isCanFreeze();
    }

    @Override
    public void setTickRate(float tickRate) {
        if (currentlyStepping) {
            currentlyStepping = false;
            Bukkit.getOnlinePlayers().forEach(player -> {
                BossBarService.instance.remove(player, Region.getGlobalRegion(), "TickStep");
            });
        }
        TPSWarpUtils.warp(tickRate);
        if (currentTPSLimit == 0 && tickRate != 0) {
            TPSFreezeUtils.unfreeze();
        }
        currentTPSLimit = tickRate;
        if (tickRate == 0) {
            TPSLimitUtils.unlimit();
            TPSFreezeUtils.freeze();
        } else if (tickRate < 20.0) {
            TPSLimitUtils.limit(tickRate);
        } else if (tickRate >= 20) {
            TPSLimitUtils.unlimit();
        }
    }

    @Override
    public boolean isFrozen() {
        return TPSFreezeUtils.frozen();
    }

    @Override
    public void setFreeze(boolean freeze) {
        if (freeze) {
            setTickRate(0);
        }
    }

    @Override
    public void stepTicks(int ticks) {
        currentLimit = 0;
        setTickRate(20);
        stepsLeft = ticks;
        stepsTotal = ticks;
        currentlyStepping = true;
    }

    @Override
    public void sprintTicks(int ticks) {
        currentLimit = currentTPSLimit;
        setTickRate(4000);
        stepsLeft = ticks;
        stepsTotal = ticks;
        currentlyStepping = true;
    }

    @Override
    public boolean isSprinting() {
        return currentlyStepping && currentTPSLimit > 20;
    }

    @Override
    public boolean isStepping() {
        return currentlyStepping && currentTPSLimit <= 20;
    }

    @Override
    public float getTickRate() {
        return currentTPSLimit;
    }

    @Override
    public void setBlockTpsPacket(boolean block) {

    }

    @Override
    public long getTotalTicks() {
        return stepsTotal;
    }

    @Override
    public long getDoneTicks() {
        return stepsTotal - stepsLeft;
    }

    @Override
    public long getRemainingTicks() {
        return stepsLeft;
    }

    @EventHandler
    public void onTickEnd(TickEndEvent event) {
        if (!currentlyStepping) return;
        stepsLeft--;
        if (stepsLeft <= 0) {
            setTickRate(currentLimit);
        }
    }
}
