import { world, system, BlockPermutation } from "@minecraft/server";

export class BedwarsItems {
    constructor() {
        // 仮想プロジェクタイルの管理
        this.activeProjectiles = new Map();
        this.oneBlockSystem = null; 
        
        system.runInterval(() => {
            this.tickProjectiles();
        }, 1);

        world.beforeEvents.itemUse.subscribe((event) => {
            const item = event.itemStack;
            const player = event.source;
            const name = item.nameTag || "";

            if (item.typeId === "minecraft:fire_charge" && name.includes("Fireball")) {
                event.cancel = true; // バニラの挙動を強制キャンセル
                system.run(() => {
                    this.throwVirtualProjectile(player, "fireball");
                    this.consumeItem(player, "minecraft:fire_charge", "Fireball"); 
                });
            }
            else if (item.typeId === "minecraft:egg" && name.includes("Bridge Egg")) {
                event.cancel = true; // バニラの卵投げを強制キャンセル
                system.run(() => {
                    this.throwVirtualProjectile(player, "bridge");
                    this.consumeItem(player, "minecraft:egg", "Bridge Egg");
                });
            }
            else if (item.typeId === "minecraft:paper" && name.includes("Home")) {
                event.cancel = true;
                system.run(() => {
                    this.useHomeScroll(player);
                });
            }
        });
    }

    onItemUse(event) {
        // Handled completely by beforeEvents
    }

    consumeItem(player, typeId, nameKeyword) {
        const equipment = player.getComponent("equippable");
        if (equipment) {
            const item = equipment.getEquipment("Mainhand");
            if (item && item.typeId === typeId && (item.nameTag || "").includes(nameKeyword)) {
                if (item.amount > 1) {
                    item.amount -= 1;
                    equipment.setEquipment("Mainhand", item);
                } else {
                    equipment.setEquipment("Mainhand", undefined);
                }
                return;
            }
        }
        
        const inv = player.getComponent("inventory").container;
        if (!inv) return;
        for (let i = 0; i < inv.size; i++) {
            const item = inv.getItem(i);
            if (item && item.typeId === typeId && (item.nameTag || "").includes(nameKeyword)) {
                if (item.amount > 1) {
                    item.amount -= 1;
                    inv.setItem(i, item);
                } else {
                    inv.setItem(i, undefined);
                }
                break;
            }
        }
    }

    // 【完全改修】エンティティを使わず、スクリプトの計算だけで仮想的に弾を飛ばす
    throwVirtualProjectile(player, type) {
        try {
            const viewDir = player.getViewDirection();
            const headLoc = player.getHeadLocation();
            
            // 目の前からスタート
            const spawnLoc = {
                x: headLoc.x + viewDir.x * 0.5,
                y: headLoc.y + viewDir.y * 0.5,
                z: headLoc.z + viewDir.z * 0.5
            };

            // ブリッジエッグの初速を 1.2 から 2.0 に上昇
            const speed = (type === "fireball") ? 1.5 : 2.0;
            const velocity = { x: viewDir.x * speed, y: viewDir.y * speed, z: viewDir.z * speed };

            // ユニークIDで弾を管理
            this.activeProjectiles.set(Date.now().toString() + Math.random().toString(), {
                type: type,
                currentLoc: spawnLoc,
                velocity: velocity,
                dimension: player.dimension,
                ticks: 0,
                placedXZ: new Set() // 【追加】ブリッジエッグの垂れ下がり防止用セット
            });

            if (type === "fireball") {
                player.playSound("mob.ghast.fireball", { pitch: 1.0, volume: 1.0 });
            } else {
                player.playSound("random.bow", { pitch: 1.0, volume: 1.0 });
            }

        } catch(e) {
            console.warn("Projectile throw error:", e);
        }
    }

