import { world, system, ItemStack, BlockPermutation, EquipmentSlot, EntityComponentTypes } from "@minecraft/server";
import { altarSequencePlayers } from "../main.js";
import * as Good from "../xp/good.js";
import * as Evil from "../xp/evil.js";

const originalBlocks = new Map();

export default function altarSequence(affiliation, altarType, altar, player, conflict) {
  const direction = altar.permutation.getState("minecraft:cardinal_direction");
  var newPermutation;
  let playerAlive = true;

  // Add player to the altarSequencePlayers map
  altarSequencePlayers.set(player.id, true);

  // Function to handle player death
  function handlePlayerDeath() {
    playerAlive = false;
    newPermutation = BlockPermutation.resolve(altar.typeId, {
      "float_ad:state": 0,
      "float_ad:sequence": false,
      "float_ad:type": altarType,
      "minecraft:cardinal_direction": direction,
      "float_ad:broken": true,
    });
    altar.setPermutation(newPermutation);
    player.runCommand(`particle float_ad:shrine_break ${altar.location.x} ${altar.location.y} ${altar.location.z}`);
    player.runCommand("event entity @e[type=float_ad:altar_wisp,r=40] float_ad:kill_entity");
    player.runCommand("event entity @e[type=float_ad:elemental_golem,r=80] float_ad:despawn");
    revertBlocks();
    // Remove player from the altarSequencePlayers map
    player.playSound("float_ad.altar_broken");
    altarSequencePlayers.delete(player.id);
  }

  // Periodically check if the player is still alive
  const checkPlayerAliveInterval = system.runInterval(() => {
    if (!playerAlive) {
      handlePlayerDeath();
      system.clearRun(checkPlayerAliveInterval);
      system.clearRun(repeatingSoundInterval);
      return;
    }

    const distance = Math.sqrt(
      Math.pow(player.location.x - altar.location.x, 2) +
        Math.pow(player.location.y - altar.location.y, 2) +
        Math.pow(player.location.z - altar.location.z, 2)
    );

    if (distance > 25) {
      handlePlayerDeath();
      system.clearRun(checkPlayerAliveInterval);
      system.clearRun(repeatingSoundInterval);
    }
  }, 20); // Check every second (20 ticks)

  // Play repeating sound every 4 seconds
  const repeatingSoundInterval = system.runInterval(() => {
    if (!playerAlive) {
      system.clearRun(repeatingSoundInterval);
      return;
    }
    player.runCommand(
      `playsound float_ad.altar_${affiliation}_in_progress @a ${altar.location.x} ${altar.location.y} ${altar.location.z}`
    );
  }, 80); // 4 seconds (80 ticks)

  if (!altar.permutation.getState("float_ad:sequence")) {
    if (
      altar.permutation.getState("float_ad:state") == 0 ||
      altar.permutation.getState("float_ad:evil") ||
      altar.permutation.getState("float_ad:good")
    ) {
      player.runCommand(`summon float_ad:altar_wisp ${altar.location.x} ${altar.location.y + 0.1} ${altar.location.z}`);
      newPermutation = BlockPermutation.resolve(altar.typeId, {
        "float_ad:state": affiliation == "good" ? 1 : 2,
        "float_ad:sequence": true,
        "minecraft:cardinal_direction": direction,
        "float_ad:type": altarType,
      });
      altar.setPermutation(newPermutation);
      player.runCommand(`event entity @e[type=float_ad:altar_wisp,r=10] float_ad:set_${affiliation}`);
      player.runCommand("event entity @e[type=float_ad:altar_wisp,r=10] float_ad:start_sequence");
      if (affiliation === "good") {
        player.runCommand(
          `playsound float_ad.altar_good_trigger @a ${altar.location.x} ${altar.location.y} ${altar.location.z}`
        );
      } else if (affiliation === "evil") {
        player.runCommand(
          `playsound float_ad.altar_evil_trigger @a ${altar.location.x} ${altar.location.y} ${altar.location.z}`
        );
      }

      if (affiliation == "evil") spreadEvil(2, altar.location, altarType); // Initial spread

      switch (altarType) {
        case 0:
          altarType0Seq(
            affiliation,
            altarType,
            altar,
            player,
            playerAlive,
            conflict,
            checkPlayerAliveInterval,
            repeatingSoundInterval
          );
          break;
        case 1:
          altarType1Seq(
            affiliation,
            altarType,
            altar,
            player,
            playerAlive,
            conflict,
            checkPlayerAliveInterval,
            repeatingSoundInterval
          );
          break;
        case 2:
          altarType2Seq(
            affiliation,
            altarType,
            altar,
            player,
            playerAlive,
            conflict,
            checkPlayerAliveInterval,
            repeatingSoundInterval
          );
          break;
        case 3:
          altarType3Seq(
            affiliation,
            altarType,
            altar,
            player,
            playerAlive,
            conflict,
            checkPlayerAliveInterval,
            repeatingSoundInterval
          );
          break;
        default:
          console.error("Invalid altar type");
      }
    } else {
      console.error("Player is Neutral");
      system.clearRun(repeatingSoundInterval);
      system.clearRun(checkPlayerAliveInterval);
      altarSequencePlayers.delete(player.id);
    }
  } else {
    handlePlayerDeath();
  }
}

