package de.viper.survivalplus.tasks;

import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.*;

public class AFKManager {

    private final Plugin plugin;
    private final long afkAfterMillis;
    private final long kickAfterMillis;
    private final long joinGracePeriodMillis = 5000; // 5 Sekunden Schonfrist

    private final Map<UUID, Long> lastActivity = new HashMap<>();
    private final Map<UUID, Long> joinTimes = new HashMap<>();
    private final Set<UUID> afkPlayers = new HashSet<>();
    private final Map<UUID, BossBar> bossBars = new WeakHashMap<>();
    private final Map<UUID, Integer> colorIndex = new HashMap<>();
    private final Map<UUID, BukkitRunnable> colorTasks = new HashMap<>();

    private final List<BarColor> colorCycle = List.of(
            BarColor.RED, BarColor.YELLOW, BarColor.GREEN,
            BarColor.BLUE, BarColor.PURPLE, BarColor.PINK
    );

    public AFKManager(Plugin plugin, long afkAfterSeconds, long kickAfterSeconds) {
        this.plugin = plugin;
        this.afkAfterMillis = afkAfterSeconds * 1000;
        this.kickAfterMillis = kickAfterSeconds * 1000;
    }

    public void updateActivity(Player player) {
        UUID uuid = player.getUniqueId();
        long now = System.currentTimeMillis();
        lastActivity.put(uuid, now);
        // Optional: Schonfrist erneuern
        joinTimes.put(uuid, now);
        if (afkPlayers.remove(uuid)) {
            removeAFKBossBar(player);
            plugin.getLogger().fine("AFK-Status entfernt für " + player.getName());
        }
    }

    public void reset(Player player) {
        UUID uuid = player.getUniqueId();
        lastActivity.remove(uuid);
        joinTimes.remove(uuid);
        afkPlayers.remove(uuid);
        removeAFKBossBar(player);
    }

    public boolean isAFK(Player player) {
        return afkPlayers.contains(player.getUniqueId());
    }

    public void checkAFKStatus(Player player) {
        UUID uuid = player.getUniqueId();
        long currentTime = System.currentTimeMillis();

        // Schonfrist nach Join
        if (joinTimes.containsKey(uuid) && (currentTime - joinTimes.get(uuid) < joinGracePeriodMillis)) {
            return;
        }

        // Kreativ- oder Zuschauermodus ausschließen
        if (player.getGameMode() == GameMode.CREATIVE ||
            player.getGameMode() == GameMode.SPECTATOR) {
            return;
        }

        if (!lastActivity.containsKey(uuid)) {
            lastActivity.put(uuid, currentTime);
            return;
        }

        long diff = currentTime - lastActivity.get(uuid);

        if (diff >= afkAfterMillis) {
            if (afkPlayers.add(uuid)) {
                showAFKBossBar(player, "§cDu bist AFK!");
            }
            if (kickAfterMillis > 0 && diff >= kickAfterMillis) {
                plugin.getLogger().info("Spieler " + player.getName() + " wird wegen AFK gekickt. Inaktiv seit: " + (diff / 1000) + " Sekunden");
                player.kickPlayer("§cDu wurdest wegen AFK gekickt.");
                removeAFKBossBar(player);
            }
        } else if (afkPlayers.remove(uuid)) {
            removeAFKBossBar(player);
        }
    }

    public void showAFKBossBar(Player player, String message) {
        UUID uuid = player.getUniqueId();
        removeAFKBossBar(player); // nur eine BossBar pro Spieler

        BossBar bar = Bukkit.createBossBar(message, BarColor.YELLOW, BarStyle.SOLID, BarFlag.CREATE_FOG);
        bar.addPlayer(player);
        bar.setVisible(true);

        bossBars.put(uuid, bar);
        colorIndex.put(uuid, 0);

        // ggf. alten Farbwechsel-Task stoppen
        if (colorTasks.containsKey(uuid)) {
            colorTasks.get(uuid).cancel();
            colorTasks.remove(uuid);
        }

        // Farben wechseln
        BukkitRunnable task = new BukkitRunnable() {
            @Override
            public void run() {
                BossBar activeBar = bossBars.get(uuid);
                if (activeBar == null) {
                    this.cancel();
                    colorTasks.remove(uuid);
                    return;
                }
                int index = colorIndex.getOrDefault(uuid, 0);
                activeBar.setColor(colorCycle.get(index));
                colorIndex.put(uuid, (index + 1) % colorCycle.size());
            }
        };
        task.runTaskTimer(plugin, 0L, 20L);
        colorTasks.put(uuid, task);
    }

    public void removeAFKBossBar(Player player) {
        UUID uuid = player.getUniqueId();
        if (colorTasks.containsKey(uuid)) {
            colorTasks.get(uuid).cancel();
            colorTasks.remove(uuid);
        }
        BossBar bar = bossBars.remove(uuid);
        if (bar != null) {
            bar.removeAll();
        }
        colorIndex.remove(uuid);
    }
}