    tickProjectiles() {
        for (const [id, data] of this.activeProjectiles.entries()) {
            const { type, dimension, velocity, placedXZ } = data;
            
            data.ticks++;
            // 生存時間アップ: より遠くまで飛ぶように強制消滅時間を 100ticks -> 200ticks(10秒) に延長
            if (data.ticks > 200) {  
                if (type === "fireball") this.triggerExplosion(dimension, data.currentLoc);
                this.activeProjectiles.delete(id);
                continue;
            }

            let nextLoc = {
                x: data.currentLoc.x + velocity.x,
                y: data.currentLoc.y + velocity.y,
                z: data.currentLoc.z + velocity.z
            };

            // ブリッジエッグのみ重力を適用して放物線を描かせる
            if (type === "bridge") {
                // 重力による落下を少し緩やかに (0.05 -> 0.035)
                velocity.y -= 0.035;
            }

            // ブロックとの衝突判定 (線形補間で細かくチェック)
            let hit = false;
            const steps = 3;
            for (let i = 1; i <= steps; i++) {
                const checkLoc = {
                    x: data.currentLoc.x + (velocity.x * (i / steps)),
                    y: data.currentLoc.y + (velocity.y * (i / steps)),
                    z: data.currentLoc.z + (velocity.z * (i / steps))
                };
                
                try {
                    const block = dimension.getBlock(checkLoc);
                    // 空気・水・マグマ以外にぶつかったら着弾
                    if (block && block.typeId !== "minecraft:air" && !block.typeId.includes("water") && !block.typeId.includes("lava")) {
                        hit = true;
                        nextLoc = checkLoc; // 当たった位置で止める
                        break;
                    }
                } catch(e) {
                    hit = true; 
                    break;
                }
            }

            if (hit) {
                if (type === "fireball") {
                    this.triggerExplosion(dimension, nextLoc);
                } else if (type === "bridge") {
                    this.placeBridge(dimension, data.currentLoc, nextLoc, placedXZ);
                }
                this.activeProjectiles.delete(id);
                continue;
            }

            // ぶつかっていないなら軌跡を描画
            if (type === "bridge") {
                this.placeBridge(dimension, data.currentLoc, nextLoc, placedXZ);
            } else if (type === "fireball") {
                try { dimension.spawnParticle(`minecraft:basic_flame_particle`, nextLoc); } catch(e){}
            }
            
            data.currentLoc = nextLoc;
        }
    }

    triggerExplosion(dimension, loc) {
        const x = loc.x;
        const y = loc.y;
        const z = loc.z;

        // 絶対に音とパーティクルを出す
        try {
            dimension.runCommand(`particle minecraft:huge_explosion_emitter ${x} ${y} ${z}`);
            dimension.runCommand(`playsound random.explode @a ${x} ${y} ${z}`);
        } catch(e) {}

        // 爆発APIの実行、失敗したらフォールバック
        try {
            // 【調整】地形破壊の威力を 4 から 3 に戻し、バランスを取る
            dimension.createExplosion({x, y, z}, 3, { breaksBlocks: true });
            
            // 【調整】爆発の中心付近(半径4)のエンティティに確実にハート3つ分(6ダメージ)を与える
            try {
                dimension.runCommand(`damage @e[x=${Math.floor(x)},y=${Math.floor(y)},z=${Math.floor(z)},r=4] 6 entity_explosion`);
            } catch(eInner) {}

        } catch(e) {
            try {
                // APIエラー時のフォールバックダメージ (ハート3つ分 = 6ダメージ)
                dimension.runCommand(`damage @e[x=${Math.floor(x)},y=${Math.floor(y)},z=${Math.floor(z)},r=4] 6 entity_explosion`);
            } catch(e2) {}
        }
    }

    placeBridge(dimension, start, end, placedXZ) {
        const dist = Math.sqrt((end.x-start.x)**2 + (end.y-start.y)**2 + (end.z-start.z)**2);
        if (dist < 0.1) return;
        const steps = Math.ceil(dist * 2); 

        for (let i = 0; i <= steps; i++) {
            const t = i / steps;
            const x = Math.floor(start.x + (end.x - start.x) * t);
            const y = Math.floor(start.y + (end.y - start.y) * t) - 1; // 軌跡の1マス下
            const z = Math.floor(start.z + (end.z - start.z) * t);

            // 【追加】垂れ下がり抑制：同じXとZの列には、一番高い位置の1回しかブロックを置かない
            const xzKey = `${x},${z}`;
            if (placedXZ && placedXZ.has(xzKey)) continue;
            if (placedXZ) placedXZ.add(xzKey);

            try {
                const block = dimension.getBlock({x, y, z}); 
                if (block && (block.typeId === "minecraft:air" || block.typeId.includes("water") || block.typeId.includes("lava"))) {
                    // APIバージョンごとの不一致を全て吸収する3段構えのブロック設置処理
                    try {
                        block.setPermutation(BlockPermutation.resolve("minecraft:white_wool"));
                    } catch(err1) {
                        try { 
                            block.setType("minecraft:white_wool"); 
                        } catch(err2) {
                            dimension.runCommand(`setblock ${x} ${y} ${z} white_wool keep`);
                        }
                    }
                }
            } catch(e) {
                try { dimension.runCommand(`setblock ${x} ${y} ${z} white_wool keep`); } catch(e2) {}
            }
        }
    }

    useHomeScroll(player) {
        if (!this.oneBlockSystem) return;
        const homeLoc = this.oneBlockSystem.getNearestHomeBlock(player);
        if (homeLoc) {
            player.teleport({ x: homeLoc.x + 0.5, y: homeLoc.y + 1, z: homeLoc.z + 0.5 });
            player.playSound("mob.endermen.portal");
            player.sendMessage("§aTeleported home!");
            
            this.consumeItem(player, "minecraft:paper", "Home");
        }
    }
}