import { world, system, BlockPermutation, ItemStack } from "@minecraft/server";
import { Economy } from "./systems/Economy.js";
import { OneBlockSystem } from "./systems/OneBlock.js";
import { InventoryMgr } from "./systems/InventoryMgr.js";
import { ShopUI } from "./systems/ShopUI.js";
import { Automation } from "./systems/Automation.js";
import { GameManager } from "./systems/GameManager.js";
import { BedwarsItems } from "./systems/BedwarsItems.js";

// ==============================================
//  One Block Wars - Main Entry Point (Integrated)
// ==============================================

class Main {
    constructor() {
        this.economy = new Economy();
        this.oneBlockSystem = new OneBlockSystem();
        this.shopUI = new ShopUI(this.economy, this.oneBlockSystem);
        this.inventoryMgr = new InventoryMgr(this.oneBlockSystem, this.economy);
        this.inventoryMgr.shopUI = this.shopUI;
        this.automation = new Automation(this.oneBlockSystem, this.economy);
        this.gameManager = new GameManager(this.oneBlockSystem, this.inventoryMgr, this.economy);
        this.bedwarsItems = new BedwarsItems();

        // 依存関係の注入
        this.shopUI.automation = this.automation;
        this.bedwarsItems.oneBlockSystem = this.oneBlockSystem;
        
        // InventoryMgrがゲーム状態を知るためにGameManagerを渡す
        this.inventoryMgr.gameManager = this.gameManager;

        // フック処理
        const originalGiveShopItem = this.inventoryMgr.giveShopItem.bind(this.inventoryMgr);
        this.inventoryMgr.giveShopItem = (player) => {
            originalGiveShopItem(player);
            this.giveLevelTools(player);
        };

        const originalStartGame = this.gameManager.startGame.bind(this.gameManager);
        // 【修正】startGameの引数(mode)を渡せるように変更
        this.gameManager.startGame = (mode = "normal") => {
            for (const p of world.getAllPlayers()) {
                p.removeTag("obw_received_start_logs");
                p.removeTag("obw_bought_scroll");
                
                p.removeTag("obw_upgrade_jump_boost");
                p.removeTag("obw_upgrade_speed");
                p.removeTag("obw_upgrade_haste");
                p.removeTag("obw_upgrade_absorption");
                p.removeTag("obw_upgrade_void_rescue");
            }
            originalStartGame(mode);
        };

        // 試合終了時に経験値をリセットするフック
        const originalStopGame = this.gameManager.stopGame.bind(this.gameManager);
        this.gameManager.stopGame = () => {
            for (const p of world.getAllPlayers()) {
                try {
                    // レベルをリセット
                    p.runCommand("xp -2147483647L @s");
                } catch(e) {}
            }
            originalStopGame();
        };
    }

    init() {
        console.warn("§e[OneBlockWars] Initializing systems...");
        try {
            this.economy.init();
            this.oneBlockSystem.init();
            this.inventoryMgr.init();
            this.automation.init();
            this.registerEvents();
            console.warn("§a[OneBlockWars] System Initialized Successfully.");
        } catch (e) {
            console.error(`Initialization Error: ${e}`);
        }
    }

    giveLevelTools(player) {
        try {
            const inv = player.getComponent("inventory").container;
            const blockLoc = this.oneBlockSystem.getNearestHomeBlock(player);
            let level = 1;
            if (blockLoc) {
                level = this.oneBlockSystem.getBlockLevel(blockLoc);
            }

            let tools = [];
            if (level === 1) {
                tools = ["minecraft:wooden_pickaxe"];
            } else if (level === 2) {
                tools = ["minecraft:stone_pickaxe"];
            } else {
                tools = ["minecraft:iron_pickaxe"];
            }

            for (const typeId of tools) {
                let hasItem = false;
                for (let i = 0; i < inv.size; i++) {
                    const item = inv.getItem(i);
                    if (item && item.typeId === typeId) {
                        hasItem = true;
                        break;
                    }
                }
                if (!hasItem) {
                    inv.addItem(new ItemStack(typeId, 1));
                }
            }

            if (!player.hasTag("obw_received_start_logs")) {
                const logId = "minecraft:oak_log";
                inv.addItem(new ItemStack(logId, 4));
                player.addTag("obw_received_start_logs");
            }
        } catch (e) {
            console.warn(`Tool Give Error: ${e}`);
        }
    }