function findSuitableLocation(baseLocation) {
  const dimension = world.getDimension("overworld");
  const radius = 10; // Radius to search for a suitable location

  for (let y = baseLocation.y - 4; y <= baseLocation.y + 4; y++) {
    for (let x = baseLocation.x - radius; x <= baseLocation.x + radius; x++) {
      for (let z = baseLocation.z - radius; z <= baseLocation.z + radius; z++) {
        const blockBelow = dimension.getBlock({ x, y: y - 1, z });
        const blockAbove = dimension.getBlock({ x, y: y + 1, z });
        if (blockBelow && blockBelow.type !== "minecraft:air" && blockAbove && blockAbove.type === "minecraft:air") {
          console.error(`Suitable location found at ${(x, y, z)}`);
          return { x, y, z };
        }
      }
    }
  }

  return baseLocation; // Fallback to base location if no suitable location is found
}

function spreadEvil(radius, location, altarType) {
  const dimension = world.getDimension("overworld");
  const blocksToReplace = ["minecraft:dirt", "minecraft:grass_path", "minecraft:gravel", "minecraft:grass_block"];
  const grassToReplace = ["minecraft:short_grass"];
  const flowersToReplace = [
    "minecraft:dandelion",
    "minecraft:poppy",
    "minecraft:blue_orchid",
    "minecraft:allium",
    "minecraft:azure_bluet",
    "minecraft:red_tulip",
    "minecraft:orange_tulip",
    "minecraft:white_tulip",
    "minecraft:pink_tulip",
    "minecraft:oxeye_daisy",
    "minecraft:cornflower",
    "minecraft:lily_of_the_valley",
  ];
  const maxRadius = altarType === 3 ? 10 : altarType === 2 ? 8 : altarType === 1 ? 6 : 4;

  for (let x = location.x - radius; x <= location.x + radius; x++) {
    for (let z = location.z - radius; z <= location.z + radius; z++) {
      for (let y = location.y - 3; y <= location.y + 3; y++) {
        const block = dimension.getBlock({ x, y, z });
        if (block) {
          const blockType = block.typeId;
          if (blocksToReplace.includes(blockType)) {
            originalBlocks.set(`${x},${y},${z}`, blockType);
            block.setType("minecraft:crimson_nylium");
          } else if (grassToReplace.includes(blockType)) {
            originalBlocks.set(`${x},${y},${z}`, blockType);
            block.setType("minecraft:crimson_roots");
          } else if (flowersToReplace.includes(blockType)) {
            originalBlocks.set(`${x},${y},${z}`, blockType);
            block.setType("minecraft:crimson_fungus");
          }
        }
      }
    }
  }

  if (radius < maxRadius) {
    system.runTimeout(() => spreadEvil(radius + 1, location, altarType), 200);
  }
}

function revertBlocks() {
  const dimension = world.getDimension("overworld");
  originalBlocks.forEach((type, coords) => {
    const [x, y, z] = coords.split(",").map(Number);
    const block = dimension.getBlock({ x, y, z });
    if (block) {
      block.setType(type);
    }
  });
  originalBlocks.clear();
}

