import { world, system, Player, BlockPermutation, Block, BlockVolume } from "@minecraft/server";
import { MAPS, COMPANY_MOODS } from "./data";
import {
  OVERWORLD,
  SOUND_OPTIONS,
  worldPlayers,
  convertToTicks,
  shipEntity,
  updateShipVol,
  creditsScoreboard,
  main,
  findShip,
  startWeather,
  spawnDaytimeEntities,
  spawnTrees,
  updateWeight,
  lockItems,
  unlockItems,
  moveBarber,
  initializePlayer,
} from "./main";

import { applyDiscount, setWeather, updateProfitDisplay, calculateOvertimeBonus, calculateNewQuota } from "./terminal";
import { convertValueToUi } from "./ui";

let bodiesRecovered = 0
let penaltyPercent = 0
let bodiesNotRecovered = 0
let deadPlayers = 0

export function saveShipEntities() {
  if (!shipEntity) return;

  worldPlayers.forEach((player) => {
    lockItems(player);
  });

  const shipLocation = shipEntity.location;
  console.warn(`saving`);

  let searchLocation = {
    x: Number((shipLocation.x + 0.5).toFixed(2)),
    y: Number(shipLocation.y.toFixed(2)),
    z: Number((shipLocation.z - 4 + 0.5).toFixed(2)),
  };

  const inOrbit = world.getDynamicProperty("inOrbit");
  if (inOrbit == true) {
    searchLocation.y += 44;
    searchLocation.z -= 41;
  } else {
    searchLocation.z -= 1;
  }

  let killerLocation = {
    x: shipLocation.x,
    y: shipLocation.y + 2,
    z: shipLocation.z - 11,
  };
  if (inOrbit == true) {
    killerLocation.y += 44;
    killerLocation.z -= 40;
  }

  const killerLocationStart = {
    x: killerLocation.x + 1,
    y: killerLocation.y,
    z: killerLocation.z,
  };
  const killerLocationEnd = {
    x: killerLocation.x - 1,
    y: killerLocation.y,
    z: killerLocation.z,
  };


  const fillVol = new BlockVolume(killerLocationStart, killerLocationEnd);
  OVERWORLD.fillBlocks(fillVol, "js:particle_killer", { blockFilter: { includeTypes: ["minecraft:air"] } });

  const entities = OVERWORLD.getEntities({ location: searchLocation, maxDistance: 8 });

  const shipVol = updateShipVol();

  let tempShipEntities = {};
  for (let entity of entities) {
    const entityLocation = entity.location;
    if (shipVol.isInside(entityLocation) == false) continue;

    let entityId = entity.typeId;
    if (entityId == "js:ship") continue;
    if (entityId == "js:circuit_bees") continue;
    if (entityId == "js:eyeless_dog") continue
    if (entityId == "js:eyeless_dog_dead") continue
    if (entityId == "js:old_bird") continue
    if (entityId == "js:wandering_locusts") continue

    if (entityId == "js:body_ent") {
      bodiesRecovered++
      entity.remove();
      continue;
    }

    if (entityId == "minecraft:player") {
      entityId = entity.nameTag;
    }
    const v = entity.getDynamicProperty("scrapValue") ?? 0;
    const b = entity.getDynamicProperty("battery") ?? 0;
    const c = entity.getDynamicProperty("collected") ?? false;
    const l = {
      x: Number((entityLocation.x - searchLocation.x).toFixed(2)),
      y: Number((entityLocation.y - searchLocation.y).toFixed(2)),
      z: Number((entityLocation.z - searchLocation.z).toFixed(2)),
    };
    const j = entity.getDynamicProperty("jetpackBroken") ?? false;
    const a = entity.getDynamicProperty("bullets") ?? 0;
    const s = entity.getDynamicProperty("safetyOn") ?? false;


    if (!tempShipEntities.hasOwnProperty(entityId)) {
      tempShipEntities[entityId] = [];
    }
    tempShipEntities[entityId].push([v, b, l, c, j, a, s]);
    if (entityId.startsWith("js:")) {
      entity.remove();
    }
  }

  world.setDynamicProperty("shipEntities", JSON.stringify(tempShipEntities));
  console.warn(JSON.stringify(tempShipEntities));
}

