package com.playerblocklife;

import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
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.BlockPlaceEvent;

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

/**
 * BlockBreakListener - PlayerBlockLife游戏模式下的方块破坏和放置监听器
 * 
 * <p>监听玩家对生命方块的破坏行为，并在PlayerBlockLife游戏模式下进行相应处理：
 * <ul>
 *   <li>检查被破坏的方块是否为生命方块（羊毛、玻璃、水泥）</li>
 *   <li>验证破坏者是否有权限破坏该方块</li>
 *   <li>更新玩家剩余生命方块数量</li>
 *   <li>处理玩家淘汰逻辑</li>
 *   <li>在游戏未开始时阻止方块破坏</li>
 * </ul>
 * 
 * <p>此监听器与GameStateManager协作，确保游戏规则正确执行。</p>
 * 
 * @author xiaobai
 * @version 2.2.0-1.20.4
 * @since 1.0.0
 */
public class BlockBreakListener implements Listener {
    private final PlayerBlockLife plugin;

    /**
     * 构造一个新的方块破坏监听器
     * 
     * @param plugin 插件主类实例
     */
    public BlockBreakListener(PlayerBlockLife plugin) {
        this.plugin = plugin;
    }

    /**
     * 处理方块被破坏的事件
     * 
     * @param event 方块破坏事件
     */
    @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
    public void onBlockBreak(BlockBreakEvent event) {
        Player breaker = event.getPlayer();
        Block block = event.getBlock();
        Location location = block.getLocation();

        // 检查是否为生命方块（羊毛、玻璃或水泥块）
        if (!isLifeBlockMaterial(block.getType())) {
            return;
        }

        // 检查游戏是否已开始
        if (plugin.getGameStateManager().getCurrentState() != GameStateManager.GameState.STARTED) {
            event.setCancelled(true);
            breaker.sendMessage(org.bukkit.ChatColor.RED + "游戏尚未开始，无法破坏方块！");
            return;
        }

        // 检查是否为玩家的生命方块
        UUID ownerId = getBlockOwner(location);
        if (ownerId == null) {
            return; // 不是生命方块
        }

        if (ownerId.equals(breaker.getUniqueId())) {
            if (breaker.getGameMode() != GameMode.CREATIVE) {
                breaker.sendMessage(org.bukkit.ChatColor.RED + "你不能挖掘自己的生命方块！");
                event.setCancelled(true);
            }
            return;
        }

        if (plugin.getGameStateManager().removeBlock(location, breaker)) {
            int remaining = plugin.getGameStateManager().getRemainingBlocks(ownerId);
            Player owner = Bukkit.getPlayer(ownerId);
            String ownerName = owner != null ? owner.getName() : Bukkit.getOfflinePlayer(ownerId).getName();

            // 通知破坏者
            Map<String, String> variables = new HashMap<>();
            variables.put("owner", ownerName != null ? ownerName : "未知玩家");
            variables.put("remaining", String.valueOf(remaining));
            variables.put("total", String.valueOf(5)); // 使用固定值5，因为配置已移除
            
            breaker.sendMessage(org.bukkit.ChatColor.GREEN + "你破坏了 " + org.bukkit.ChatColor.YELLOW + 
                (ownerName != null ? ownerName : "未知玩家") + org.bukkit.ChatColor.GREEN + " 的生命方块！");
            breaker.sendMessage(org.bukkit.ChatColor.GRAY + "剩余方块: " + org.bukkit.ChatColor.YELLOW + 
                remaining + org.bukkit.ChatColor.GRAY + "/" + org.bukkit.ChatColor.RED + 5);

            if (remaining == 1) {
                breaker.sendMessage(org.bukkit.ChatColor.GOLD + "⚡ 对方只剩最后1个生命方块了！");
                breaker.playSound(breaker.getLocation(),
                        org.bukkit.Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.5f);
            }
            
            // 通知方块所有者
            if (owner != null && owner.isOnline()) {
                owner.sendMessage(org.bukkit.ChatColor.RED + "⚠ 警告！你的生命方块被 " + 
                    org.bukkit.ChatColor.YELLOW + breaker.getName() + org.bukkit.ChatColor.RED + " 破坏了！");
                owner.sendMessage(org.bukkit.ChatColor.GRAY + "剩余方块: " + org.bukkit.ChatColor.YELLOW + 
                    remaining + org.bukkit.ChatColor.GRAY + "/" + org.bukkit.ChatColor.RED + 5);
                
                if (remaining == 0) {
                    owner.sendMessage(org.bukkit.ChatColor.DARK_RED + "☠ 你的所有生命方块已被破坏！你已被淘汰！");
                }
            }
            
            // 广播（如果启用）
            if (plugin.getConfigManager().isBroadcastOnBlockBreak()) {
                int range = plugin.getConfigManager().getBroadcastRange();
                for (Player nearby : breaker.getWorld().getPlayers()) {
                    if (nearby.getLocation().distance(breaker.getLocation()) <= range && 
                        nearby != breaker && (owner == null || nearby != owner)) {
                        nearby.sendMessage(org.bukkit.ChatColor.GOLD + breaker.getName() + 
                            org.bukkit.ChatColor.GRAY + " 破坏了 " + org.bukkit.ChatColor.YELLOW + 
                            (ownerName != null ? ownerName : "某人") + org.bukkit.ChatColor.GRAY + " 的生命方块！");
                    }
                }
            }
        }
    }

    /**
     * 处理方块被放置的事件
     * 
     * @param event 方块放置事件
     */
    @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
    public void onBlockPlace(BlockPlaceEvent event) {
        Player player = event.getPlayer();
        Block block = event.getBlock();

        // 检查是否为生命方块材料
        if (isLifeBlockMaterial(block.getType())) {
            player.sendMessage(org.bukkit.ChatColor.RED + "你不能放置生命方块！");
            event.setCancelled(true);
            return;
        }
    }
    
    /**
     * 检查材料是否为生命方块材料
     */
    private boolean isLifeBlockMaterial(Material material) {
        return material.name().endsWith("_WOOL") || 
               material.name().endsWith("_STAINED_GLASS") || 
               material.name().endsWith("_CONCRETE");
    }
    
    /**
     * 获取方块所有者
     */
    private UUID getBlockOwner(Location location) {
        // 检查是否有任何玩家的方块在此位置
        for (Map.Entry<UUID, java.util.List<Location>> entry : plugin.getGameStateManager().getPlayerBlocks().entrySet()) {
            if (entry.getValue().contains(location)) {
                return entry.getKey();
            }
        }
        return null;
    }
}