function altarType0Seq(
  affiliation,
  altarType,
  altar,
  player,
  playerAlive,
  conflict,
  checkPlayerAliveInterval,
  repeatingSoundInterval
) {
  var newPermutation;
  let shouldContinue = true; // Flag to control execution of further timeouts
  summonWisps(affiliation, altar, player);
  const summonLocation = findSuitableLocation({ x: altar.location.x, y: altar.location.y, z: altar.location.z + 8 });
  if (!conflict) {
    player.runCommand(
      `summon float_ad:elemental_golem ${summonLocation.x} ${summonLocation.y} ${summonLocation.z} 180 0`
    );
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:turn_${affiliation}`
      );
    }, 5);
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:activate`
      );
    }, 20);
  }
  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar1_1" ${altar.location.x - 5} ${altar.location.y - 1} ${
          altar.location.z - 5
        } 0_degrees none`
      );
      if (affiliation == "evil") spreadEvil(3, altar.location, altarType); // Increase spread radius
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 200);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar1_2" ${altar.location.x - 5} ${altar.location.y - 1} ${
          altar.location.z - 5
        } 0_degrees none`
      );
      if (affiliation == "evil") spreadEvil(4, altar.location, altarType); // Increase spread radius
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 400);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar1_3" ${altar.location.x - 5} ${altar.location.y - 1} ${
          altar.location.z - 5
        } 0_degrees none`
      );
      if (affiliation == "evil") spreadEvil(5, altar.location, altarType); // Increase spread radius
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 600);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar1_4" ${altar.location.x - 5} ${altar.location.y - 1} ${
          altar.location.z - 5
        } 0_degrees none`
      );
      system.runTimeout(() => {
        if (!playerAlive) return; // Exit if the player is dead
        player.runCommand(
          `event entity @e[type=float_ad:elemental_golem,x=${altar.location.x},y=${altar.location.y},z=${
            altar.location.z + 8
          },r=30] float_ad:turn_${affiliation}`
        );
      }, 5);
      newPermutation = BlockPermutation.resolve(altar.typeId, {
        "float_ad:state": affiliation == "good" ? 1 : 2,
        "float_ad:sequence": false,
        "minecraft:cardinal_direction": altar.permutation.getState("minecraft:cardinal_direction"),
        "float_ad:type": altar.permutation.getState("float_ad:type"),
        [`float_ad:${affiliation}`]: true,
      });
      if (affiliation === "good") {
        player.playSound("float_ad.altar_good_complete");
        Good.progress(player, 100);
      } else {
        player.playSound("float_ad.altar_evil_complete");
        Evil.progress(player, 100);
      }
      player.runCommand(`event entity @e[type=float_ad:altar_wisp,r=20] float_ad:set_${affiliation}`);
      player.runCommand("event entity @e[type=float_ad:altar_wisp,r=20] float_ad:end_sequence");
      player.runCommand(
        `particle float_ad:xp_gain_100 ${altar.location.x} ${altar.location.y + 1} ${altar.location.z}`
      );
      altar.setPermutation(newPermutation);
      player.runCommand(
        `loot spawn ${altar.location.x} ${altar.location.y + 1} ${altar.location.z} loot "float/ad/${
          affiliation === "good" ? "crystalised_light_two" : "infernal_shard_two"
        }"`
      );
      // Remove player from the altarSequencePlayers map
      altarSequencePlayers.delete(player.id);
      system.clearRun(repeatingSoundInterval);
      system.clearRun(checkPlayerAliveInterval);
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 800);
}

function altarType1Seq(
  affiliation,
  altarType,
  altar,
  player,
  playerAlive,
  conflict,
  checkPlayerAliveInterval,
  repeatingSoundInterval
) {
  var newPermutation;
  let shouldContinue = true; // Flag to control execution of further timeouts
  summonWisps(affiliation, altar, player);
  const summonLocation = findSuitableLocation({ x: altar.location.x, y: altar.location.y, z: altar.location.z + 8 });
  if (!conflict) {
    player.runCommand(
      `summon float_ad:elemental_golem ${summonLocation.x} ${summonLocation.y} ${summonLocation.z} 180 0`
    );
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:turn_${affiliation}`
      );
    }, 5);
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:activate`
      );
    }, 20);
  }
  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar2_1" ${altar.location.x - 2} ${altar.location.y - 1} ${
          altar.location.z - 2
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 200);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar2_2" ${altar.location.x - 2} ${altar.location.y - 1} ${
          altar.location.z - 2
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 400);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar2_3" ${altar.location.x - 2} ${altar.location.y - 1} ${
          altar.location.z - 2
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 600);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar2_4" ${altar.location.x - 2} ${altar.location.y - 1} ${
          altar.location.z - 2
        } 0_degrees none`
      );
      newPermutation = BlockPermutation.resolve(altar.typeId, {
        "float_ad:state": affiliation == "good" ? 1 : 2,
        "float_ad:sequence": false,
        "minecraft:cardinal_direction": altar.permutation.getState("minecraft:cardinal_direction"),
        "float_ad:type": altar.permutation.getState("float_ad:type"),
        [`float_ad:${affiliation}`]: true,
      });
      if (affiliation === "good") {
        player.playSound("float_ad.altar_good_complete");
        Good.progress(player, 100);
      } else {
        player.playSound("float_ad.altar_evil_complete");
        Evil.progress(player, 100);
      }
      player.runCommand(`event entity @e[type=float_ad:altar_wisp,r=20] float_ad:set_${affiliation}`);
      player.runCommand("event entity @e[type=float_ad:altar_wisp,r=20] float_ad:end_sequence");
      player.runCommand(
        `particle float_ad:xp_gain_100 ${altar.location.x} ${altar.location.y + 1} ${altar.location.z}`
      );
      altar.setPermutation(newPermutation);
      player.runCommand(
        `loot spawn ${altar.location.x} ${altar.location.y + 1} ${altar.location.z} loot "float/ad/${
          affiliation === "good" ? "crystalised_light_two" : "infernal_shard_two"
        }"`
      );
      // Remove player from the altarSequencePlayers map
      altarSequencePlayers.delete(player.id);
      system.clearRun(repeatingSoundInterval);
      system.clearRun(checkPlayerAliveInterval);
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 800);
}

