import { world, system } from "@minecraft/server";
import {
  findEntityBelow,
  carryEntity,
  getCarriedEntity,
  releaseCarriedEntity,
  tooFarFromUfo,
  getHoverHeightForEntity,
} from "./vehicleUFOTractorUtils.js";

const UFO_FAMILY = "pb_plane_ufo";

system.runInterval(() => {
  const dimensions = ["overworld", "nether", "the_end"];
  const ufos = [];

  for (const dimName of dimensions) {
    const dim = world.getDimension(dimName);
    ufos.push(...dim.getEntities({ families: [UFO_FAMILY] }));
  }

  for (const ufo of ufos) {
    let tractorActive = ufo.getProperty("pb_plane:tractor_active") === true;
    let isCarrying = ufo.getProperty("pb_plane:tractor_carrying") === true;

    const riders = ufo.getComponent("minecraft:rideable")?.getRiders() ?? [];
    const hasRider = riders.length > 0;

    if (!hasRider && isCarrying) {
      //console.warn(`UFO ${ufo.id} has no rider — releasing carried entity.`);
      releaseCarriedEntity(ufo);
      ufo.setProperty("pb_plane:tractor_active", false);
      ufo.setProperty("pb_plane:tractor_carrying", false);
      continue;
    }

    // 🚜 Try to pick something up
    if (tractorActive && !isCarrying) {
      const target = findEntityBelow(ufo);
      if (target) {
        carryEntity(ufo, target);

        // ✅ Initialize lift_progress
        target.setDynamicProperty("lift_progress", 0);

        ufo.setProperty("pb_plane:tractor_carrying", true);
        isCarrying = true;
      }
    }

    // 🛰 Keep the carried entity hovering
    if (isCarrying) {
      const carried = getCarriedEntity(ufo);

      if (!carried || !carried.isValid()) {
        releaseCarriedEntity(ufo);
        ufo.setProperty("pb_plane:tractor_active", false);
        ufo.setProperty("pb_plane:tractor_carrying", false);
        continue;
      }

      let carriedTicks = carried.getDynamicProperty("carried_ticks") ?? 0;

      const skipTooFarCheck = carriedTicks < 20;

      if (!skipTooFarCheck && tooFarFromUfo(ufo, carried)) {
        releaseCarriedEntity(ufo);
        ufo.setProperty("pb_plane:tractor_active", false);
        ufo.setProperty("pb_plane:tractor_carrying", false);
        continue;
      }

      const ufoLoc = ufo.location;
      const hoverHeight = getHoverHeightForEntity(carried);
      const targetY = ufoLoc.y - hoverHeight;

      // 📌 Store initial Y only once
      let baseY = carried.getDynamicProperty("initial_lift_y");
      if (typeof baseY !== "number") {
        baseY = carried.location.y;
        carried.setDynamicProperty("initial_lift_y", baseY);
      }

      // 🪜 Gradual lift
      let liftProgress = carried.getDynamicProperty("lift_progress") ?? 0;
      if (typeof liftProgress !== "number") liftProgress = 0;

      const LIFT_SPEED = 0.02; // try values between 0.01 and 0.05 for slower lift
      liftProgress = Math.min(liftProgress + LIFT_SPEED, 1);
      carried.setDynamicProperty("lift_progress", liftProgress);
      carried.setDynamicProperty("carried_ticks", carriedTicks + 1);

      // Skip teleport if we haven't initialized baseY yet
      if (typeof baseY === "number") {
        const smoothY = baseY + (targetY - baseY) * liftProgress;

        // Only check for air if we're near the UFO
        const closeToUfo = targetY - smoothY < 1;

        let safeY = smoothY;

        if (closeToUfo) {
          const belowBlock = ufo.dimension.getBlock({
            x: Math.floor(ufoLoc.x),
            y: Math.floor(smoothY - 0.9),
            z: Math.floor(ufoLoc.z),
          });

          if (belowBlock && belowBlock.typeId !== "minecraft:air") {
            // fallback to UFO Y if not safe
            safeY = ufoLoc.y;
          }
        }

        carried.teleport(
          {
            x: ufoLoc.x,
            y: safeY,
            z: ufoLoc.z,
          }
        );
      }

      // 🧹 Ensure state
      ufo.setProperty("pb_plane:tractor_carrying", true);
    } else {
      ufo.setProperty("pb_plane:tractor_carrying", false);
    }

    if (!tractorActive) {
      ufo.setProperty("pb_plane:tractor_active", false);
    }
  }
});