    registerEvents() {
        const safeSubscribe = (eventGroup, eventName, handler) => {
            if (eventGroup && eventGroup[eventName]) {
                try { eventGroup[eventName].subscribe(handler); } catch (e) {}
            }
        };

        // --- チャットコマンド ---
        safeSubscribe(world.beforeEvents, "chatSend", (event) => {
            const msg = event.message.trim();
            if (!msg.startsWith("!")) return;
            
            const player = event.sender;
            const args = msg.toLowerCase().split(" ");
            const command = args[0];

            if (command === "!start" || command === "!start_b" || command === "!stop" || command === "!reset") {
                event.cancel = true;
                
                system.run(() => {
                    if (command === "!start") {
                        this.gameManager.startGame("normal");
                    } 
                    else if (command === "!start_b") {
                        this.gameManager.startGame("blitz");
                    }
                    else if (command === "!stop" || command === "!reset") {
                        this.gameManager.stopGame();
                    }
                });
            }
        });

        // --- 【強化】ネザーゲート防止策 ---
        
        // 1. 黒曜石への着火キャンセル (念のため維持)
        safeSubscribe(world.beforeEvents, "itemUseOn", (event) => {
            const { block, itemStack } = event;
            if (block.typeId === "minecraft:obsidian" || block.typeId === "minecraft:crying_obsidian") {
                if (itemStack && (itemStack.typeId === "minecraft:flint_and_steel" || itemStack.typeId === "minecraft:fire_charge")) {
                    event.cancel = true;
                    system.run(() => {
                        try { event.source.sendMessage("§cNether travel is disabled."); } catch(e) {}
                    });
                }
            }
        });

        // 2. ディメンション移動検知 (万が一入ってしまった場合の強制送還)
        safeSubscribe(world.afterEvents, "playerDimensionChange", (event) => {
            const { player, fromDimension, toDimension } = event;
            // ネザーまたはエンドへの移動を検知
            if (toDimension.id === "minecraft:nether" || toDimension.id === "minecraft:the_end") {
                // 【修正】即時実行だとロード待ちで失敗する場合があるため、20tick(1秒)遅延させる
                system.runTimeout(() => {
                    try {
                        // オーバーワールドのスポーン地点へ戻す
                        const overworld = world.getDimension("overworld");
                        // 修正: overworld.getSpawnLocation() は存在しないため world.getDefaultSpawnLocation() を使用
                        const spawn = world.getDefaultSpawnLocation(); 
                        
                        // プレイヤーごとのスポーン地点があれば優先
                        const pSpawn = player.getSpawnPoint();
                        let targetLoc = { x: 0, y: 100, z: 0 }; 
                        
                        if (pSpawn && pSpawn.dimension.id === "minecraft:overworld") {
                            targetLoc = { x: pSpawn.x, y: pSpawn.y, z: pSpawn.z };
                        } else if (spawn) {
                            targetLoc = { x: spawn.x, y: spawn.y, z: spawn.z };
                        }

                        player.teleport(targetLoc, { dimension: overworld });
                        player.sendMessage("§cNether travel is disabled! Returning to Overworld...");
                        player.playSound("note.bass");

                    } catch(e) {
                         console.warn(`Nether Return Error: ${e}`);
                    }
                }, 20);
            }
        });

        // --- 結果イベント ---
        safeSubscribe(world.afterEvents, "playerBreakBlock", (event) => {
            if (event.brokenBlockPermutation.type.id === "minecraft:white_wool") {
                const { x, y, z } = event.block.location;
                try { event.dimension.runCommand(`kill @e[type=item,x=${x},y=${y},z=${z},r=2]`); } catch(e) {}
            }
            this.oneBlockSystem.onBlockBreak(event);
        });

        safeSubscribe(world.afterEvents, "itemUse", (event) => {
            this.inventoryMgr.onItemUse(event);
            this.bedwarsItems.onItemUse(event);
        });

        safeSubscribe(world.afterEvents, "entityDie", (event) => {
            if (event.deadEntity.typeId === "minecraft:player") {
                this.gameManager.onPlayerDeath(event.deadEntity, event.damageSource);
            }
        });

        safeSubscribe(world.afterEvents, "playerSpawn", (event) => {
            if (event.initialSpawn === false) {
                const player = event.player;
                system.runTimeout(() => this.gameManager.onPlayerRespawn(player), 20);
            }
        });

        // --- 爆発検知 (TNTによるOneBlock消失対策) ---
        safeSubscribe(world.afterEvents, "explosion", (event) => {
            const impactedBlocks = event.getImpactedBlocks(); 
            if (!impactedBlocks) return;
            
            for (const block of impactedBlocks) {
                if (block) {
                    this.oneBlockSystem.restoreExplodedBlock(block.location);
                }
            }
        });

        // --- ダメージ検知 (キルログ用 & ヒット確認) ---
        safeSubscribe(world.afterEvents, "entityHurt", (event) => {
            const { damageSource, hurtEntity } = event;
            
            // プレイヤー間のダメージをGameManagerに記録する（落下死判定用）
            if (hurtEntity.typeId === "minecraft:player" && damageSource.damagingEntity?.typeId === "minecraft:player") {
                this.gameManager.recordHit(hurtEntity, damageSource.damagingEntity);
            }

            // 弓などのプロジェクタイルヒット時の演出
            if (damageSource.cause === "projectile" && damageSource.damagingEntity?.typeId === "minecraft:player") {
                const attacker = damageSource.damagingEntity;
                if (attacker === hurtEntity) return;

                if (hurtEntity.typeId === "minecraft:player") {
                    const healthComp = hurtEntity.getComponent("minecraft:health");
                    if (healthComp) {
                        const currentHp = Math.ceil(healthComp.currentValue); 
                        attacker.playSound("random.orb", { pitch: 0.5 });
                        attacker.sendMessage(`§eHit! §7${hurtEntity.name} is now at §c${currentHp} HP`);
                    }
                } else {
                    attacker.playSound("random.orb", { pitch: 0.5 });
                }
            }
        });
    }
}

const main = new Main();
system.run(() => { main.init(); });