export function loadShipEntities() {
  const shipEntitiesJson = world.getDynamicProperty("shipEntities");
  const shipEntities = JSON.parse(shipEntitiesJson);

  console.warn(`loading`);
  console.warn(JSON.stringify(shipEntities));

  const shipLocation = shipEntity.location;

  let searchLocation = {
    x: Number((shipLocation.x + 0.5).toFixed(2)),
    y: Number(shipLocation.y.toFixed(2)),
    z: Number((shipLocation.z - 4 + 0.5).toFixed(2)),
  };

  const inOrbit = world.getDynamicProperty("inOrbit");
  if (inOrbit == true) {
    searchLocation.y += 44;
    searchLocation.z -= 41;
  } else {
    searchLocation.z -= 1;
  }

  for (let entityId in shipEntities) {
    if (!shipEntities.hasOwnProperty(entityId)) continue;

    const entityDataArray = shipEntities[entityId];
    for (let i = 0; i < entityDataArray.length; i++) {
      const entityData = entityDataArray[i];
      const value = entityData[0];
      const battery = entityData[1];
      const location = entityData[2];
      const collected = entityData[3];
      const jetpackBroken = entityData[4];
      const bullets = entityData[5]
      const safetyOn = entityData[6]

      const spawnLocation = {
        x: searchLocation.x + location.x,
        y: searchLocation.y + location.y,
        z: searchLocation.z + location.z,
      };

      if (entityId.startsWith("js:")) {
        const spawnedEntity = OVERWORLD.spawnEntity(entityId, spawnLocation);
        spawnedEntity.setDynamicProperty("scrapValue", value);
        spawnedEntity.setDynamicProperty("battery", battery);
        spawnedEntity.setDynamicProperty("collected", collected);
        if (entityId == "js:jetpack_ent") {
          spawnedEntity.setDynamicProperty("jetpackBroken", jetpackBroken);
        }
        if (entityId == "js:shotgun_ent") {
          spawnedEntity.setDynamicProperty("bullets", bullets);
          spawnedEntity.setDynamicProperty("safetyOn", safetyOn);
        }
      } else {
        OVERWORLD.runCommand(
          `execute as @a[name="${entityId}"] run tp @s ${spawnLocation.x} ${spawnLocation.y} ${spawnLocation.z} ~ ~`
        );
      }

      entityDataArray.splice(i, 1);
      i--;
    }

    if (entityDataArray.length === 0) {
      delete shipEntities[entityId];
    }
  }
  world.setDynamicProperty("shipEntities", JSON.stringify(shipEntities));
  updateProfitDisplay();

  for (let player of worldPlayers) {
    if (player.state == "dead" || player.state == "missing") {
      player.teleport(searchLocation);
      player.state = "alive";
    }
    player.addEffect("weakness", 20000000, { amplifier: 255, showParticles: false });
    unlockItems(player);
    updateWeight(player)
  }

  system.runTimeout(() => {
    updateProfitDisplay();
  }, 5);
}

export function deleteAllScrapItems() {
  const shipEntitiesJson = world.getDynamicProperty("shipEntities");
  const shipEntities = JSON.parse(shipEntitiesJson);

  let itemsDeleted = false;

  for (let entityId in shipEntities) {
    if (!shipEntities.hasOwnProperty(entityId)) continue;

    const entityDataArray = shipEntities[entityId];
    for (let i = 0; i < entityDataArray.length; i++) {
      const entityData = entityDataArray[i];
      const value = entityData[0];

      if (value > 0) {
        entityDataArray.splice(i, 1);
        i--;
        itemsDeleted = true;
      }
    }

    if (entityDataArray.length === 0) {
      delete shipEntities[entityId];
    }
  }

  if (itemsDeleted) {
    world.setDynamicProperty("shipEntities", JSON.stringify(shipEntities));
  } else {
  }
}

