import { world, system } from "@minecraft/server";
import { getDifficulty } from './dungeonSkeletons.js'; // Ajusta la ruta


/* === CONFIGURACIÓN BASE EXISTENTE === */
const VALID_MOB_IDS = [
  "dungeon:gray_skeleton", "dungeon:rock_monster", "dungeon:dungeonzombie",
  "dungeon:mummy", "dungeon:gray_zombie", "dungeon:brown_skeleton",
  "minecraft:vindicator", "minecraft:wither_skeleton", "minecraft:piglin", "minecraft:piglin_brute", "minecraft:zombie",
  "dungeon:gray_mummy", "dungeon:gorgona",
  "dungeon:miner_skeleton", "dungeon:purple_skeleton", "dungeon:purple_zombie"
];

const TAG = "otherworldly_expert";
const MAX_DISTANCE_SQ = 2.5 * 2.5;
const MIN_DELTA_Y = 1.95;
const MAX_DELTA_Y = 4;
const JUMP_Y = 0.55;
const JUMP_XZ = 0.4;
const MAX_VERTICAL_VEL = 0.01;

const NATURE_GUARD = "dungeon:nature_guard";
const RETREAT_DISTANCE = 4.15;
const ATTACK_DISTANCE = 2.5;

const DIMENSIONS = ["overworld", "nether", "the_end"];

/* === CONTROL DE IA EXISTENTE: SALTO VERTICAL === */
function ai_control(dimension) {
  const players = dimension.getPlayers();
  if (players.length === 0) return;

  for (const mobId of VALID_MOB_IDS) {
    const mobs = dimension.getEntities({
      type: mobId,
      tags: [TAG]
    });

    for (const entity of mobs) {
      const { x: ex, y: ey, z: ez } = entity.location;

      let targetPlayer = null;
      let closestDistSq = MAX_DISTANCE_SQ;

      // Buscar SOLO el jugador más cercano
      for (const player of players) {
        const { x: px, y: py, z: pz } = player.location;

        const dx = px - ex;
        const dz = pz - ez;
        const deltaY = py - ey;
        const distSq = dx * dx + dz * dz;

        if (
          distSq <= closestDistSq &&
          deltaY > MIN_DELTA_Y &&
          deltaY < MAX_DELTA_Y
        ) {
          closestDistSq = distSq;
          targetPlayer = player;
        }
      }

      if (!targetPlayer) continue;

      const { x: px, y: py, z: pz } = targetPlayer.location;

      const block = dimension.getBlock({
        x: Math.floor(px),
        y: Math.floor(py) - 1,
        z: Math.floor(pz)
      });

      if (!block || block.typeId === "minecraft:air") continue;

      const velocity = entity.getVelocity();
      if (Math.abs(velocity.y) >= MAX_VERTICAL_VEL) continue;

      const dx = px - ex;
      const dz = pz - ez;
      const len = Math.sqrt(dx * dx + dz * dz);
      if (len === 0) continue;

      entity.applyImpulse({
        x: (dx / len) * JUMP_XZ,
        y: JUMP_Y,
        z: (dz / len) * JUMP_XZ
      });
    }
  }
}



/* === CONTROL DE IA DEL ENEMIGO DE PIEDRA FLOTANTE === */
function stone_guard_ai(dimension) {
  const players = dimension.getPlayers();
  if (players.length === 0) return;

  const processed = new Set();

  for (const player of players) {
    const px = player.location.x;
    const pz = player.location.z;

    const mobs = dimension.getEntities({
      type: NATURE_GUARD,
      tags: [TAG],
      location: player.location,
      maxDistance: 12 // rango razonable de acción del guard
    });

    for (const mob of mobs) {
      if (processed.has(mob.id)) continue; // para no repetir mobs cerca de varios players
      processed.add(mob.id);

      const mobPos = mob.location;

      const dx = px - mobPos.x;
      const dz = pz - mobPos.z;
      const distance = Math.sqrt(dx * dx + dz * dz);

      const neighbors = mobs.filter(other => {
        if (other === mob) return false;
        const odx = other.location.x - mobPos.x;
        const odz = other.location.z - mobPos.z;
        const dist = Math.sqrt(odx * odx + odz * odz);
        return dist < 6;
      });

      if (neighbors.length > 0) {
        for (const neighbor of neighbors) {
          const ndx = mobPos.x - neighbor.location.x;
          const ndz = mobPos.z - neighbor.location.z;
          const len = Math.sqrt(ndx * ndx + ndz * ndz);
          if (len > 0) {
            const nx = ndx / len;
            const nz = ndz / len;
            mob.applyImpulse({ x: nx * 0.2, y: 0.0, z: nz * 0.2 });
          }
        }
      }

      if (distance < RETREAT_DISTANCE) {
        retreatFromPlayer(mob, player.location);
      } else if (distance < ATTACK_DISTANCE && neighbors.length === 0) {
        attackPlayer(mob, player);
      }

      if (players.length > 2 && distance < ATTACK_DISTANCE) {
        attackPlayer(mob, player);
      }
    }
  }
}

