package com.playerblocklife;

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.logging.Level;

/**
 * PlayerBlockLife插件主类 - PlayerBlockLife生存游戏模式的核心控制器
 * 
 * <p>这个插件为Minecraft服务器添加了一个独特的生存游戏模式：每个非OP玩家拥有一定数量的生命方块，
 * 这些方块使用不同颜色的羊毛、玻璃或水泥方块表示。当其他玩家挖光某个玩家的所有生命方块时，该玩家会被淘汰。
 * 游戏需要管理员使用/pbl start命令开始，支持限时模式，最后存活的玩家获胜。</p>
 * 
 * <p>主要功能：</p>
 * <ul>
 *   <li>管理PlayerBlockLife游戏的完整生命周期（等待、进行、结束）</li>
 *   <li>为非OP玩家分配独特的颜色生命方块</li>
 *   <li>处理生命方块的生成和销毁</li>
 *   <li>监控游戏状态和玩家存活情况</li>
 *   <li>提供PlayerBlockLife专用命令系统（/pbl start, /pbl rstgm）</li>
 *   <li>支持游戏计分板显示</li>
 *   <li>管理员可使用传统命令进行管理</li>
 * </ul>
 * 
 * @author xiaobai
 * @version 2.2.0-1.20.4
 * @since 1.0.0
 */
public class PlayerBlockLife extends JavaPlugin {
    private static PlayerBlockLife instance;
    private PlayerBlockManager blockManager;
    private SkinManager skinManager;
    private LifeSystem lifeSystem;
    private ConfigManager configManager;
    private MessageManager messageManager;
    private GameStateManager gameStateManager;

    /**
     * 插件启用时调用，执行初始化操作
     * 
     * <p>初始化流程：
     * <ol>
     *   <li>保存默认配置文件</li>
     *   <li>初始化所有管理器（注意依赖顺序）</li>
     *   <li>加载配置和消息数据</li>
     *   <li>注册事件监听器</li>
     *   <li>注册命令执行器</li>
     *   <li>加载玩家数据和皮肤缓存</li>
     *   <li>启动定时任务</li>
     * </ol>
     * 
     * @see #onDisable()
     */
    @Override
    public void onEnable() {
        instance = this;

        // 第一步：保存默认配置
        saveDefaultConfig();

        // 第二步：初始化管理器（注意顺序！）
        this.configManager = new ConfigManager(this);
        this.messageManager = new MessageManager(this);
        this.skinManager = new SkinManager(this);
        this.blockManager = new PlayerBlockManager(this, skinManager);
        this.lifeSystem = new LifeSystem(this);

        // 第三步：加载数据（必须在管理器初始化之后）
        this.configManager.loadConfig();
        this.messageManager.loadMessages();

        // 第四步：注册事件监听器
        getServer().getPluginManager().registerEvents(new BlockBreakListener(this), this);
        getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this);
        getServer().getPluginManager().registerEvents(new PlayerQuitListener(this), this);

        // 第五步：注册命令
        getCommand("setlifeblocks").setExecutor(new SetLifeBlocksCommand(this));
        getCommand("checklifeblocks").setExecutor(new CheckLifeBlocksCommand(this));
        getCommand("pblreload").setExecutor(new AdminCommands(this));
        getCommand("pbldelete").setExecutor(new AdminCommands(this));
        getCommand("pblrevive").setExecutor(new AdminCommands(this));
        getCommand("pblstats").setExecutor(new AdminCommands(this));
        getCommand("pbl").setExecutor(new PBLCommands(this));

        // 第六步：初始化游戏状态管理器（先于其他数据加载）
        this.gameStateManager = new GameStateManager(this);

        // 第七步：加载其他数据
        // 注意：在新模式下，我们不再使用原有的blockManager和skinManager
        // 因此不再调用blockManager.loadData()和skinManager.loadAllSkins()

        // 第八步：启动定时任务
        startScheduler();