system.afterEvents.scriptEventReceive.subscribe((ev) => {
  const entity = ev.sourceEntity;
  const block = ev.sourceBlock;
  const message = ev.id;
  if (entity) {
    const command = message.split(" ")[0];
    switch (command) {
      case "js:test":
        const testId = ev.message;

        //shipEntities
        if (testId == 1) {
          saveShipEntities();
        }
        if (testId == 2) {
          loadShipEntities();
        }

        break;
      case "js:status":
        const statusId = ev.message;

        //shipEntities
        if (statusId == 1) {
          const shipEntitiesJson = world.getDynamicProperty("shipEntities");
          const shipEntities = JSON.parse(shipEntitiesJson);

          console.warn(JSON.stringify(shipEntities));
        }

        break;
      case "js:shipLoaded":
        updateShipVol();
        updateProfitDisplay();
        //    console.warn(`Ran ship loaded`)
        break;
      case "js:setupShip":
        world.setDynamicProperty("moon", 1);
        world.setDynamicProperty("inOrbit", true);
        world.setDynamicProperty("js:teleporter", false);
        world.setDynamicProperty("js:inverse_teleporter", false);
        world.setDynamicProperty('js:teleporter_cooldown', 0)
        world.setDynamicProperty('js:inverse_teleporter_cooldown', 0)
        world.setDynamicProperty("time", 0);
        world.setTimeOfDay(0);
        OVERWORLD.runCommand(
          `execute as @e[type=js:ship] at @s run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ceiling_lamp`
        );
        OVERWORLD.runCommand(
          `execute as @e[type=js:ship] at @s run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ship_collision`
        );
        OVERWORLD.runCommand(`execute as @e[type=js:ship] at @s run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ladder`);
        system.runTimeout(() => {
          let shipLocation = MAPS["experimentation"].shipLocation;
          OVERWORLD.runCommand(`kill @e[type=js:ship]`);
          OVERWORLD.runCommand(`kill @e[family=scrap]`);

          const orbitLocation = {
            x: shipLocation.x + 0.5,
            y: shipLocation.y + 46,
            z: shipLocation.z - 45 + 0.5,
          };

          for (let player of worldPlayers) {
            initializePlayer(player);
            player.runCommand(`gamemode a @s[tag=!debug]`);
            player.runCommand(`gamemode c @s[tag=debug]`);
            player.teleport(orbitLocation, { rotation: { x: 0, y: 0 } });
            let spawnpoint = OVERWORLD.getBlock({ x: shipLocation.x, y: shipLocation.y, z: shipLocation.z });
            player.setSpawnPoint(spawnpoint);

            player.runCommand(`clear @s`);
            player.runCommand(`function initializeItems`);
            player.runCommand(`effect @s clear`);
            player.setProperty('js:flashlight_state', 0)
            player.setProperty("js:energy", 0);
            player.setProperty('js:has_jetpack', false)
            player.addEffect("weakness", 2000000, { amplifier: 255, showParticles: false });
            player.addEffect("instant_health", 2, { amplifier: 255, showParticles: false });
            updateWeight(player);
          }

          system.runTimeout(() => {
            const spawnLocation = {
              x: shipLocation.x + 0.5,
              y: shipLocation.y,
              z: shipLocation.z + 0.5,
            };
            const ship = OVERWORLD.spawnEntity("js:ship", spawnLocation);

            world.setDynamicProperty("companyMood", "agitated");

            OVERWORLD.runCommand(`execute as @e[type=js:ship] at @s run structure load mystructure:ship ~-6 ~42 ~-54`);

            system.runTimeout(() => {
              OVERWORLD.runCommand(
                `execute as @e[type=js:ship] at @s run fill ~2 ~44 ~-39 ~-2 ~47 ~-39 ding:ship_door_collision`
              );
              findShip();
              
              for (let player of worldPlayers) {
                player.teleport(orbitLocation, { rotation: { x: 0, y: 0 } });
              }
              system.runTimeout(() => {
                world.setDynamicProperty("day", 4);
                world.setDynamicProperty("daysSurvived", 0);
                world.setDynamicProperty("scrapSold", 0);
                world.setDynamicProperty("quota", 130);
                world.setDynamicProperty("quotasFulfilled", 0);
                world.setDynamicProperty('totalRunScrapCollected', 0)
                world.setDynamicProperty('totalRunDeaths', 0)
                world.setDynamicProperty("arachnophobiaMode", false);
                creditsScoreboard.setScore("world", 60);

                applyDiscount();
                setWeather();
                OVERWORLD.runCommand(`scriptevent js:resetDeliveryShip`)
                system.runTimeout(() => {
                  updateProfitDisplay();
                }, 20);

                OVERWORLD.runCommand(`playsound misc.ship.squeak @a`);
                OVERWORLD.runCommand(`playsound game.profit.intro @a`);
              }, 20);
            }, 5);
          }, 20);
        }, 10);
        break;
      case "js:fullReset":
          world.setDynamicProperty("moon", 1);
          world.setDynamicProperty("inOrbit", true);
          world.setDynamicProperty("js:teleporter", false);
          world.setDynamicProperty("js:inverse_teleporter", false);
          world.setDynamicProperty('js:teleporter_cooldown', 0)
          world.setDynamicProperty('js:inverse_teleporter_cooldown', 0)
          world.setDynamicProperty("time", 0);
          world.setTimeOfDay(0);
          OVERWORLD.runCommand(
            `execute as @e[type=js:ship] at @s run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ceiling_lamp`
          );
          OVERWORLD.runCommand(
            `execute as @e[type=js:ship] at @s run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ship_collision`
          );
          OVERWORLD.runCommand(`execute as @e[type=js:ship] at @s run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ladder`);
          system.runTimeout(() => {
            let shipLocation = MAPS["experimentation"].shipLocation;
            OVERWORLD.runCommand(`kill @e[type=js:ship]`);
            OVERWORLD.runCommand(`kill @e[family=scrap]`);

            const orbitLocation = {
              x: shipLocation.x + 0.5,
              y: shipLocation.y + 46,
              z: shipLocation.z - 45 + 0.5,
            };

            for (let player of worldPlayers) {
              player.teleport(orbitLocation, { rotation: { x: 0, y: 0 } });
              let spawnpoint = OVERWORLD.getBlock({ x: shipLocation.x, y: shipLocation.y, z: shipLocation.z });
              player.setSpawnPoint(spawnpoint);

              player.runCommand(`clear @s`);
              player.runCommand(`function initializeItems`);
              player.runCommand(`effect @s clear`);
              player.setProperty('js:flashlight_state', 0)
              player.setProperty("js:energy", 0);
              player.setProperty('js:has_jetpack', false)
              player.addEffect("weakness", 2000000, { amplifier: 255, showParticles: false });
              player.addEffect("instant_health", 2, { amplifier: 255, showParticles: false });
              updateWeight(player);
            }

            system.runTimeout(() => {
              const spawnLocation = {
                x: shipLocation.x + 0.5,
                y: shipLocation.y,
                z: shipLocation.z + 0.5,
              };
              const ship = OVERWORLD.spawnEntity("js:ship", spawnLocation);

              world.setDynamicProperty("companyMood", "agitated");

              OVERWORLD.runCommand(`execute as @e[type=js:ship] at @s run structure load mystructure:ship ~-6 ~42 ~-54`);

              system.runTimeout(() => {
                OVERWORLD.runCommand(
                  `execute as @e[type=js:ship] at @s run fill ~2 ~44 ~-39 ~-2 ~47 ~-39 ding:ship_door_collision`
                );
                findShip();
                
                for (let player of worldPlayers) {
                  player.teleport(orbitLocation, { rotation: { x: 0, y: 0 } });
                }
                system.runTimeout(() => {
                  world.setDynamicProperty("day", 4);
                  world.setDynamicProperty("daysSurvived", 0);
                  world.setDynamicProperty("scrapSold", 0);
                  world.setDynamicProperty("quota", 130);
                  world.setDynamicProperty("quotasFulfilled", 0);
                  world.setDynamicProperty('totalRunScrapCollected', 0)
                  world.setDynamicProperty('totalRunDeaths', 0)
                  world.setDynamicProperty("arachnophobiaMode", false);
                  creditsScoreboard.setScore("world", 60);

                  applyDiscount();
                  setWeather();
                  OVERWORLD.runCommand(`scriptevent js:resetDeliveryShip`)
                  system.runTimeout(() => {
                    updateProfitDisplay();
                  }, 20);

                  OVERWORLD.runCommand(`playsound misc.ship.squeak @a`);
                  OVERWORLD.runCommand(`execute as @a at @s run scriptevent ding:intro`);
                }, 20);
              }, 5);
            }, 20);
          }, 10);
        break;

      case "js:shipEnter":
        const input = ev.message;
        const moonId = world.getDynamicProperty("moon");
        let mapName;
        let shipLocation = { x: 0, y: -60, z: 0 };
        for (const key of Object.keys(MAPS)) {
          if (MAPS[key].id === moonId) {
            mapName = MAPS[key].name;
            shipLocation = MAPS[key].shipLocation;
            break;
          }
        }
        const spawnLocation = {
          x: shipLocation.x + 0.5,
          y: shipLocation.y,
          z: shipLocation.z + 0.5,
        };

        const orbitLocation = {
          x: shipLocation.x + 0.5,
          y: shipLocation.y + 45.5,
          z: shipLocation.z - 43 + 0.5,
        };

        startWeather();

        if (input == 1) {
          console.warn(`Entering ${mapName}`);
          shipEntity.shipLeaving = false
          if (mapName == "The Company Building") {
            entity.runCommand(`summon js:company 1010 62 24 180 0`);
            entity.runCommand(`summon js:bell 1009 62 24 180 0`);
            entity.runCommand(`time set night`);

            const day = world.getDynamicProperty("day");
            if (day == 4) {
              entity.runCommand(`event entity @e[type=js:company] sell30`);
            } else if (day == 3) {
              entity.runCommand(`event entity @e[type=js:company] sell53`);
            } else if (day == 2) {
              entity.runCommand(`event entity @e[type=js:company] sell77`);
            } else if (day <= 1) {
              entity.runCommand(`event entity @e[type=js:company] sell100`);
            }
          }

          const shipVol = updateShipVol();
          saveShipEntities();

          system.run(() => {
            if (moonId == 7 || moonId == 9) {
              world.setTimeOfDay(14000)
            } else if (moonId == 0) {
              world.setTimeOfDay(14000)
            } else {
              world.setTimeOfDay(6000)
            }

            world.setDynamicProperty("inOrbit", false);
            world.setDynamicProperty("scrapCollected", 0);
            world.setDynamicProperty("barberChargeTimer", 2.75);
            moveBarber();

            main.setScore("alivePlayers", worldPlayers.length);

            worldPlayers.forEach((player) => {
              player.camera.clear();
              player.addTag('cutscene')

              let spawnpoint = OVERWORLD.getBlock({ x: shipLocation.x, y: shipLocation.y, z: shipLocation.z });
              player.setSpawnPoint(spawnpoint);

              player.spectatorIndex = undefined;

              player.injuries = 0;
              player.laziness = 0;
              player.paranoia = 0;
              player.profitability = 0;

              player.insanity = 0;

              if (moonId == 7) {
                player.runCommand(`scriptevent js:fog rend_landing`);
              } else if (moonId == 9) {
                player.runCommand(`scriptevent js:fog titan_landing`);
              } else {
                player.runCommand(`scriptevent js:fog outside`);
              }
            });

            system.run(() => {
              entity.setProperty("js:animation", 1);
              entity.runCommand(
                `execute as @s at @s positioned ~ ~44 ~-40 run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ceiling_lamp`
              );
              entity.runCommand(
                `execute as @s at @s positioned ~ ~44 ~-40 run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ship_collision`
              );
              entity.runCommand(
                `execute as @s at @s positioned ~ ~44 ~-40 run fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ladder`
              );

              worldPlayers.forEach((player) => {
                player.addTag("inGame");
                player.runCommand(`gamemode spectator @s`);
                player.runCommand(`inputpermission set @s movement disabled`);
                player.runCommand(`inputpermission set @s camera disabled`);
                player.teleport(shipLocation, { rotation: { x: 0, y: 0 } });

                player.camera.setCamera("minecraft:free", {
                  location: orbitLocation,
                  rotation: { x: 0, y: 0 },
                });
              });

              if (moonId !== 0) {
                let treeMax = 38
                let treeMin = 29
                let treeCount = 30
                let treeType = "js:tree"
                if (moonId == 7) {
                  treeMax = 20
                  treeMin = 13
                }
                if (moonId == 5) {
                  treeMax = 288
                  treeMin = 268
                  treeType = "js:alive_tree"
                }

                if (moonId !== 9 && moonId !== 10 && moonId !== 2) {
                  treeCount = Math.floor(Math.random() * (treeMin - treeMin + 1)) + treeMin;
                } else {
                  treeCount = 0
                }

                // world.sendMessage(`${moonId}, ${treeCount}, ${treeType}`)
                spawnTrees(moonId, treeCount, treeType);
                spawnDaytimeEntities();
              }
            });
          })
        }

        if (input == 2) {
          const newLocation = {
            x: shipLocation.x - 14 + 0.5,
            y: shipLocation.y + 1,
            z: shipLocation.z + 12 + 0.5,
          };

          worldPlayers.forEach((player) => {
            player.camera.setCamera("minecraft:free", {
              location: newLocation,
              rotation: { x: -35, y: -170 },
            });
            system.runTimeout(() => {
              player.camera.setCamera("minecraft:free", {
                location: newLocation,
                rotation: { x: -15, y: -120 },
                easeOptions: {
                  easeType: "InOutQuad",
                  easeTime: 11,
                },
              });
            }, 5);
          });
        }

        if (input == 3) {
          entity.runCommand(`structure load mystructure:ship ~-6 ~-2 ~-14`);
          world.setDynamicProperty("generationPercentage", 0);

          worldPlayers.forEach((player) => {
            player.camera.fade({
              fadeTime: { fadeInTime: 0.25, holdTime: 0.3, fadeOutTime: 0.25 },
            });
            player.uiManager.updateGenerationPercent(0)
          });

          system.runTimeout(() => {
            worldPlayers.forEach((player) => {
              player.camera.clear();
              player.removeTag('cutscene')
  
              player.runCommand(`gamemode a @s[tag=!debug]`);
              player.runCommand(`gamemode c @s[tag=debug]`);
              player.runCommand(`inputpermission set @s movement enabled`);
              player.runCommand(`inputpermission set @s camera enabled`);
              player.runCommand(`scriptevent js:stop_ambience`);
              player.runCommand(`scriptevent js:ambience`);
            });

            system.run(() => {
              entity.setProperty("js:animation", 2);
              entity.setProperty("js:in_orbit", 0);
              system.run(() => {
                loadShipEntities();

                world.setDynamicProperty("scrapCollected", 0);
              });
            });
          }, 0.3 * 20);
        }
        break;
      case "js:shipLeave":
        const input2 = ev.message.split(" ")[0];
        shipEntity.shipLeaving = true

        const leaveReason = ev.message.split(" ")[1];

        const moonId2 = world.getDynamicProperty("moon");
        let mapName2;
        let shipLocation2 = { x: 0, y: -60, z: 0 };
        for (const key of Object.keys(MAPS)) {
          if (MAPS[key].id === moonId2) {
            mapName2 = MAPS[key].name;
            shipLocation2 = MAPS[key].shipLocation;
            break;
          }
        }
        const orbitLocation2 = {
          x: shipLocation2.x + 0.5,
          y: shipLocation2.y + 46,
          z: shipLocation2.z - 43 + 0.5,
        };

        let leaveMessage;
        switch (leaveReason) {
          case "none":
            break;
          case "midnight":
            leaveMessage = "Alert! The autopilot is leaving due to dangerous conditions.";
            break;
          case "allPlayersDead":
            leaveMessage = "Warning! No response detected from crew, which has not returned. Emergency code activated.";
            break;
          default:
            leaveMessage = null;
            break;
        }
        if (leaveMessage) {
          worldPlayers.forEach((player) => {
            player.runCommand(`playsound misc.beep @s`);
            player.runCommand(`tellraw @s {"rawtext": [ { "text": "dingUI:pilot_____${leaveMessage}" } ] }`);
          });

          if (leaveReason == "allPlayersDead") {
            system.runTimeout(() => {
              let leaveMessage2 =
                "The autopilot will now attempt to fly to the closest safe spaceport. Your items have been lost.";
              worldPlayers.forEach((player) => {
                player.runCommand(`tellraw @s {"rawtext": [ { "text": "dingUI:pilot_____${leaveMessage2}" } ] }`);
              });
            }, 5 * 20);
          }
        }

        if (input2 == 1) {
          const shipVol = updateShipVol();
          saveShipEntities();

          const moonId = world.getDynamicProperty("moon");
          let shipLocation = { x: 0, y: -60, z: 0 };
          for (const key of Object.keys(MAPS)) {
            if (MAPS[key].id === moonId) {
              shipLocation = MAPS[key].shipLocation;
              break;
            }
          }

          for (let player of worldPlayers) {
            player.addTag('cutscene')

            const shipVol = updateShipVol();

            player.spectatorIndex = undefined;
            player.addEffect("invisibility", 99999, { showParticles: false });

            if (shipVol.isInside(player.location) == false && player.state != "dead") {
              player.state = "missing";
              player.runCommand(`clear @s`);
              player.runCommand(`function initializeItems`);
              world.sendMessage(`§9${player.nameTag} was left behind.`)
            }

            if (moonId == 7) {
              player.runCommand(`scriptevent js:fog rend_taking_off`);
            } else if (moonId == 9) {
              player.runCommand(`scriptevent js:fog titan_taking_off`);
            } else {
              player.runCommand(`scriptevent js:fog outside`);
            }
            player.runCommand(`scriptevent js:stop_ambience`);
            player.runCommand(`scriptevent js:ambience`);

            player.teleport(shipLocation);

            player.setProperty('js:flashlight_state', 0)
          }

          system.runTimeout(() => {
            const newLocation = {
              x: shipLocation2.x - 14 + 0.5,
              y: shipLocation2.y + 1,
              z: shipLocation2.z + 12 + 0.5,
            };
            console.warn(`Leaving ${mapName2}`);

            world.setDynamicProperty("inOrbit", true);

            system.run(() => {
              entity.setProperty("js:animation", 3);
              entity.setProperty("js:in_orbit", 1);
              entity.runCommand(`fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ceiling_lamp`);
              entity.runCommand(`fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ding:ship_collision`);
              entity.runCommand(`fill ~-6 ~-2 ~-14 ~6 ~6 ~4 air replace ladder`);
              updateProfitDisplay();

              worldPlayers.forEach((player) => {
                player.runCommand(`gamemode spectator @s`);
                player.runCommand(`inputpermission set @s movement disabled`);
                player.runCommand(`inputpermission set @s camera disabled`);
                player.teleport(orbitLocation2, { rotation: { x: 0, y: 0 } });

                player.runCommand(`scriptevent js:stop_ambience`);

                player.runCommand(`function initializeItems`);

                player.camera.setCamera("minecraft:free", {
                  location: newLocation,
                  rotation: { x: -15, y: -120 },
                });
                system.runTimeout(() => {
                  player.camera.setCamera("minecraft:free", {
                    location: newLocation,
                    rotation: { x: -35, y: -170 },
                    easeOptions: {
                      easeType: "InOutQuad",
                      easeTime: 10,
                    },
                  });
                }, 5);
              });
            });
          }, 3);
        }

        if (input2 == 2) {
          const newLocation2 = {
            x: shipLocation2.x + 2 + 0.5,
            y: shipLocation2.y + 47,
            z: shipLocation2.z - 41.5 + 0.5,
          };

          let alivePlayers = 0;
          deadPlayers = 0
          for (let player of worldPlayers) {
            player.teleport(newLocation2);

            if (player.state != "dead" && player.state != "missing") {
              alivePlayers++;
              player.state = "alive";
            }
            if (player.state == "dead" || player.state == "missing") {
              deadPlayers++
            }
          }
          console.warn(`Alive PLayers ${alivePlayers}`);
          if (alivePlayers == 0) {
            deleteAllScrapItems();
            entity.runCommand(`music play music.stinger.all_players_dead`);
          }

          penaltyPercent = 0
          bodiesNotRecovered = 0
          if (deadPlayers > 0) {
            bodiesNotRecovered = deadPlayers - bodiesRecovered

            for (let i = 0; i < bodiesNotRecovered; i++) {
              penaltyPercent += 20
            }
            for (let i = 0; i < bodiesRecovered; i++) {
              penaltyPercent += 8
            }

            if (penaltyPercent > 100) {
              penaltyPercent = 100
            }

            console.warn(`Final percent: ${penaltyPercent}`)
          }

          if (entity.getProperty("js:door") == 1) {
            entity.runCommand(`execute as @a at @s run playsound door.ship.close @s ~~~ 0.3`);
          }

          worldPlayers.forEach((player) => {
            player.camera.setCamera("minecraft:free", {
              location: newLocation2,
              rotation: { x: 25, y: 24 },
            });
          });

          if (mapName2 == "The Company Building") {
            entity.runCommand(`kill @e[type=js:company]`);
            OVERWORLD.runCommand(`kill @e[type=js:dropship]`);
          } else {

            world.setDynamicProperty('totalRunScrapCollected', world.getDynamicProperty('totalRunScrapCollected') + world.getDynamicProperty('scrapCollected'))

            entity.runCommand(`execute as @a run scriptevent js:ui 1`);
          }

          entity.runCommand(`scriptevent js:clearGenerate`);
        }

        if (input2 == 3) {
          worldPlayers.forEach((player) => {
            player.camera.fade({
              fadeTime: { fadeInTime: 0.25, holdTime: 0.3, fadeOutTime: 0.25 },
            });
          });

          system.runTimeout(() => {
            const newLocation3 = {
              x: shipLocation2.x + 2 + 0.5,
              y: shipLocation2.y + 47,
              z: shipLocation2.z - 41.5 + 0.5,
            };

            worldPlayers.forEach((player) => {
              player.teleport(newLocation3);
              player.camera.clear();
              player.removeTag("inFacility");
              player.removeTag('cutscene')
              player.runCommand(`scriptevent js:fog outside`);
              player.runCommand(`gamemode a @s[tag=!debug]`);
              player.runCommand(`gamemode c @s[tag=debug]`);
              player.runCommand(`inputpermission set @s movement enabled`);
              player.runCommand(`inputpermission set @s camera enabled`);
              player.runCommand(`function initializeItems`);
              player.runCommand(`camera @s set minecraft:first_person`)
            });

            entity.runCommand(
              `execute as @s at @s positioned ~ ~44 ~-40 run structure load mystructure:ship ~-6 ~-2 ~-14`
            );

            system.run(() => {
              entity.runCommand(`fill ~2 ~44 ~-39 ~-2 ~47 ~-39 ding:ship_door_collision`);

              world.setDynamicProperty("time", 0);
              const currentTime = world.getDynamicProperty("time");
              const ticks = convertToTicks(currentTime);
              world.setTimeOfDay(ticks);

              system.run(() => {
                loadShipEntities();
                updateProfitDisplay();

                worldPlayers.forEach((player) => {
                  player.playSound("misc.ship.squeak", SOUND_OPTIONS);
                  player.runCommand(`fog @s pop facility`);
                  player.runCommand(`fog @s pop company`);
                  player.runCommand(`fog @s pop experimentation`);
                  player.runCommand(`fog @s pop experimentation_foggy`);
                });
                updateProfitDisplay();
              });
            });
          }, 0.3 * 20);
        }

        if (input2 == 4) {
          let currentDay = world.getDynamicProperty("day");
          const currentDaysSurvived = world.getDynamicProperty("daysSurvived");

          let delay = 6 * 20;

          if (mapName2 !== "The Company Building") {
            const newDay = currentDay - 1;
            world.setDynamicProperty("day", newDay);
            console.warn(world.getDynamicProperty("day"));

            const newDaysSurvived = parseInt(currentDaysSurvived + 1);
            world.setDynamicProperty("daysSurvived", newDaysSurvived);
            applyDiscount();
            setWeather();
            updateProfitDisplay();
          }
          if (mapName2 == "The Company Building" && currentDay == 1) {
            world.setDynamicProperty("day", 0);
            delay = 2 * 20;
          }
          currentDay = world.getDynamicProperty("day");

          const randomMood = getRandomMood(COMPANY_MOODS);
          world.setDynamicProperty("companyMood", randomMood.name);

          entity.setProperty("js:animation", 4);

          worldPlayers.forEach((player) => {
            player.removeTag("inGame");
            player.addEffect("instant_health", 2, { showParticles: false, amplifier: 255 });
            player.addEffect("weakness", 2000000, { amplifier: 255, showParticles: false });
          });


          if (deadPlayers > 0) {
            delay += 5 * 20
            system.runTimeout(() => {
              const credits = world.scoreboard.getObjective("credits");
              let creditsPenalty = Math.floor(credits.getScore('world') * ((penaltyPercent) / 100))
              credits.setScore("world", credits.getScore('world') - creditsPenalty);

              let penaltyDisplay = convertValueToUi(String(creditsPenalty), 6)
    
              worldPlayers.forEach((player) => {
                player.runCommand(
                  `tellraw @s {"rawtext":[{"text":"dingUI:penalty___${penaltyDisplay}§z${deadPlayers} Casualties: -${penaltyPercent}\n(${bodiesRecovered} Bodies Recovered)"}]}`
                );
              });
            }, 4.1 * 20)
          }

          system.runTimeout(() => {
            if (currentDay > 1) {
              worldPlayers.forEach((player) => {
                player.runCommand(
                  `tellraw @s {"rawtext":[{"text":"dingUI:quota_blue§z${
                    currentDay - 1
                  } Days LeftTO MEET PROFIT QUOTA"}]}`
                );
              });

              if (currentDay == 2) {
                worldPlayers.forEach((player) => {
                  player.runCommand(`playsound game.profit.final_day @s`);
                });
              } else {
                worldPlayers.forEach((player) => {
                  player.runCommand(`playsound game.profit.days_left @s`);
                });
              }
            }
            if (currentDay == 1) {
              worldPlayers.forEach((player) => {
                player.runCommand(
                  `tellraw @s {"rawtext":[{"text":"dingUI:quota__red§z${
                    currentDay - 1
                  } Days LeftTO MEET PROFIT QUOTA"}]}`
                );
                player.runCommand(`playsound game.profit.zero_days_left @s`);
              });
            }

            system.run(() => {
              if (currentDay == 0) {
                const scrapSold = world.getDynamicProperty("scrapSold");
                const currentQuota = world.getDynamicProperty("quota");
                if (scrapSold >= currentQuota) {
                  worldPlayers.forEach((player) => {
                    player.runCommand(`tellraw @s {"rawtext":[{"text":"dingUI:quotareach§zQUOTA REACHED!"}]}`);
                    player.runCommand(`playsound game.profit.reached @s`);
                  });

                  let overtimeBonus = 0;
                  overtimeBonus = calculateOvertimeBonus();

                  world.sendMessage(`§a>> Overtime Bonus: ${overtimeBonus}`);
                  const credits = world.scoreboard.getObjective("credits");
                  credits.setScore("world", credits.getScore("world") + overtimeBonus);

                  const quotasFulfilled = world.getDynamicProperty("quotasFulfilled");
                  world.setDynamicProperty("quotasFulfilled", quotasFulfilled + 1);
                  system.runTimeout(() => {
                    const newQuota = calculateNewQuota();
                    world.setDynamicProperty("quota", newQuota);

                    const paddedNewQuota = newQuota.toString().padStart(6, "p");

                    shipEntity.runCommand(`tellraw @a {"rawtext":[{"text":"dingUI:new_quota_${paddedNewQuota}"}]}`);

                    world.setDynamicProperty("day", 4);

                    world.setDynamicProperty("scrapSold", 0);

                    applyDiscount();
                    setWeather();
                    updateProfitDisplay();

                    system.runTimeout(() => {
                      worldPlayers.forEach((player) => {
                        player.runCommand(`playsound game.profit.new_quota @s`);
                      });
                    }, 4.4 * 20);
                  }, 6 * 20);
                } else {
                  entity.runCommand(`scriptevent js:fired`);
                }
              }
            });
          }, delay);
        }
        break;
      default:
        break;
    }
  }
});

function getRandomMood(moods) {
  const keys = Object.keys(moods);
  const randomIndex = Math.floor(Math.random() * keys.length);
  const randomKey = keys[randomIndex];
  return {
    name: randomKey,
    properties: moods[randomKey],
  };
}
