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

system.runInterval(() => {
  // Get all crates in the world
  let crates = world
    .getDimension("overworld")
    .getEntities({ families: ["pb_dino_crate"] });
  crates = crates.concat(
    world.getDimension("nether").getEntities({ families: ["pb_dino_crate"] })
  );
  crates = crates.concat(
    world.getDimension("the_end").getEntities({ families: ["pb_dino_crate"] })
  );
  crates.forEach((crate) => {
    // Check if crate has a dino or lead attached
    const riders = crate.getComponent("rideable").getRiders().length;
    const attached = crate.getComponent("leashable").isLeashed;
    // Stop if no dino or lead attached
    if (riders == 0 || attached) return;
    // If crate has a dino and is not attached - get all helicopters nearby
    if (riders > 0 && !attached) {
      let helicopters = crate.dimension.getEntities({
        location: crate.location,
        maxDistance: 4,
        closest: 1,
        families: ["pb_dino_helicopter"],
      });
      // Check if the helicopter has cargo or a driver
      helicopters.forEach((helicopter) => {
        // Detect property to see if already has cargo
        const hasCargo = helicopter.getProperty("pb_dino:cargo_active");
        // CHeck if helicopter has driver
        const driver = helicopter.getComponent("rideable").getRiders().length;
        // If the helicopter has cargo, or no driver, stop
        if (hasCargo == true || driver == 0) return;
        // if the helicopter has no cargo and has a driver, attach the crate to the helicopter with a lead
        if (hasCargo == false && driver > 0) {
          // Leash to helicopter
          crate.getComponent("leashable").leashTo(helicopter);
          // Set helicopter component to true (using event)
          helicopter.triggerEvent("pb_dino:cargo_active");
          // set property of crate to be that of the helicopter ID
          crate.setDynamicProperty("leash_holder", helicopter.id);
          helicopter.setDynamicProperty("crateId", crate.id);
        }
      });
    }
  });
}, 40);

//process script events
system.afterEvents.scriptEventReceive.subscribe((eventData) => {
  //id is for the id of the script command - sourceEntity is the entity that run the script command
  const { id, sourceEntity } = eventData;
  if (sourceEntity == null) return;
  // Lead check from crate a/c
  if (id == "pb_dino:leash_broken") {
    const leashHolderID = sourceEntity.getDynamicProperty("leash_holder");
    const leashHolder = getEntityByID(
      sourceEntity,
      "pb_dino:helicopter",
      leashHolderID
    );

    if (leashHolder == undefined) return;
    leashHolder.triggerEvent("pb_dino:cargo_inactive");
    return;
  }
  // Drop Cargo run from helicopter a/c
  if (id == "pb_dino:drop_cargo") {
    const crateId = sourceEntity.getDynamicProperty("crateId");
    const crate = getEntityByID(
      sourceEntity,
      "pb_dino:crate",
      crateId
    )
    if (crateId == undefined) return;
    crate.getComponent("leashable").unleash();
    crate.triggerEvent("pb_dino:airdrop");
    crate.addEffect("slow_falling", 200, {
      amplifier: 0,
      showParticles: false,
    });
    return;
  }
});
function getEntityByID(sourceEntity, type, id) {
  const entities = sourceEntity.dimension.getEntities({ type: type });
  let targetentity;
  entities.forEach((entity) => {
    if (entity.id == id) targetentity = entity;
  });
  return targetentity;
}
