package party.cybsec.griefdetect.modules;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.plugin.java.JavaPlugin;
import party.cybsec.griefdetect.GriefDetectPlugin;
import party.cybsec.griefdetect.core.DetectionEngine;
import party.cybsec.griefdetect.core.DetectionEvent;
import party.cybsec.griefdetect.core.ModuleManager;
import party.cybsec.griefdetect.config.PluginConfig;

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

/**
 * LavaCastDetector module for detecting grief patterns involving lava-water interactions.
 * Tracks cobblestone/stone/obsidian formation with spatial and temporal analysis.
 */
public class LavaCastDetector implements ModuleManager.DetectionModule, Listener {
    
    private final GriefDetectPlugin plugin;
    private final PluginConfig config;
    private final DetectionEngine detectionEngine;
    
    // Module configuration
    private boolean enabled;
    private int minBlockCount;
    private int minDuration;
    private double suppressionThreshold;
    
    public LavaCastDetector(GriefDetectPlugin plugin) {
        this.plugin = plugin;
        this.config = plugin.getPluginConfig();
        this.detectionEngine = plugin.getDetectionEngine();
        
        loadConfiguration();
    }
    
    @Override
    public String getModuleName() {
        return "LavaCastDetector";
    }
    
    @Override
    public void initialize() {
        if (enabled) {
            Bukkit.getPluginManager().registerEvents(this, plugin);
            plugin.getLogger().info("LavaCastDetector initialized");
        }
    }
    
    @Override
    public void reload() {
        loadConfiguration();
        plugin.getLogger().info("LavaCastDetector configuration reloaded");
    }
    
    @Override
    public void shutdown() {
        // No specific cleanup needed, events will be unregistered automatically
        plugin.getLogger().info("LavaCastDetector shutdown");
    }
    
    @Override
    public Map<String, Object> getModuleConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put("enabled", enabled);
        config.put("minBlockCount", minBlockCount);
        config.put("minDuration", minDuration);
        config.put("suppressionThreshold", suppressionThreshold);
        return config;
    }
    
    /**
     * Load module configuration from plugin config.
     */
    private void loadConfiguration() {
        enabled = config.isModuleEnabled("LavaCastDetector");
        minBlockCount = config.getLavaCastMinBlockCount();
        minDuration = config.getLavaCastMinDuration();
        suppressionThreshold = config.getLavaCastSuppressionThreshold();
    }
    
    /**
     * Event handlers for lava-water interactions and block formation.
     */
    
    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
    public void onBlockFromTo(BlockFromToEvent event) {
        if (!enabled) return;
        
        // Capture lava-water interactions
        if (isLavaSource(event.getBlock()) && isWaterTarget(event.getToBlock())) {
            // This event is already handled by DetectionEngine
            // We just need to ensure our module is active
        }
    }
    
    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
    public void onBlockForm(BlockFormEvent event) {
        if (!enabled) return;
        
        // Capture cobblestone/stone/obsidian formation
        String blockType = event.getNewState().getType().name();
        if (isRelevantFormation(blockType)) {
            // This event is already handled by DetectionEngine
            // We just need to ensure our module is active
        }
    }
    
    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
    public void onBlockBreak(BlockBreakEvent event) {
        if (!enabled) return;
        
        // Track mining activity for suppression ratio
        Player player = event.getPlayer();
        Block block = event.getBlock();
        
        // Only track relevant block types for suppression calculation
        String blockType = block.getType().name();
        if (isRelevantFormation(blockType)) {
            // This event is already handled by DetectionEngine
            // We just need to ensure our module is active
        }
    }
    
    /**
     * Helper methods for block type checking.
     */
    
    private boolean isLavaSource(Block block) {
        String type = block.getType().name();
        return type.contains("LAVA") && (type.endsWith("_SOURCE") || type.equals("LAVA"));
    }
    
    private boolean isWaterTarget(Block block) {
        String type = block.getType().name();
        return type.contains("WATER") || type.contains("ICE");
    }
    
    private boolean isRelevantFormation(String blockType) {
        // Only detect cobblestone formation to reduce false positives from natural stone/obsidian
        return blockType.contains("COBBLESTONE");
    }
    
    /**
     * Additional helper methods for cobble generator suppression detection.
     */
    
    /**
     * Check if a cluster shows signs of legitimate cobblestone generator.
     * This would be called during cluster evaluation.
     */
    public boolean isLikelyCobbleGenerator(int blockCount, int minX, int minY, int minZ, 
                                         int maxX, int maxY, int maxZ, int miningActivity) {
        // Small footprint check
        int width = maxX - minX + 1;
        int height = maxY - minY + 1;
        int depth = maxZ - minZ + 1;
        
        if (width > 10 || height > 10 || depth > 10) {
            return false; // Too large for generator
        }
        
        // Stable block count check (minimal mining)
        if (miningActivity > blockCount * 0.1) {
            return false; // Too much mining for generator
        }
        
        // Linear/static geometry check
        int volume = width * height * depth;
        double efficiency = (double) blockCount / volume;
        
        if (efficiency > 0.8) {
            return true; // Very regular shape, likely generator
        }
        
        return false;
    }
}