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


function hasHeavyRockTag(entity) {
    // Verificar si la entidad tiene la etiqueta "heavy_rock"
    return entity.hasTag("heavy_rock");
}

export function heavy_rock(damageSource, hurtEntity) {
    // Verificar si la fuente del daño es un ataque directo de entidad
    if (damageSource.cause !== EntityDamageCause.entityAttack) return;

    // Verificar si el atacante es un jugador y tiene la etiqueta "heavy_rock"
    const attacker = damageSource.damagingEntity;
    if (!(attacker instanceof Player)) return; // Verificamos si el atacante es un jugador
    if (!hasHeavyRockTag(attacker)) return;

    // Aplicar el retroceso a la entidad golpeada
    hurtEntity.applyKnockback(
        -attacker.getViewDirection().z, // Dirección Z del retroceso
        -attacker.getViewDirection().x, // Dirección X del retroceso
        0.2, // Intensidad horizontal del retroceso
        0.4  // Intensidad vertical del retroceso
    );
}




let regenerationTick = new Map(); // Mapa para almacenar el contador por jugador

export function moonstone(player) {
    const regenerationInterval = 21; // Cada cuántos ticks ejecutar regeneración

    if (world.getTimeOfDay() >= 12500 && world.getTimeOfDay() <= 24000 && player.hasTag("moonstone_item")) {
        // Aplicar efectos constantes
        player.runCommand('effect @s speed 1 1 true');
        player.runCommand('effect @s strength 1 1 true');
        player.runCommand('effect @s jump_boost 1 1 true');
        player.runCommand('effect @s hunger 1 25 true');

        // Inicializar el contador del jugador si no existe
        if (!regenerationTick.has(player.id)) {
            regenerationTick.set(player.id, 0);
        }
        let tick = regenerationTick.get(player.id) + 1;

        // Incrementar el contador del jugador
        if (tick >= regenerationInterval) {
            if (Math.random() < 0.2) { // 50% de probabilidad
                // Aplicar efecto de regeneración cada 5 segundos con probabilidad del 50%
                player.runCommand('effect @s regeneration 5 0 true');
            }
            tick = 0; // Reiniciar contador
        }

        // Actualizar el contador en el mapa
        regenerationTick.set(player.id, tick);
    } else {
        // Si no se cumplen las condiciones, eliminar el contador del jugador
        regenerationTick.delete(player.id);
    }
}

// Evento para eliminar las entidades de control cuando un jugador respawnea
world.afterEvents.playerSpawn.subscribe(({ player }) => {
    // Limitar la ejecución solo si el jugador está en el rango Y permitido
    if (player.location.y >= -64 && player.location.y <= 319) {
        const player_controllers = player.dimension.getEntities({
            type: "dungeon:player_controller",
            location: player.location
        });

        // Eliminar entidades de control que no tengan etiquetas válidas
        for (let j = 0; j < player_controllers.length; j++) {
            const entity = player_controllers[j];
            // Solo mantener entidades con etiquetas 'snow', 'snow2' o 'sandstorm'
            if (!entity.getTags().some(tag => ["snow", "snow2", "sandstorm"].includes(tag))) {
                entity.remove();
            }
        }
    }
});

