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

const id_mansao = "mystructure:mansao_da_arvore";
const id_ruina = "mystructure:cabana_map";
const id_godo = "mystructure:godo_house";

const dist_mansao = { min: 400, max: 700 }; 
const dist_ruina = { min: 80, max: 150 };
const dist_godo = { min: 80, max: 90 };

async function cmd(c) {
    try { 
   return await world.getDimension("overworld").runCommandAsync(c); 
    } catch { return { error: true }; }
}

function random(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min) * (Math.random() < 0.5 ? 1 : -1);
}

function checarLocal(dim, x, z) {
    try {
        let bloco = dim.getTopmostBlock({ x, z });
        if (!bloco) return "NÃO CARREGADO";

        let block_id = bloco.typeId;
        if (block_id.includes("water") || block_id.includes("kelp") || block_id.includes("seagrass") || block_id.includes("ice") || block_id.includes("air")) {
            return "INVALIDO";
        }
        
        let block_up = dim.getBlock({ x, y: bloco.location.y + 1, z });
        if (block_up && (block_up.typeId.includes("water") || block_up.typeId.includes("leaves") || block_up.typeId.includes("log"))) return "OBSTRUIDO";

        return { x, y: bloco.location.y, z, status: "OK", bloco: block_id };
    } catch { return "ERRO"; }
}

async function tentarMansao(tentativa = 1) {
    if (world.getDynamicProperty("mansao_spawned")) {
        tentarRuina(); 
        return;
    }

    if (tentativa > 15) {
        system.runTimeout(() => tentarMansao(1), 600);
        return;
    }

    let player = world.getAllPlayers()[0];
    if (!player) return;

    let posX = Math.floor(player.location.x + random(dist_mansao.min, dist_mansao.max));
    let posZ = Math.floor(player.location.z + random(dist_mansao.min, dist_mansao.max));
    let area_name = `spawn_mansao`;

    await cmd(`tickingarea remove ${area_name}`);
    await cmd(`tickingarea add circle ${posX} 100 ${posZ} 2 ${area_name}`);

    system.runTimeout(async () => {
        let mundo = world.getDimension("overworld");
        let resultado = checarLocal(mundo, posX, posZ);

        await cmd(`tickingarea remove ${area_name}`);

        if (resultado.status === "OK") {
            let carregar = await cmd(`structure load "${id_mansao}" ${resultado.x} ${resultado.y} ${resultado.z}`);
            
            if (!carregar.error) {
                world.setDynamicProperty("mansao_spawned", true);
                world.setDynamicProperty("m_x", resultado.x);
                world.setDynamicProperty("m_y", resultado.y);
                world.setDynamicProperty("m_z", resultado.z);
                system.runTimeout(() => tentarRuina(1), 200);
            } else {
                system.runTimeout(() => tentarMansao(tentativa + 1), 100);
            }
        } else {
            system.runTimeout(() => tentarMansao(tentativa + 1), 100);
        }
    }, 240); 
}

async function tentarRuina(tentativa = 1) {
    if (world.getDynamicProperty("ruina_spawned")) {
        if (!world.getDynamicProperty("godo_spawned")) system.runTimeout(() => tentarGodoHouse(1), 200);
        return;
    }

    if (tentativa > 15) {
        system.runTimeout(() => tentarRuina(1), 400);
        return;
    }

    let player = world.getAllPlayers()[0];
    let rX = Math.floor(player.location.x + random(dist_ruina.min, dist_ruina.max));
    let rZ = Math.floor(player.location.z + random(dist_ruina.min, dist_ruina.max));
    let area_ruina = `spawn_ruina`;

    await cmd(`tickingarea remove ${area_ruina}`);
    await cmd(`tickingarea add circle ${rX} 100 ${rZ} 2 ${area_ruina}`);

    system.runTimeout(async () => {
        let dimension = world.getDimension("overworld");
        let check = checarLocal(dimension, rX, rZ);
        
        await cmd(`tickingarea remove ${area_ruina}`);

        if (check.status === "OK") {
            let load_ruina = await cmd(`structure load "${id_ruina}" ${check.x} ${check.y - 1} ${check.z}`);
            if (!load_ruina.error) {
                world.setDynamicProperty("ruina_spawned", true);
                world.setDynamicProperty("ruina_x", check.x);
                world.setDynamicProperty("ruina_z", check.z);
          world.sendMessage(`§e[Event] §fA mysterious cabin was spotted at: §a${check.x}, ${check.y}, ${check.z}`);
                
                system.runTimeout(() => tentarGodoHouse(1), 300);
            } else {
                system.runTimeout(() => tentarRuina(tentativa + 1), 100);
            }
        } else {
            system.runTimeout(() => tentarRuina(tentativa + 1), 100);
        }
    }, 160);
}