function hasLineOfSight(dimension, start, end) {
  const dx = end.x - start.x;
  const dy = end.y - start.y;
  const dz = end.z - start.z;

  const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
  const step = 0.3;
  const steps = Math.ceil(distance / step);

  for (let i = 0; i <= steps; i++) {
    const t = i / steps;
    const x = start.x + dx * t;
    const y = start.y + dy * t;
    const z = start.z + dz * t;

    const block = dimension.getBlock({
      x: Math.floor(x),
      y: Math.floor(y),
      z: Math.floor(z)
    });

    if (!block || block.typeId !== "minecraft:air") {
      return false;
    }
  }

  return true;
}

export function carnivorous_plant(dimension) {
  const difficulty = getDifficulty();

  let chance = 0.75;
  let radius = 4.2;
  let enableBarrage = false;

  switch (difficulty) {
    case "easy":
      chance = 0.2;
      break;
    case "normal":
      chance = 0.3;
      break;
    case "hard":
      chance = 0.5;
      break;
    case "expert":
      chance = 1.0;
      radius = 6.2;
      enableBarrage = true;
      break;
  }

  const players = dimension.getPlayers();
  if (players.length === 0) return;

  const processed = new Set();

  for (const player of players) {
    const gameMode = player.getGameMode();
    if (gameMode !== "Survival" && gameMode !== "Adventure") continue;

    const px = player.location.x;
    const py = player.location.y + 1.6;
    const pz = player.location.z;

    const plants = dimension.getEntities({
      families: ["dcarnivorous_plant"],
      location: { x: px, y: py, z: pz },
      maxDistance: 32
    });

    let index = 0;

    for (const plant of plants) {
      if (processed.has(plant.id)) continue;
      processed.add(plant.id);

      const plantEye = {
        x: plant.location.x,
        y: plant.location.y + 1.5,
        z: plant.location.z
      };

      const playerEye = { x: px, y: py, z: pz };

      const dy = Math.abs(plantEye.y - playerEye.y);
      if (dy > 5) continue;

      if (!hasLineOfSight(dimension, plantEye, playerEye)) continue;

      if (Math.random() < chance) {
        plant.playAnimation("animation.dcarnivorous_plant.escape");

        let targetPos;

        if (plants.length === 1 || (index === 0 && plants.length > 1)) {
          // Planta única o la primera: debajo del jugador
          targetPos = {
            x: px,
            y: player.location.y - 1,
            z: pz
          };
        } else {
          const angle = (2 * Math.PI / (plants.length - 1)) * index;

          const offsetX = Math.cos(angle) * radius;
          const offsetZ = Math.sin(angle) * radius;

          targetPos = {
            x: px + offsetX,
            y: player.location.y,
            z: pz + offsetZ
          };
        }


        system.runTimeout(() => {
          plant.addEffect("minecraft:invisibility", 20, { showParticles: false });
        }, 28);
        try {
          system.runTimeout(() => {
            plant.teleport(
              targetPos,
              {
                dimension: dimension,
                rotation: { x: 0, y: 0 }
              }
            );
            plant.playAnimation("animation.dcarnivorous_plant.spawn");

            if (enableBarrage) {
              startAttackBarrage(plant, player, dimension);
            }
          }, 32);
        } catch { }

        index++;
      }
    }
  }
}

function startAttackBarrage(plant, player, dimension) {
  let ticks = 0;
  const maxTicks = 5 * 20; // 5 segundos

  const tickInterval = system.runInterval(() => {
    ticks += 20;

    // Solo aplica si aún está cerca
    try {
      const dx = player.location.x - plant.location.x;
      const dz = player.location.z - plant.location.z;
      const distance = Math.sqrt(dx * dx + dz * dz);

      if (distance < 5) {
        player.addEffect("minecraft:poison", 120, { amplifier: 255, showParticles: true });
      }
    } catch (e) { }
    if (ticks >= maxTicks) {
      system.clearRun(tickInterval);
    }
  }, 20); // Cada 1 segundo
}

/* === FUNCIONES AUXILIARES === */

function retreatFromPlayer(mob, playerPos) {
  const mobPos = mob.location;
  const dx = mobPos.x - playerPos.x;
  const dz = mobPos.z - playerPos.z;
  const len = Math.sqrt(dx * dx + dz * dz);
  if (len === 0) return;

  const nx = dx / len;
  const nz = dz / len;

  mob.applyImpulse({ x: nx * 0.4, y: 0, z: nz * 0.4 });
}

function attackPlayer(mob, player) {
  const mobPos = mob.location;
  const dx = player.location.x - mobPos.x;
  const dz = player.location.z - mobPos.z;
  const len = Math.sqrt(dx * dx + dz * dz);
  if (len === 0) return;

  const nx = dx / len;
  const nz = dz / len;

  mob.applyImpulse({ x: nx * 0.8, y: 0, z: nz * 0.8 });
}

system.runInterval(() => {
  for (const dimId of DIMENSIONS) {
    const dimension = world.getDimension(dimId);
    ai_control(dimension);
    stone_guard_ai(dimension);
  }
}, 5); // Cada 5 tick


system.runInterval(() => {
  for (const dimId of DIMENSIONS) {
    const dimension = world.getDimension(dimId);
    carnivorous_plant(dimension); // Ahora sí incluida correctamente
  }
}, 100); // Cada 5 ticks
