import { world, system, BlockPermutation } from "@minecraft/server";
import { Config } from "../config.js";

export class MapGenerator {
    constructor(oneBlockSystem) {
        this.oneBlockSystem = oneBlockSystem;
    }

    generateMap(playerCount) {
        world.sendMessage(`§e[MapGen] Creating OneBlocks for ${playerCount} players...`);
        
        // メモリとDBを強制リセット
        this.oneBlockSystem.oneBlockLocations.clear();
        this.oneBlockSystem.blockLevels.clear();
        this.oneBlockSystem.breakCounts.clear();
        
        world.setDynamicProperty("obw:one_block_locations", JSON.stringify({}));
        world.setDynamicProperty("obw:one_block_levels", JSON.stringify({}));

        // 生成前に広範囲を物理リセット
        this.resetMapPhysics();

        const center = Config.MAP_CENTER;
        const radius = Config.MAP_RADIUS;

        // --- 中央(Mid) ---
        this.createOneBlockIsland(center, "mid");

        // --- 各プレイヤーのホーム ---
        const count = playerCount < 1 ? 1 : playerCount;

        for (let i = 0; i < count; i++) {
            const angle = (2 * Math.PI / count) * i;
            // 座標計算 (四捨五入)
            const x = Math.round(center.x + radius * Math.cos(angle));
            const z = Math.round(center.z + radius * Math.sin(angle));
            const y = center.y;

            const location = { x, y, z };
            
            this.createOneBlockIsland(location, "home");
            
            console.warn(`[MapGen] Registered Home ${i+1} at ${x}, ${y}, ${z}`);
        }

        this.oneBlockSystem.saveOneBlocks();
        world.sendMessage("§a[MapGen] Map generation complete!");
    }

    createOneBlockIsland(location, type) {
        const dimension = world.getDimension("overworld");
        
        try {
            this.oneBlockSystem.registerOneBlock(location, type);

            const blockId = (type === "mid") ? Config.MID_BLOCK : Config.INITIAL_BLOCK;
            const block = dimension.getBlock(location);
            if (block) {
                block.setPermutation(BlockPermutation.resolve(blockId));
            }

            const barrierLoc = { x: location.x, y: location.y - 1, z: location.z };
            const barrier = dimension.getBlock(barrierLoc);
            if (barrier) {
                barrier.setPermutation(BlockPermutation.resolve(Config.BARRIER_BLOCK));
            }

        } catch (e) {
            console.warn(`[MapGen] Error creating island: ${e}`);
        }
    }

    resetMap() {
        const dimension = world.getDimension("overworld");
        
        // データのクリア
        this.oneBlockSystem.clearAll(dimension);

        // 物理リセット (広範囲) - 3回実行して確実に消す
        this.resetMapPhysics();
        this.resetMapPhysics();
        this.resetMapPhysics();

        // エンティティ掃除
        this.clearEntities(dimension);

        world.sendMessage("§a[MapGen] Map reset complete.");
    }

    /**
     * 物理的なブロック消去処理
     * 【修正】範囲を調整し、Y軸の下限を0に戻す
     * 注意: 範囲を広げすぎるとロードされていないチャンクになり消去できないため、
     * 確実にロードされる現実的な範囲(160)に設定します。
     */
    resetMapPhysics() {
        const dimension = world.getDimension("overworld");
        const center = Config.MAP_CENTER;
        
        // 【修正】範囲を300から160に変更
        // 半径160ブロックあれば、Config.MAP_RADIUS(40)の島から120ブロック外側までカバーできるため十分です。
        // これ以上広げるとシミュレーション距離外となり、fillコマンドが機能せず消え残ります。
        const range = 160; 
        
        // 【修正】下限を0に戻す (ロビー等の保護)
        const minY = 0;
        const maxY = 320;

        // コマンドの負荷軽減のため細かく分割
        const stepXZ = 32; 
        const stepY = 20; 

        for (let x = center.x - range; x <= center.x + range; x += stepXZ) {
            for (let z = center.z - range; z <= center.z + range; z += stepXZ) {
                for (let y = minY; y < maxY; y += stepY) {
                    
                    const x2 = Math.min(x + stepXZ - 1, center.x + range);
                    const z2 = Math.min(z + stepXZ - 1, center.z + range);
                    const y2 = Math.min(y + stepY - 1, maxY);
                    
                    try {
                        // fill x1 y1 z1 x2 y2 z2 air
                        dimension.runCommand(`fill ${x} ${y} ${z} ${x2} ${y2} ${z2} air`);
                    } catch(e) {
                        // 範囲外エラー等は無視
                    }
                }
            }
        }
    }

    clearEntities(dimension) {
        try {
            const types = [
                "item", "tnt", "creeper", "zombie", "skeleton", "spider",
                "armor_stand", "arrow", "snowball", "thrown_trident",
                "minecraft:wind_charge_projectile", "xp_orb" 
            ];
            
            for (const type of types) {
                dimension.runCommand(`kill @e[type=${type}]`);
            }
        } catch (e) {}
    }
}