async function tentarGodoHouse(tentativa = 1) {
    if (world.getDynamicProperty("godo_spawned")) return;

    if (tentativa > 15) {
        system.runTimeout(() => tentarGodoHouse(1), 300);
        return;
    }

    let player = world.getAllPlayers()[0];
    let gX = Math.floor(player.location.x + random(dist_godo.min, dist_godo.max));
    let gZ = Math.floor(player.location.z + random(dist_godo.min, dist_godo.max));
    let area_godo = `spawn_godo`;

    await cmd(`tickingarea remove ${area_godo}`);
    await cmd(`tickingarea add circle ${gX} 100 ${gZ} 2 ${area_godo}`);

    system.runTimeout(async () => {
        let dim_over = world.getDimension("overworld");
        let local = checarLocal(dim_over, gX, gZ);

        await cmd(`tickingarea remove ${area_godo}`);

        if (local.status === "OK") {
            let forge_load = await cmd(`structure load "${id_godo}" ${local.x} ${local.y} ${local.z}`);
            if (!forge_load.error) {
                world.setDynamicProperty("godo_spawned", true);
          world.sendMessage(`§e[Event] §fGodo's Blacksmith found at: §a${local.x}, ${local.y}, ${local.z}`);
            } else {
                system.runTimeout(() => tentarGodoHouse(tentativa + 1), 100);
            }
        } else {
            system.runTimeout(() => tentarGodoHouse(tentativa + 1), 100);
        }
    }, 160);
}

system.runInterval(() => {
    if (!world.getDynamicProperty("ruina_spawned") || world.getDynamicProperty("mapa_revelado")) return;
    let cabin_x = world.getDynamicProperty("ruina_x");
    let cabin_z = world.getDynamicProperty("ruina_z");
    
    if (cabin_x == undefined || cabin_z == undefined) return;

    for (let p of world.getAllPlayers()) {
        let dist_x = p.location.x - cabin_x;
        let dist_z = p.location.z - cabin_z;
        if ((dist_x*dist_x + dist_z*dist_z) < 100) {
            world.setDynamicProperty("mapa_revelado", true);
            let m_x = world.getDynamicProperty("m_x");
            let m_y = world.getDynamicProperty("m_y");
            let m_z = world.getDynamicProperty("m_z");
      p.sendMessage("§b§l[Mystery] §r§fYou found an old map on the table...");
      p.playSound("random.levelup");
            if (m_x !== undefined) p.sendMessage(`§7It points to a colossal structure at: §a${Math.floor(m_x)}, ${Math.floor(m_y)}, ${Math.floor(m_z)}`);
        }
    }
}, 40);

let start = false;
system.runInterval(() => {
    if (start) return;
    let player = world.getAllPlayers()[0];
    if (player && (Math.abs(player.location.x) > 5 || Math.abs(player.location.z) > 5)) {
        start = true;
     cmd("tickingarea remove_all");
        system.runTimeout(() => tentarMansao(), 100);
    }
}, 60);