        getLogger().info("§a========================================");
        getLogger().info("§ePlayerBlockLife v" + getDescription().getVersion() + " 已启用");
        getLogger().info("§e作者: " + getDescription().getAuthors());
        getLogger().info("§a========================================");
    }

    /**
     * 插件禁用时调用，执行清理操作
     * 
     * <p>执行以下清理操作：
     * <ul>
     *   <li>保存玩家方块数据到文件</li>
     *   <li>保存皮肤缓存数据</li>
     *   <li>记录插件禁用日志</li>
     * </ul>
     * 
     * @see #onEnable()
     */
    @Override
    public void onDisable() {
        // 保存数据
        if (blockManager != null) {
            blockManager.saveData();
        }
        if (skinManager != null) {
            skinManager.saveSkinData();
        }
        getLogger().info("§cPlayerBlockLife 插件已禁用");
    }

    /**
     * 重写 reloadConfig 方法，避免循环依赖
     */
    @Override
    public void reloadConfig() {
        // 只调用父类的reloadConfig，不调用configManager的方法
        super.reloadConfig();
        getLogger().info("基础配置文件已重新加载");
    }

    /**
     * 插件的完整重载方法（用于命令）
     * 
     * <p>重新加载所有插件配置和数据，包括：
     * <ul>
     *   <li>主配置文件 (config.yml)</li>
     *   <li>消息配置文件 (messages.yml)</li>
     *   <li>玩家方块数据</li>
     *   <li>皮肤缓存数据</li>
     * </ul>
     * 
     * <p>这个方法通常由管理员通过/pblreload命令调用。</p>
     */
    public void reloadPluginConfig() {
        if (configManager != null) {
            configManager.reloadConfig();
        }
        if (messageManager != null) {
            messageManager.reloadMessages();
        }
        if (blockManager != null) {
            blockManager.loadData();
        }
        if (skinManager != null) {
            skinManager.loadAllSkins();
        }
        getLogger().info("插件配置已完全重载");
    }

    private void startScheduler() {
        // 每5分钟自动保存数据
        getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
            if (blockManager != null) {
                blockManager.saveData();
            }
            if (skinManager != null) {
                skinManager.saveSkinData();
            }
            getLogger().info("数据已自动保存");
        }, 6000L, 6000L);

        // 每10秒检查玩家生命方块
        getServer().getScheduler().runTaskTimer(this, () -> {
            if (lifeSystem != null) {
                lifeSystem.checkAllPlayers();
            }
            // 每10秒检查游戏结束条件
            if (gameStateManager != null) {
                gameStateManager.checkGameEnd();
            }
        }, 200L, 200L);

        // 每分钟清理一次过期缓存
        getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
            if (skinManager != null) {
                skinManager.cleanupOldCache();
            }
        }, 1200L, 1200L);
        
        // 每秒更新计分板
        getServer().getScheduler().runTaskTimer(this, () -> {
            if (gameStateManager != null) {
                gameStateManager.updateScoreboard();
            }
        }, 20L, 20L);
    }

    /**
     * 获取插件单例实例
     * 
     * <p>提供全局访问点，允许其他类访问插件主实例。</p>
     * 
     * @return PlayerBlockLife插件实例
     * @throws IllegalStateException 如果插件尚未启用（实例为null）
     */
    public static PlayerBlockLife getInstance() {
        return instance;
    }

    /**
     * 获取方块管理器
     * 
     * @return 方块管理器实例
     */
    public PlayerBlockManager getBlockManager() {
        return blockManager;
    }

    /**
     * 获取皮肤管理器
     * 
     * @return 皮肤管理器实例
     */
    public SkinManager getSkinManager() {
        return skinManager;
    }

    /**
     * 获取生命值系统
     * 
     * @return 生命值系统实例
     */
    public LifeSystem getLifeSystem() {
        return lifeSystem;
    }

    /**
     * 获取配置管理器
     * 
     * @return 配置管理器实例
     */
    public ConfigManager getConfigManager() {
        return configManager;
    }

    /**
     * 获取消息管理器
     * 
     * @return 消息管理器实例
     */
    public MessageManager getMessageManager() {
        return messageManager;
    }

    /**
     * 获取游戏状态管理器
     * 
     * @return 游戏状态管理器实例
     */
    public GameStateManager getGameStateManager() {
        return gameStateManager;
    }

    /**
     * 记录信息级别日志
     * 
     * @param message 日志消息
     */
    public void logInfo(String message) {
        getLogger().info(message);
    }

    /**
     * 记录警告级别日志
     * 
     * @param message 日志消息
     */
    public void logWarning(String message) {
        getLogger().warning(message);
    }

    /**
     * 记录错误级别日志
     * 
     * @param message 日志消息
     * @param throwable 异常对象
     */
    public void logError(String message, Throwable throwable) {
        getLogger().log(Level.SEVERE, message, throwable);
    }
}