function altarType2Seq(affiliation, altarType, altar, player, playerAlive, conflict, checkPlayerAliveInterval) {
  let shouldContinue = true; // Flag to control execution of further timeouts
  var newPermutation;
  summonWisps(affiliation, altar, player);
  const summonLocation = findSuitableLocation({ x: altar.location.x, y: altar.location.y, z: altar.location.z + 8 });
  if (!conflict) {
    player.runCommand(
      `summon float_ad:elemental_golem ${summonLocation.x} ${summonLocation.y} ${summonLocation.z} 180 0`
    );
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:turn_${affiliation}`
      );
    }, 5);
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:activate`
      );
    }, 20);
  }
  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar3_1" ${altar.location.x - 3} ${altar.location.y - 1} ${
          altar.location.z - 3
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 200);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar3_2" ${altar.location.x - 3} ${altar.location.y - 1} ${
          altar.location.z - 3
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 400);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar3_3" ${altar.location.x - 3} ${altar.location.y - 1} ${
          altar.location.z - 3
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 600);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar3_4" ${altar.location.x - 3} ${altar.location.y - 1} ${
          altar.location.z - 3
        } 0_degrees none`
      );
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${altar.location.x},y=${altar.location.y},z=${
          altar.location.z + 8
        },r=30] float_ad:turn_${affiliation}`
      );
      newPermutation = BlockPermutation.resolve(altar.typeId, {
        "float_ad:state": affiliation == "good" ? 1 : 2,
        "float_ad:sequence": false,
        "minecraft:cardinal_direction": altar.permutation.getState("minecraft:cardinal_direction"),
        "float_ad:type": altar.permutation.getState("float_ad:type"),
        [`float_ad:${affiliation}`]: true,
      });
      if (affiliation === "good") {
        player.playSound("float_ad.altar_good_complete");
        Good.progress(player, 100);
      } else {
        player.playSound("float_ad.altar_evil_complete");
        Evil.progress(player, 100);
      }
      player.runCommand(`event entity @e[type=float_ad:altar_wisp,r=20] float_ad:set_${affiliation}`);
      player.runCommand("event entity @e[type=float_ad:altar_wisp,r=20] float_ad:end_sequence");
      player.runCommand(
        `particle float_ad:xp_gain_100 ${altar.location.x} ${altar.location.y + 1} ${altar.location.z}`
      );
      altar.setPermutation(newPermutation);
      player.runCommand(
        `loot spawn ${altar.location.x} ${altar.location.y + 1} ${altar.location.z} loot "float/ad/${
          affiliation === "good" ? "crystalised_light_two" : "infernal_shard_two"
        }"`
      );
      // Remove player from the altarSequencePlayers map
      altarSequencePlayers.delete(player.id);
      system.clearRun(repeatingSoundInterval);
      system.clearRun(checkPlayerAliveInterval);
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 800);
}

