package de.viper.survivalplus.listeners;

import de.viper.survivalplus.SurvivalPlus;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;

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

public class OreAlarmListener implements Listener {

    private static final long TIME_FRAME_MILLIS = 30 * 1000;

    private final SurvivalPlus plugin;

    private final Map<UUID, Map<Material, OreData>> playerOreData = new HashMap<>();

    private FileConfiguration config;

    // Schwellenwert wird jetzt aus der Config geladen (Fallback DEFAULT_THRESHOLD)
    private int threshold;

    public OreAlarmListener(SurvivalPlus plugin) {
        this.plugin = plugin;
        this.config = plugin.getConfig();
        loadSettings();
    }

    private void loadSettings() {
        this.threshold = config.getInt("ore-alarm.threshold", 10);
    }

    /**
     * Reloadet die Config, lädt die Einstellungen neu und leert gespeicherte Daten.
     */
    public void reloadConfig(FileConfiguration newConfig) {
        this.config = newConfig;
        loadSettings();
        playerOreData.clear();
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        Player player = event.getPlayer();
        Material blockType = event.getBlock().getType();

        if (!isMonitoredOre(blockType)) {
            return;
        }

        UUID playerId = player.getUniqueId();
        long now = System.currentTimeMillis();

        playerOreData.putIfAbsent(playerId, new HashMap<>());
        Map<Material, OreData> oreMap = playerOreData.get(playerId);

        oreMap.putIfAbsent(blockType, new OreData(0, now));
        OreData data = oreMap.get(blockType);

        if (now - data.startTime > TIME_FRAME_MILLIS) {
            data.count = 1;
            data.startTime = now;
        } else {
            data.count++;
        }

        oreMap.put(blockType, data);

        int threshold = calculateDynamicThreshold(playerId, blockType);
        if (data.count >= threshold) {
            String oreName = prettifyMaterialName(blockType);

            String rawMessage = plugin.getLangConfig().getString("orealarm.message",
                    "§c[Erz-Alarm] Spieler §e%player% §chat in %seconds% Sekunden ungewöhnlich viele %ore% abgebaut: §e%count%");

            String message = rawMessage
                    .replace("%player%", player.getName())
                    .replace("%ore%", oreName)
                    .replace("%count%", Integer.toString(data.count))
                    .replace("%seconds%", Long.toString(TIME_FRAME_MILLIS / 1000));

            Bukkit.getOnlinePlayers().stream()
                    .filter(p -> p.isOp() || p.hasPermission("survivalplus.orealarm"))
                    .forEach(p -> p.sendMessage(message));

            data.count = 0;
            data.startTime = now;
        }
    }

    private boolean isMonitoredOre(Material material) {
        switch (material) {
            case DIAMOND_ORE:
            case DEEPSLATE_DIAMOND_ORE:
            case REDSTONE_ORE:
            case DEEPSLATE_REDSTONE_ORE:
            case GOLD_ORE:
            case DEEPSLATE_GOLD_ORE:
            case IRON_ORE:
            case DEEPSLATE_IRON_ORE:
            case LAPIS_ORE:
            case DEEPSLATE_LAPIS_ORE:
            case EMERALD_ORE:
            case DEEPSLATE_EMERALD_ORE:
                return true;
            default:
                return false;
        }
    }

    private int calculateDynamicThreshold(UUID playerId, Material ore) {
        // Nutzt jetzt das geladene threshold, kann später erweitert werden
        return threshold;
    }

    private String prettifyMaterialName(Material material) {
        String name = material.name().toLowerCase();
        name = name.replace("_ore", " Erz");
        name = name.replace("deepslate ", "Tiefgeschichtetes ");
        name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
        return name;
    }

    private static class OreData {
        int count;
        long startTime;

        OreData(int count, long startTime) {
            this.count = count;
            this.startTime = startTime;
        }
    }
}