// Intervalo para manejar las entidades de control del jugador
system.runInterval(() => {
    const players = world.getAllPlayers();

    for (let player of players) {
        // Verificar si el jugador está en el rango Y permitido
        if (player.location.y < -64 || player.location.y > 319) {
            continue; // Saltar a la siguiente iteración si no está en el rango
        }

        const playerControllers = player.dimension.getEntities({
            type: "dungeon:player_controller",
            location: player.location
        });

        // Buscar la entidad de control del jugador correspondiente
        let playerControllerByPlayer;
        for (let controller of playerControllers) {
            // Verificar si la entidad tiene una etiqueta válida
            if (!controller.getTags().some(tag => ["snow", "snow2", "sandstorm"].includes(tag))) {
                controller.remove(); // Eliminar si no tiene etiquetas válidas
                continue;
            }

            // Encontrar el controlador correspondiente al jugador
            if (controller.getTags().includes(player.id)) {
                playerControllerByPlayer = controller;
            }
        }

        // Si el jugador está en el Overworld
        if (player.dimension.id === "minecraft:overworld") {
            // Si el jugador está en la capa de incaves
            //if (player.location.y <= 56) {
                // Despawns y elimina el controlador
           //     if (playerControllerByPlayer) {
                  //  playerControllerByPlayer.triggerEvent("minecraft:remove_event");
                //}
               // player.addTag("incaves");
             //   continue;
           // }

            // Verifica el ciclo de día y noche para manejar las condiciones
          //  if (world.getTimeOfDay() >= 12500 && world.getTimeOfDay() <= 24000) {
                // Lógica si es de noche (vacía por ahora)
           // } else {
                // Si no existe el controlador, lo crea
                if (!playerControllerByPlayer) {
                    try {
                        const controllerEntity = player.dimension.spawnEntity("dungeon:player_controller", player.location);
                        controllerEntity.addTag(player.id); // Asocia la entidad al jugador
                    } catch (e) {
                        console.error("Error al crear la entidad de controlador:", e);
                    }
                } else {
                    // Teletransporta el controlador al jugador
                    playerControllerByPlayer.teleport({
                        x: player.getHeadLocation().x,
                        y: player.getHeadLocation().y + 0.25,
                        z: player.getHeadLocation().z
                    });

                    // Manejo de las etiquetas y eliminación de otras etiquetas
                    if (playerControllerByPlayer.hasTag("snow")) {
                        playerControllerByPlayer.removeTag("snow2");
                        playerControllerByPlayer.removeTag("sandstorm");
                    } else if (playerControllerByPlayer.hasTag("snow2")) {
                        playerControllerByPlayer.removeTag("snow");
                        playerControllerByPlayer.removeTag("sandstorm");
                    } else if (playerControllerByPlayer.hasTag("sandstorm")) {
                        playerControllerByPlayer.removeTag("snow");
                        playerControllerByPlayer.removeTag("snow2");
                    }
                }
          //  }
        }
    }
}, 21); // 20 tics por segundo (1 segundo real)

// Variable global para suscribir al evento solo una vez
let isSubscribed = false;

// Función para ejecutar los comandos cuando el jugador muere
export function executeDeathCommands() {
    if (isSubscribed) return; // Si ya estamos suscritos, no hacer nada

    // Suscribir al evento de muerte de entidad solo una vez
    world.afterEvents.entityDie.subscribe(({deadEntity }) => {
        if (deadEntity instanceof Player) {
            deadEntity.runCommand(`/tag @s[tag=!guide_book] add guide_book`); 
            deadEntity.runCommand(`/tag @s remove respawned`);
            deadEntity.runCommand(`/fog @s remove cemetery`);
            deadEntity.runCommand(`/fog @s remove cursedcementery`);
            deadEntity.runCommand(`/clear @s[tag=totemofrecovery] dungeon:totemofrecovery 0 1`);  // Eliminar la invulnerabilidad
            deadEntity.runCommand(`/execute if entity @s[tag=totemofrecovery] run summon dungeon:gravestone`); // Aparece tumba
            deadEntity.runCommand(`/execute if entity @s[tag=totemofrecovery] run msg @s §3X: ${Math.round(deadEntity.location.x)}, Y: ${Math.round(deadEntity.location.y)}, Z: ${Math.round(deadEntity.location.z)}`); //Escribir coordenadas
            deadEntity.runCommand(`/execute if entity @s[tag=totemofrecovery] run kill @e[type=item,name=\"Totem of recovery §3(Accessory) "\,c=1,r=6]`); // Eliminar totem
            deadEntity.runCommand(`/execute if entity @s[tag=totemofrecovery] run kill @e[type=item,name=\"Totem de la recuperación §3(Accesorio) "\,c=1,r=6]`); // Eliminar totem
            deadEntity.runCommand(`/execute if entity @s[tag=totemofrecovery] run playsound random.totem @s`); // Sonido
            deadEntity.runCommand(`/execute if entity @s[tag=totemofrecovery] run particle minecraft:totem_particle ~ ~1~`); // Particulo
            deadEntity.runCommand(`/xp -99l @s`); // Aplicar experiencia negativa
            deadEntity.runCommand(`/tag @s add invulnerable`); // Agregar la etiqueta de invulnerabilidad
            deadEntity.runCommand(`/scoreboard players reset @s stonetest`); // Eliminar insomnio
            deadEntity.runCommand(`/scoreboard players remove @s[m=0,scores={insomnio=45000..}] insomnio 45000`); // Eliminar insomnio
            deadEntity.runCommand(`/tag @s remove cemetery`); // Eliminar etiqueta de cementerio
            deadEntity.runCommand(`/tag @s remove punisher`); // Eliminar etiqueta de castigo
            deadEntity.runCommand(`/tag @s remove punishment`); // Eliminar etiqueta de castigo
            deadEntity.runCommand(`/tag @s remove stone_player`); // Eliminar etiqueta de piedra de jugador
            deadEntity.runCommand(`/tag @s remove stone`); // Eliminar etiqueta de piedra
        }
    });

    // Marcar que ya estamos suscritos
    isSubscribed = true;
}