function altarType3Seq(
  affiliation,
  altarType,
  altar,
  player,
  playerAlive,
  conflict,
  checkPlayerAliveInterval,
  repeatingSoundInterval
) {
  var newPermutation;
  let shouldContinue = true; // Flag to control execution of further timeouts
  summonWisps(affiliation, altar, player);
  const summonLocation = findSuitableLocation({ x: altar.location.x, y: altar.location.y, z: altar.location.z + 8 });
  if (!conflict) {
    player.runCommand(
      `summon float_ad:elemental_golem ${summonLocation.x} ${summonLocation.y} ${summonLocation.z} 180 0`
    );
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:turn_${affiliation}`
      );
    }, 5);
    system.runTimeout(() => {
      if (!playerAlive) return; // Exit if the player is dead
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${summonLocation.x},y=${summonLocation.y},z=${summonLocation.z},r=4] float_ad:activate`
      );
    }, 20);
  }
  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar4_1" ${altar.location.x - 5} ${altar.location.y - 2} ${
          altar.location.z - 5
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 200);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar4_2" ${altar.location.x - 5} ${altar.location.y - 2} ${
          altar.location.z - 5
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 400);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      summonWisps(affiliation, altar, player);
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar4_3" ${altar.location.x - 5} ${altar.location.y - 2} ${
          altar.location.z - 5
        } 0_degrees none`
      );
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 600);

  system.runTimeout(() => {
    if (!shouldContinue || !playerAlive) return; // Exit if the sequence is halted or player is dead
    const currentPermutation = altar.permutation;
    if (currentPermutation.getState("float_ad:sequence")) {
      player.runCommand(
        `structure load "float_ad/${affiliation}_altar4_4" ${altar.location.x - 5} ${altar.location.y - 2} ${
          altar.location.z - 5
        } 0_degrees none`
      );
      player.runCommand(
        `event entity @e[type=float_ad:elemental_golem,x=${altar.location.x},y=${altar.location.y},z=${
          altar.location.z + 8
        },r=30] float_ad:turn_${affiliation}`
      );
      newPermutation = BlockPermutation.resolve(altar.typeId, {
        "float_ad:state": affiliation == "good" ? 1 : 2,
        "float_ad:sequence": false,
        "minecraft:cardinal_direction": altar.permutation.getState("minecraft:cardinal_direction"),
        "float_ad:type": altar.permutation.getState("float_ad:type"),
        [`float_ad:${affiliation}`]: true,
      });
      if (affiliation === "good") {
        player.playSound("float_ad.altar_good_complete");
        Good.progress(player, 100);
      } else {
        player.playSound("float_ad.altar_evil_complete");
        Evil.progress(player, 100);
      }
      player.runCommand(`event entity @e[type=float_ad:altar_wisp,r=20] float_ad:set_${affiliation}`);
      player.runCommand("event entity @e[type=float_ad:altar_wisp,r=20] float_ad:end_sequence");
      player.runCommand(
        `particle float_ad:xp_gain_100 ${altar.location.x} ${altar.location.y + 1} ${altar.location.z}`
      );
      altar.setPermutation(newPermutation);
      player.runCommand(
        `loot spawn ${altar.location.x} ${altar.location.y + 1} ${altar.location.z} loot "float/ad/${
          affiliation === "good" ? "crystalised_light_two" : "infernal_shard_two"
        }"`
      );
      // Remove player from the altarSequencePlayers map
      altarSequencePlayers.delete(player.id);
      system.clearRun(repeatingSoundInterval);
      system.clearRun(checkPlayerAliveInterval);
    } else {
      shouldContinue = false; // Halt further execution
      return;
    }
  }, 800);
}

function summonWisps(affiliation, altar, player) {
  if (affiliation == "good") {
    player.runCommand(
      `summon float_ad:wisp ${altar.location.x - 5} ${altar.location.y + 4} ${altar.location.z - 5} 180 0`
    );
    player.runCommand(
      `summon float_ad:wisp ${altar.location.x + 5} ${altar.location.y + 4} ${altar.location.z + 5} 180 0`
    );
    system.runTimeout(() => {
      player.runCommand(
        `event entity @e[type=float_ad:wisp,x=${altar.location.x},y=${altar.location.y},z=${altar.location.z},r=20] float_ad:set_evil`
      );
    }, 4);
  } else {
    player.runCommand(
      `summon float_ad:wisp ${altar.location.x + 5} ${altar.location.y + 5} ${altar.location.z + 5} 0 0`
    );
    player.runCommand(
      `summon float_ad:wisp ${altar.location.x - 5} ${altar.location.y + 4} ${altar.location.z - 5} 180 0`
    );
    system.runTimeout(() => {
      player.runCommand(
        `event entity @e[type=float_ad:wisp,x=${altar.location.x},y=${altar.location.y},z=${altar.location.z},r=20] float_ad:set_good`
      );
    }, 4);
  }
  system.runTimeout(() => {
    player.runCommand(
      `event entity @e[type=float_ad:wisp,x=${altar.location.x},y=${altar.location.y},z=${altar.location.z},r=20] float_ad:player_hostile`
    );
  }, 4);
}
