import { ModalFormData, ActionFormData, uiManager } from "@minecraft/server-ui";
import { world, system, Player, Entity, MolangVariableMap, BlockPermutation, BlockVolume } from "@minecraft/server";

import { ITEM_LIST, MAPS } from "./data";

import { OVERWORLD, SOUND_OPTIONS, worldPlayers, creditsScoreboard, shipEntity, startWeather } from "./main";
import { saveShipEntities, loadShipEntities } from "./shipSystems";

//white percent 
//green percent 
//red percent 
//credits 

/**
 * @param {Player} player
 */
export function credits2(player) {
  const credits2Form = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  credits2Form.title(`Terminal ${credits}`);

  let display = { translate: 'form.credits', "with": ["\n"] }
  let submitButton = { translate: 'form.credits.submit_button'}

  credits2Form.textField(display, submitButton);

  credits2Form.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      return;
    }
    const input = confirmResponse.formValues?.[0];
    if (input) {
      exitTerminal(player);
    } else {
      exitTerminal(player);
    }
  });
}

/**
 * @param {Player} player
 */
export function credits1(player) {
  let tutorial1Form = new ActionFormData();
  tutorial1Form.title("credits");
  tutorial1Form.body("");

  tutorial1Form.button(``);
  tutorial1Form
    .show(player)
    .then((r) => {
      if (r.canceled) {
        credits2(player);
        return;
      }

      let response = r.selection;
      if (response == 0) {
        credits2(player);
      }
    })
    .catch((e) => {
      console.error(e, e.stack);
    });
}

/**
 * @param {Player} player
 */
//Text credits
export function tutorial3(player) {
  const credits2Form = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  credits2Form.title(`Terminal ${credits}`);

  let display = { translate: 'form.credits', "with": ["\n"] }
  let submitButton = { translate: 'form.credits.submit_button'}

  credits2Form.textField(display, submitButton);

  credits2Form.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      player.inputPermissions.movementEnabled = true
      player.inputPermissions.cameraEnabled = true
      player.runCommand(`function hudOverlays/systemsOnline`);

      system.runTimeout(() => {
        player.playSound('game.profit.intro')
      }, 3 * 20);
      return;
    }
    const input = confirmResponse.formValues[0];

    if (input) {
      exitTerminal(player);
      player.inputPermissions.movementEnabled = true
      player.inputPermissions.cameraEnabled = true
      player.runCommand(`function hudOverlays/systemsOnline`);

      system.runTimeout(() => {
        player.playSound('game.profit.intro')
      }, 3 * 20);
    } else {
      exitTerminal(player);
      player.inputPermissions.movementEnabled = true
      player.inputPermissions.cameraEnabled = true
      player.runCommand(`function hudOverlays/systemsOnline`);

      system.runTimeout(() => {
        player.playSound('game.profit.intro')
      }, 3 * 20);
    }
  });
}


export function tutorialMobile1(player) {
  let tutorial1Form = new ActionFormData();
  tutorial1Form.title("tutorial2");
  tutorial1Form.body("");

  tutorial1Form.button(``);
  tutorial1Form
    .show(player)
    .then((r) => {
      if (r.canceled) {
        tutorialMobile2(player);
        return;
      }

      let response = r.selection;
      if (response == 0) {
        tutorialMobile2(player);
      }
    })
    .catch((e) => {
      console.error(e, e.stack);
    });
}

export function tutorialMobile2(player) {
  let tutorial1Form = new ActionFormData();
  tutorial1Form.title("tutorial3");
  tutorial1Form.body("");

  tutorial1Form.button(``);
  tutorial1Form
    .show(player)
    .then((r) => {
      if (r.canceled) {
        tutorial2(player);
        return;
      }

      let response = r.selection;
      if (response == 0) {
        tutorial2(player);
      }
    })
    .catch((e) => {
      console.error(e, e.stack);
    });
}


/**
 * @param {Player} player
 */
//Credits
export function tutorial2(player) {
  let tutorial1Form = new ActionFormData();
  tutorial1Form.title("credits");
  tutorial1Form.body("");

  tutorial1Form.button(``);
  tutorial1Form
    .show(player)
    .then((r) => {
      if (r.canceled) {
        tutorial3(player);
        return;
      }

      let response = r.selection;
      if (response == 0) {
        tutorial3(player);
      }
    })
    .catch((e) => {
      console.error(e, e.stack);
    });
}

/**
 * @param {Player} player
 */
//Recommended settings
export function tutorial1(player, skipMobile = false) {
  let tutorial1Form = new ActionFormData();
  tutorial1Form.title("tutorial");
  tutorial1Form.body("");

  tutorial1Form.button(``);
  tutorial1Form
    .show(player)
    .then((r) => {
      if (r.canceled) {
        if (skipMobile == false) {
          tutorialMobile1(player);
        } else {
          tutorial2(player)
        }
        return;
      }

      let response = r.selection;
      if (response == 0) {
        if (skipMobile == false) {
          tutorialMobile1(player);
        } else {
          tutorial2(player)
        }
      }
    })
    .catch((e) => {
      console.error(e, e.stack);
    });
}

let isFirstDisplay = true;

/**
 * @param {Player} player 
 */
export function performanceReport(player) {
  system.runTimeout(() => {
    uiManager.closeAllForms(player);
  }, 9 * 20);

  let reportForm = new ActionFormData();
  // reportForm.title("perf report");
  reportForm.title("performance report");
  reportForm.body("");
  let alivePlayers = 0;
  for (let run = 0; run < 4; run++) {
    try {
      reportForm.button(`${worldPlayers[run].nameTag}`);
    } catch (error) {
      reportForm.button(``);
    }
  }
  for (let run_two = 0; run_two < 4; run_two++) {
    let status = "c";
    try {
      if (worldPlayers[run_two].state == "missing") {
        status = "x";
      } else if (worldPlayers[run_two].state == "dead") {
        status = "x";
      } else if (worldPlayers[run_two].state != "dead" && worldPlayers[run_two].state != "missing") {
        status = "c";
        alivePlayers++;
      }
      reportForm.button(`${status}`);
    } catch (error) {
      reportForm.button(``);
    }
  }
  //notes
  let addedNotesCount = 0;

  // Initialize an object to keep track of the highest stat holders
  let mostStats = {
    injuries: { player: null, value: 0 },
    laziness: { player: null, value: 99999 },
    paranoia: { player: null, value: 0 },
    profitability: { player: null, value: 0 },
  };

  console.warn(
    `before ${mostStats.injuries?.nameTag} ${mostStats.laziness?.nameTag} ${mostStats.paranoia?.nameTag} ${mostStats.profitability?.nameTag}`
  );

  // Step 1: Identify the "Most" Stat Holders
  worldPlayers.forEach((player) => {
    const injuries = player.injuries ?? 0;
    const laziness = player.laziness ?? 0;
    const paranoia = player.paranoia ?? 0;
    const profitability = player.profitability ?? 0;

    if (injuries > mostStats.injuries.value) {
      mostStats.injuries = { player: player, value: injuries };
    }
    if (laziness < mostStats.laziness.value) {
      mostStats.laziness = { player: player, value: laziness };
    }
    if (paranoia > mostStats.paranoia.value) {
      mostStats.paranoia = { player: player, value: paranoia };
    }
    if (profitability > mostStats.profitability.value) {
      mostStats.profitability = { player: player, value: profitability };
    }
  });
  /*
    for (let player of worldPlayers) {
        console.warn(`${player.nameTag}`)
        console.warn(`I ${player.injuries}`)
        console.warn(`L ${player.laziness}`)
        console.warn(`P ${player.paranoia}`)
        console.warn(`Pr ${player.profitability}`)
    }

  */ // Step 2: Generate the Report for Each Player
  worldPlayers.forEach((player) => {
    let notes = "";

    if (mostStats.injuries.player === player) {
      notes += "- Sustained the most injuries\n";
    }
    if (mostStats.laziness.player === player) {
      notes += "- The laziest employee\n";
    }
    if (mostStats.paranoia.player === player) {
      notes += "- The most paranoid employee\n";
    }
    if (mostStats.profitability.player === player) {
      notes += "- Most profitable\n";
    }

    // Remove the last newline character
    notes = notes.trim();

    // If no notes, add a default message
    if (!notes) {
      reportForm.button(``);
    } else {
      reportForm.button(notes);
    }
    addedNotesCount++;
  });

  while (addedNotesCount < 4) {
    reportForm.button(``);
    addedNotesCount++;
  }

  if (alivePlayers == 0) {
    //scrap collected
    reportForm.button(`ALL SCRAP LOST`);

    //rank
    reportForm.button(`f`);

    //true for survivors
    reportForm.button(`f`);
  } else {
    const scrapCollected = world.getDynamicProperty("scrapCollected");
    const totalScrapPossible = world.getDynamicProperty("totalScrapPossible");
    const tier = calculateTier(scrapCollected, totalScrapPossible, alivePlayers);

   
    //scrap collected
    reportForm.button(`${scrapCollected}\n${totalScrapPossible}`);

    //rank
    reportForm.button(`${tier}`);

    //survivors
    reportForm.button(`t`);
  }

  reportForm
    .show(player)
    .then((r) => {
      if (r.canceled) return;

      let response = r.selection;
      if (response) {
        world.sendMessage(``);
      }
    })
    .catch((e) => {
      console.error(e, e.stack);
    });
}

function calculateTier(scrapCollected, totalScrapPossible, alivePlayers) {
  let ratio = scrapCollected / totalScrapPossible;

  if (alivePlayers == 0) {
    ratio = ratio - 0.2;
  } else if (alivePlayers == 1) {
    ratio = ratio + 0;
  } else if (alivePlayers == 2) {
    ratio = ratio + 0.1;
  } else if (alivePlayers == 3) {
    ratio = ratio + 0.15;
  } else if (alivePlayers >= 4) {
    ratio = ratio + 0.2;
  }

  if (ratio >= 0.9) {
    return "s";
  } else if (ratio >= 0.8) {
    return "a";
  } else if (ratio >= 0.7) {
    return "b";
  } else if (ratio >= 0.5) {
    return "c";
  } else if (ratio >= 0.3) {
    return "d";
  } else {
    return "f";
  }
}

/**
 * @param {Player} player 
 */
function displayMoons(player, confirmText = "") {
  const moonsForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  moonsForm.title(`Terminal ${credits}`);

  let companyBuyingPercentage = 30;
  const day = world.getDynamicProperty("day");
  switch (day) {
    case 4:
      companyBuyingPercentage = 30;
      break;
    case 3:
      companyBuyingPercentage = 53;
      break;
    case 2:
      companyBuyingPercentage = 77;
      break;
    case 1:
      companyBuyingPercentage = 100;
      break;
    default:
      companyBuyingPercentage = 100;
      break;
  }
  let display;
  if (confirmText === "") {
    display = `§aWelcome to the exomoons catalogue.\nTo route the autopilot to a moon, type the moon name.\nTo learn about a moon, use the word INFO.\n___________________________\n\n* The Company Building     // Buying at ${companyBuyingPercentage}\n\n`;

    for (const moon in weather) {
      let moonName = moon.charAt(0).toUpperCase() + moon.slice(1);
      let weatherDisplay = "";
      if (moon == "vow" || moon == "offense" || moon == "adamance" || moon == "dine") {
        continue;
      }
      // if (moonName !== "Experimentation" && moonName !== "March" && moonName !== "Titan" && moonName !== "Rend" && moonName !== "Company") {
      //   moonName += " (Unavailable)";
      // }
      switch (weather[moon]) {
        case "clear":
          weatherDisplay = "";
          break;
        case "foggy":
          weatherDisplay = "(Foggy)";
          break;
        case "rainy":
          weatherDisplay = "(Rainy)";
          break;
        case "stormy":
          weatherDisplay = "(Stormy)";
          break;
        case "flooded":
          weatherDisplay = "(Flooded)";
          break;
        case "eclipsed":
          weatherDisplay = "(Eclipsed)";
          break;
        default:
          weatherDisplay = "";
          break;
      }
      // if (moon === "vow" || moon === "adamance") {
      if (moon === "assurance" || moon === "march" || moon === "titan") {
        display += `* ${moonName} ${weatherDisplay}\n\n`;
      } else {
        display += `* ${moonName} ${weatherDisplay}\n`;
      }
    }
  } else {
    display = confirmText;
  }

  moonsForm.textField(display, "Enter Command");

  moonsForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }
    const input = response.formValues[0];
    const inputLowerCase = guessCommand(input);

    switch (inputLowerCase) {
      case "company":
      case "experimentation":
      case "assurance":
      // case "vow":
      // case "offense":
      case "march":
      // case "adamance":
      case "rend":
      // case "dine":
      case "titan":
      case "embrion":
      case "artifice":
        console.warn(`${inputLowerCase}`);
        moonConfirmationForm(player, inputLowerCase);
        break;
      default:
        terminalErrorForm(player);
    }
  });
}

/**
 * @param {Player} player 
 * @param {string} command 
 */
function switchForm(player, command) {
  const switchForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  switchForm.title(`Terminal ${credits}`);

  const name = command.split(" ")[1];
  console.warn(name);

  let switchedPlayer;
  if (name !== undefined) {
    switchedPlayer = switchToPlayer(name);
  } else {
    switchedPlayer = switchToPlayer();
  }

  console.warn(`Switched to ${switchedPlayer.nameTag}`);

  let display = `§aSwitched monitor to ${switchedPlayer.nameTag}`;
  switchForm.textField(display, "Enter Command");

  switchForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }

    const userInput = response.formValues[0];
    const inputLowerCase = guessCommand(userInput);

    inputs(player, inputLowerCase, display);
  });
}

/**
 * @param {Player} player 
 */
function resetConfirmationForm(player) {
  const resetConfirmationForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  resetConfirmationForm.title(`Terminal ${credits}`);

  let display = `§aAre you sure you want to reset the map? This will wipe all data, replay the intro and set the ship's location back to 41-Experimentation.\n\nPlease CONFIRM or DENY.`;

  resetConfirmationForm.textField(display, "Enter Command");

  resetConfirmationForm.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      return;
    }
    const input = confirmResponse.formValues[0];

    const inputLowerCase = guessCommand(input);

    if (inputLowerCase == "confirm") {
      player.runCommand(`function resetFull`);
      exitTerminal(player);
    }
    if (inputLowerCase == "deny") {
      display += `\n\nYou have cancelled the order.`;

      const nextForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      nextForm.title(`Terminal ${credits}`);
      nextForm.textField(display, "Enter Command");

      nextForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }
        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });
    }
    if (inputLowerCase !== "confirm" && inputLowerCase !== "deny") {
      terminalErrorForm(player);
    }
  });
}


function arachnophobiaConfirmationForm(player) {
  const arachnophobiaConfirmationForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  arachnophobiaConfirmationForm.title(`Terminal ${credits}`);

  let arachnophobiaMode = world.getDynamicProperty('arachnophobiaMode') ?? false
  let display = `§aToggle Arachnophobia Mode? Currently set to: ${arachnophobiaMode}\n\nPlease CONFIRM or DENY.`;

  arachnophobiaConfirmationForm.textField(display, "Enter Command");

  arachnophobiaConfirmationForm.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      return;
    }
    const input = confirmResponse.formValues[0];

    const inputLowerCase = guessCommand(input);

    if (inputLowerCase == "confirm") {

      if (arachnophobiaMode == true) {
        world.setDynamicProperty('arachnophobiaMode', false)
      } else {
        world.setDynamicProperty('arachnophobiaMode', true)
      }

      player.runCommand(`execute as @e[type=js:bunker_spider] run scriptevent js:bunkerSpiderModel`)
      player.runCommand(`execute as @e[type=js:bunker_spider_dead] run scriptevent js:bunkerSpiderModel`)
      arachnophobiaMode = world.getDynamicProperty('arachnophobiaMode') 
      
      display += `\n\nSet Arachnophobia Mode to: ${arachnophobiaMode}`;

      const nextForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      nextForm.title(`Terminal ${credits}`);
      nextForm.textField(display, "Enter Command");

      nextForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }
        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });
    }
    if (inputLowerCase == "deny") {
      display += `\n\nYou have cancelled the order.`;

      const nextForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      nextForm.title(`Terminal ${credits}`);
      nextForm.textField(display, "Enter Command");

      nextForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }
        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });
    }
    if (inputLowerCase !== "confirm" && inputLowerCase !== "deny") {
      terminalErrorForm(player);
    }
  });
}

/**
 * @param {Player} player 
 */
function ejectForm(player) {
  const ejectForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  ejectForm.title(`Terminal ${credits}`);

  let display = `§aDo you want to eject all crew members off the ship including yourself? You must be in Orbit.\n\nPlease CONFIRM or DENY.`;

  ejectForm.textField(display, "Enter Command");

  ejectForm.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      return;
    }
    const input = confirmResponse.formValues[0];

    const inputLowerCase = guessCommand(input);

    if (inputLowerCase == "confirm") {
      if (world.getDynamicProperty("inOrbit") == false) {
        const nextForm = new ModalFormData();
        const credits = creditsScoreboard.getScore("world");
        nextForm.title(`Terminal ${credits}`);

        display = `§aShip is not in orbit!`;
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      } else {
        player.runCommand(`scriptevent js:fired`);
        exitTerminal(player);
      }
    }
    if (inputLowerCase == "deny") {
      display += `\n\nYou have cancelled the order.`;

      const nextForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      nextForm.title(`Terminal ${credits}`);
      nextForm.textField(display, "Enter Command");

      nextForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }
        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });
    }
    if (inputLowerCase !== "confirm" && inputLowerCase !== "deny") {
      terminalErrorForm(player);
    }
  });
}

/**
 * @param {Player} player 
 * @param {string} selectedMoon 
 */
function moonConfirmationForm(player, selectedMoon) {
  const costConfirmationForm = new ModalFormData();

  const credits = creditsScoreboard.getScore("world");

  costConfirmationForm.title(`Terminal ${credits}`);

  let display;
  let weatherCondition;
  switch (weather[selectedMoon]) {
    case "clear":
      weatherCondition = "mild weather";
      break;
    case "foggy":
      weatherCondition = "foggy";
      break;
    case "rainy":
      weatherCondition = "rainy";
      break;
    case "stormy":
      weatherCondition = "stormy";
      break;
    case "flooded":
      weatherCondition = "flooded";
      break;
    case "eclipsed":
      weatherCondition = "eclipsed";
      break;
    default:
      weatherCondition = "mild weather";
      break;
  }

  display = `§aThe cost to route to ${MAPS[selectedMoon].name} is  ${MAPS[selectedMoon].cost}. It is currently ${weatherCondition} on this moon.\n\nPlease CONFIRM or DENY.`;

  costConfirmationForm.textField(display, "Enter Command");

  costConfirmationForm.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      return;
    }
    const input = confirmResponse.formValues[0];

    const inputLowerCase = guessCommand(input);

    if (inputLowerCase == "confirm") {
      const costConfirmedForm = new ModalFormData();
      let credits = creditsScoreboard.getScore("world");
      costConfirmedForm.title(`Terminal ${credits}`);

      //0 = false, 1 = true, 2 = landed
      let success = 0;

      const orbitStatus = world.getDynamicProperty("inOrbit");
      const currentMoon = world.getDynamicProperty("moon");

      if (credits >= MAPS[selectedMoon].cost && orbitStatus == true && currentMoon !== MAPS[selectedMoon].id) {
        success = 1;
      }
      if (orbitStatus == false) {
        success = 2;
      }
      if (orbitStatus == true && currentMoon == MAPS[selectedMoon].id) {
        success = 3;
      }

      if (success == 0) {
        display += `\n\nYou could not afford these items!\nYour balance is  ${credits}. Total cost of these items is  ${MAPS[selectedMoon].cost}`;
        console.warn(`failed travel to ${MAPS[selectedMoon].name}`);
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        const nextForm = new ModalFormData();
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
      if (success == 1) {
        creditsScoreboard.addScore("world", -MAPS[selectedMoon].cost)
        credits = creditsScoreboard.getScore("world");

        display += `\n\nRouting Autopilot to ${MAPS[selectedMoon].name}.\nYour new balance is  ${credits}.\n\nPlease enjoy your flight.`;
        console.warn(`travelling to ${MAPS[selectedMoon].name}`);
        world.setDynamicProperty("moon", MAPS[selectedMoon].id);
        OVERWORLD.playSound("misc.ship.routing", player.location, SOUND_OPTIONS);

        player.runCommand(`camerashake add @a 0.5 1 rotational`);
        player.runCommand(`fill ~-12 ~-12 ~-12 ~12 ~12 ~12 air replace ding:terminal_block`);
        player.runCommand(`fill ~-12 ~-12 ~-12 ~12 ~12 ~12 air replace ding:ship_lever`);

        system.runTimeout(() => {
          let shipLocation = MAPS[selectedMoon].shipLocation;
          player.runCommand(
            `tickingarea add circle ${shipLocation.x} ${shipLocation.y + 45} ${shipLocation.z - 40} 1 Temp true`
          );

          saveShipEntities();

          system.runTimeout(() => {
            system.run(() => {
              const teleportShipLocation = {
                x: shipLocation.x + 0.5,
                y: shipLocation.y,
                z: shipLocation.z + 0.5,
              };
              shipEntity.teleport(teleportShipLocation);

              shipEntity.runCommand(`structure load mystructure:ship ~-6 ~42 ~-54`);

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

                system.run(() => {
                  shipEntity.runCommand(`fill ~2 ~44 ~-39 ~-2 ~47 ~-39 ding:ship_door_collision`);
                  player.runCommand(`tickingarea remove Temp`);
                  system.run(() => {
                    shipEntity.runCommand(`scriptevent js:stopsound_ship_ambience`);
                    shipEntity.runCommand(`scriptevent js:playsound_ship_ambience`);

                    OVERWORLD.playSound("misc.ship.arrive", player.location, SOUND_OPTIONS);
                  });
                });
              })
            });
          }, 2.3 * 20);
        }, 20);

        const nextForm = new ModalFormData();
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
      if (success == 2) {
        display += `\n\nUnable to route the ship currently. It must be in orbit around a moon to route the autopilot.\nUse the main lever at the front desk to enter orbit.`;
        console.warn(`failed travel to ${MAPS[selectedMoon].name} due to not in orbit`);
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        const nextForm = new ModalFormData();
        const credits = creditsScoreboard.getScore("world");
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
      if (success == 3) {
        display += `\n\nUnable to route the ship. You are already on ${MAPS[selectedMoon].name}.`;
        console.warn(`failed travel to ${MAPS[selectedMoon].name} due to already being there`);
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        const nextForm = new ModalFormData();
        const credits = creditsScoreboard.getScore("world");
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
    }
    if (inputLowerCase == "deny") {
      display += `\n\nYou have cancelled the order.`;

      const nextForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      nextForm.title(`Terminal ${credits}`);
      nextForm.textField(display, "Enter Command");

      nextForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }
        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });
    }
    if (inputLowerCase !== "confirm" && inputLowerCase !== "deny") {
      terminalErrorForm(player);
    }
  });
}

const STORE_ITEMS_INFO = {
  walkie: {
    display: "Walkie-talkie",
    info: "Useful for keeping in touch! Hear other players when the walkie-talkie is in your inventory. Must be in your hand and pressed down to transmit voice.",
  },
  flashlight: {
    display: "Flashlight",
    info: "The most affordable light source. It's even waterproof!",
  },
  shovel: {
    display: "Shovel",
    info: "For self-defense!",
  },
  lockpicker: {
    display: "Lockpicker",
    info: "Lock-pickers will unlock your limitless potential for efficiency on the job. Powered by proprietary AI software, they will get you access through any locked door.",
  },
  pro_flashlight: {
    display: "Pro-flashlight",
    info: "With an extra battery life and even brighter bulb, your colleagues can never leave you in the dark again!",
  },
  stun_grenade: {
    display: "Stun grenade",
    info: "Perfect for if anything gets too close for comfort.",
  },
  boombox: {
    display: "Boombox",
    info: "These jamming tunes are great for a morale boost on your crew!",
  },
  tzp_inhalant: {
    display: "TZP-Inhalant",
    info: "This safe and legal medicine can be administered to see great benefits to your performance on the job! Your ability to move LONG distances while carrying HEFTY objects will be second to none! Warning: TZP gas may impact the brain with extended exposure. Follow instructions manual provided with the canister. Don't forget to share!",
  },
  zap_gun: {
    display: "Zap gun",
    info: "The most specialized self-protective equipment, capable of sending upwards of 80,000 volts!\n\nTo keep it targeted as long as possible, pull the gun side-to-side to counter the bend and fight against the pull of the electric beam. It can only stun for as long as you keep the current flowing.",
  },
  jetpack: {
    display: "Jetpack",
    info: "This device will get you around anywhere! Just use it responsibly!",
  },
  extension_ladder: {
    display: "Extension ladder",
    info: "The extension ladder can reach as high as nine meters! Use it to scale any cliff and reach for the stars! To save batteries the extension ladder automatically stores itself after 18 seconds.",
  },
  radar_booster: {
    display: "Radar-booster",
    info: `Radar boosters come with many uses!\n\nUse the "SWITCH" command before the radar booster's name to view it on the main monitor. It must be activated.\n\nUse the "PING" command before the radar booster's name to play a special sound from the device.`,
  },
  spray_paint: {
    display: "Spray Paint",
    info: "Easily get lost? Mark your paths with Spray Paint! DISCLAIMER: The Company is not responsible for any sensitive images or text made using our Spray Paint",
  },
  loud_horn: {
    display: "Loud horn",
    info: "Used to communicate with any crew member from any distance, no walkie talkie required! The horn can be heard from anywhere. But what does it mean? That's up to you!",
  },
  signal_translator: {
    display: "Signal Translator",
    info: `Use the "transmit" command to broadcast a text message to all crewmates. The message must be under 10 letters.`,
  },
  teleporter: {
    display: "Teleporter",
    info: "Press the button to activate the teleporter. It will teleport whoever is currently being monitored on the ship's radar. They will not be able to keep any of their held items through the teleport. It takes about ten seconds to recharge.",
  },
  inverse_teleporter: {
    display: "Inverse Teleporter",
    info: `The inverse teleporter is a modified teleporter which will teleport you to a random position outside the ship. All your items will be dropped at the teleporter before transport. The inverse teleporter can be used by everyone at once and has a 3.5 minute cooldown.\n\nDISCLAIMER: The inverse teleporter can only transport you out, not in, and you may become trapped. The Company is not responsible for injury or replacement of heads and limbs induced by quantum entanglement and bad luck.`,
  },
};



let storeItems = {
  walkie: {
    original_price: 12,
    price: 12,
    discount_percent: 0,
  },
  flashlight: {
    original_price: 15,
    price: 15,
    discount_percent: 0,
  },
  shovel: {
    original_price: 30,
    price: 30,
    discount_percent: 0,
  },
  // lockpicker: {
  //   original_price: 20,
  //   price: 20,
  //   discount_percent: 0,
  // },
  pro_flashlight: {
    original_price: 25,
    price: 25,
    discount_percent: 0,
  },
  // stun_grenade: {
  //   original_price: 30,
  //   price: 30,
  //   discount_percent: 0,
  // },
  boombox: {
    original_price: 60,
    price: 60,
    discount_percent: 0,
  },
  // tzp_inhalant: {
  //   original_price: 120,
  //   price: 120,
  //   discount_percent: 0,
  // },
  // zap_gun: {
  //   original_price: 400,
  //   price: 400,
  //   discount_percent: 0,
  // },
  jetpack: {
    original_price: 900,
    price: 900,
    discount_percent: 0,
  },
  // extension_ladder: {
  //   original_price: 60,
  //   price: 60,
  //   discount_percent: 0,
  // },
  // radar_booster: {
  //   original_price: 60,
  //   price: 60,
  //   discount_percent: 0,
  // },
  // spray_paint: {
  //   original_price: 60,
  //   price: 60,
  //   discount_percent: 0,
  // },
  loud_horn: {
    price: 100,
  },
  signal_translator: {
    price: 255,
  },
  teleporter: {
    price: 375,
  },
  inverse_teleporter: {
    price: 425,
  },
};


// const storeItemsString = JSON.stringify(storeItems);
// world.setDynamicProperty("storeItems", storeItemsString);

export function applyDiscount() {
  const storedStoreItemsString = world.getDynamicProperty("storeItems");

  storeItems = JSON.parse(storedStoreItemsString);

  console.warn(JSON.stringify(storeItems));

  for (const itemName in storeItems) {
    const item = storeItems[itemName]

    const chance = Math.random();

    const originalPrice = item.original_price;

    if (
      itemName !== "loud_horn" &&
      itemName !== "signal_translator" &&
      itemName !== "teleporter" &&
      itemName !== "inverse_teleporter"
    ) {
      if (chance <= 0.1) {
        const discountPercentage = Math.floor(Math.random() * 8 + 1) * 10;
        const discountedPrice = Math.round(originalPrice * (1 - discountPercentage / 100));
        item.price = discountedPrice;
        item.discount_percent = discountPercentage;
        console.warn(`${discountPercentage} ${discountedPrice} item price ${item.price}`);
      } else {
        item.price = item.original_price;
        item.discount_percent = 0;
      }
    } else {
      item.price = item.price;
    }
  }
  const storeItemsString = JSON.stringify(storeItems);
  world.setDynamicProperty("storeItems", storeItemsString);
  console.warn(storeItemsString);
}

const MOON_WEATHER = {
  experimentation: ["rainy", "stormy", "foggy", "flooded", "eclipsed"],
  assurance: ["rainy", "stormy", "flooded", "eclipsed"],
  vow: ["foggy", "stormy", "flooded", "eclipsed"],
  offense: ["rainy", "stormy", "flooded", "eclipsed"],
  march: ["flooded", "stormy", "foggy", "eclipsed"],
  adamance: ["rainy", "stormy", "flooded", "eclipsed"],
  rend: ["stormy", "eclipsed"],
  dine: ["flooded", "eclipsed"],
  titan: ["stormy", "foggy", "eclipsed"],
  artifice: ["rainy", "stormy", "flooded", "eclipsed"],
  embrion: ["foggy", "eclipsed"],
};

export let weather = {
  experimentation: "clear",
  assurance: "clear",
  vow: "clear",
  offense: "clear",
  march: "clear",
  adamance: "clear",
  rend: "clear",
  dine: "clear",
  titan: "clear",
  artifice: "clear",
  embrion: "clear",
};

world.afterEvents.worldLoad.subscribe((ev) => {
  const storedWeatherString = world.getDynamicProperty("weather");
  weather = JSON.parse(storedWeatherString);
})

function calculateMoonsAffected(numMoons, numEmployees, daysSurvived) {
  let randomInput = Math.random();

  if (numEmployees >= 2 && daysSurvived % 3 === 0) {
    randomInput *= Math.random() * (2.5 - 1.5) + 1.5;
  }

  return Math.min(Math.max(Math.floor(randomInput * numMoons), 0), numMoons); // Allows 0
}

export function setWeather() {
  const storedWeatherString = world.getDynamicProperty("weather");
  weather = storedWeatherString ? JSON.parse(storedWeatherString) : { ...weather }; // Ensure valid JSON

  console.warn("Previous Weather:", JSON.stringify(weather));

  const numEmployees = worldPlayers.length;
  const daysSurvived = world.getDynamicProperty("daysSurvived");

  const moonsAffected = calculateMoonsAffected(7, numEmployees, daysSurvived);
  const allMoons = [...Object.keys(weather)];

  // **Fisher-Yates Shuffle**
  for (let i = allMoons.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [allMoons[i], allMoons[j]] = [allMoons[j], allMoons[i]];
  }

  const affectedMoons = allMoons.slice(0, moonsAffected); // Select affected moons

  for (const moon of allMoons) {
    if (affectedMoons.includes(moon) && MOON_WEATHER[moon].length > 0) {
      const randomIndex = Math.floor(Math.random() * MOON_WEATHER[moon].length);
      weather[moon] = MOON_WEATHER[moon][randomIndex];
    } else {
      weather[moon] = "clear"; // Default to clear
    }
  }

  const weatherString = JSON.stringify(weather);
  world.setDynamicProperty("weather", weatherString);
  console.warn("New Weather:", weatherString);
}



function displayStore(player) {
  const storeForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  storeForm.title(`Terminal ${credits}`);

  const storedStoreItemsString = world.getDynamicProperty("storeItems");

  storeItems = JSON.parse(storedStoreItemsString);

  let display = `§aWelcome to the Company store.\nUse words BUY and INFO on any item.\nOrder tools in bulk by typing a number.\n___________________________\n\n`;
  for (const itemName in storeItems) {
    const item = storeItems[itemName];

    if (
      itemName == "loud_horn" ||
      itemName == "signal_translator" ||
      itemName == "teleporter" ||
      itemName == "inverse_teleporter"
    )
      continue;

    if (
      itemName !== "shovel" &&
      itemName !== "pro_flashlight" &&
      itemName !== "flashlight" &&
      itemName !== "walkie" &&
      itemName !== "boombox" &&
      itemName !== "jetpack"
    ) {
      display += `\n* ${STORE_ITEMS_INFO[itemName].display} (Unavailable)`;
    } else {
      if (item.price !== item.original_price) {
        display += `\n* ${STORE_ITEMS_INFO[itemName].display}  //  Price:  ${item.price} (${item.discount_percent} OFF!)`;
      } else {
        display += `\n* ${STORE_ITEMS_INFO[itemName].display}  //  Price:  ${item.price}`;
      }
    }
  }

  display += `\n\nSHIP UPGRADES:\n`;

  for (const itemName in storeItems) {
    const item = storeItems[itemName];

    if (
      itemName !== "loud_horn" &&
      itemName !== "signal_translator" &&
      itemName !== "teleporter" &&
      itemName !== "inverse_teleporter"
    )
      continue;

    if (itemName == "teleporter" || itemName == "inverse_teleporter") {
        display += `\n* ${STORE_ITEMS_INFO[itemName].display}  //  Price:  ${item.price}`;
    } else {
      display += `\n* ${STORE_ITEMS_INFO[itemName].display} (Unavailable)`;
    }
    // //  Price:  ${item.price}
  }

  storeForm.textField(display, "Enter Command");

  storeForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }
    const input = response.formValues[0];
    const inputLowerCase = guessCommand(input);

    inputs(player, inputLowerCase, display);
  });
}

let deliveryShipContents = [];

function buyConfirmationForm(player, itemName, itemAmount) {
  const buyConfirmationForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  buyConfirmationForm.title(`Terminal ${credits}`);

  const item = storeItems[itemName];
  //  console.warn(itemName)
  // console.warn(JSON.stringify(item))

  const totalPrice = item.price * itemAmount;

  let display = `§aYou have requested to order ${STORE_ITEMS_INFO[itemName].display}s. Amount: ${itemAmount}.\nTotal cost of items is  ${totalPrice}.\n\nPlease CONFIRM or DENY.`;

  buyConfirmationForm.textField(display, "Enter Command");

  buyConfirmationForm.show(player).then((confirmResponse) => {
    if (confirmResponse.canceled) {
      exitTerminal(player);
      return;
    }
    const input = confirmResponse.formValues[0];

    const inputLowerCase = guessCommand(input);

    if (inputLowerCase == "confirm") {
      const buyConfirmedForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      buyConfirmedForm.title(`Terminal ${credits}`);
      let success = 0;

      let deliveryShipContents = [];
      let deliveryShipContentsString = world.getDynamicProperty("deliveryShip");
      deliveryShipContents = JSON.parse(deliveryShipContentsString);

      let totalPurchasedOnRoute = 0;

      for (const deliveryItem of deliveryShipContents) {
        // Add the amount of the current item to the total amount counter
        totalPurchasedOnRoute += deliveryItem.amount;
      }

      console.warn(`ding`, credits, totalPrice, (credits - totalPrice), itemName)
      if (credits < totalPrice) {
        success = 0;
      }

      if (itemName !== "teleporter" && itemName !== "inverse_teleporter") {
          if (credits >= totalPrice && totalPurchasedOnRoute + itemAmount <= 12) {
            success = 1;
          }
          if (credits >= totalPrice && totalPurchasedOnRoute + itemAmount > 12) {
            success = 2;
          }
      } else {
        console.warn(world.getDynamicProperty('js:teleporter'))
        console.warn(world.getDynamicProperty('js:inverse_teleporter'))
        if (itemName == "teleporter" && credits >= totalPrice && world.getDynamicProperty('js:teleporter') == false) {
          success = 1
        }
        if (itemName == "teleporter" && credits >= totalPrice && world.getDynamicProperty('js:teleporter') == true) {
          success = 3
        }

        if (itemName == "inverse_teleporter" && credits >= totalPrice && world.getDynamicProperty('js:inverse_teleporter') == false) {
          success = 1
        }
        if (itemName == "inverse_teleporter" && credits >= totalPrice && world.getDynamicProperty('js:inverse_teleporter') == true) {
          success = 3
        }
      }


      if (success == 0) {
        display += `\n\nYou could not afford these items!\nYour balance is  ${credits}. Total cost of these items is  ${totalPrice}`;
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        const nextForm = new ModalFormData();
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
      if (success == 1) {
        OVERWORLD.playSound("misc.purchase", player.location, SOUND_OPTIONS);

        if (itemName !== "teleporter" && itemName !== "inverse_teleporter") {
          deliveryShipContents.push({ item: itemName, amount: itemAmount });
          let condensedContents = [];

          // Iterate through the original deliveryShipContents array
          for (const delivery of deliveryShipContents) {
            // Check if an entry for the current item already exists in the condensed array
            const existingEntryIndex = condensedContents.findIndex((entry) => entry.item === delivery.item);

            if (existingEntryIndex !== -1) {
              // If an entry already exists, update the amount
              condensedContents[existingEntryIndex].amount += delivery.amount;
            } else {
              // If not, add a new entry
              condensedContents.push({ item: delivery.item, amount: delivery.amount });
            }
          }

          // Replace the original array with the condensed one
          deliveryShipContents = condensedContents;

          const deliveryShipContentsString = JSON.stringify(deliveryShipContents);
          world.setDynamicProperty("deliveryShip", deliveryShipContentsString);
          world.setDynamicProperty("deliveryShipQueue", 1);

          const newCredits = credits - totalPrice;
          creditsScoreboard.setScore("world", parseInt(newCredits));

          const nextForm = new ModalFormData();
          nextForm.title(`Terminal ${newCredits}`);

          display += `\n\nOrdered ${itemAmount} ${itemName}s.\nYour new balance is  ${newCredits}.\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.`;

          nextForm.textField(display, "Enter Command");

          nextForm.show(player).then((response) => {
            if (response.canceled) {
              exitTerminal(player);
              return;
            }
            const userInput = response.formValues[0];
            const inputLowerCase = guessCommand(userInput);

            inputs(player, inputLowerCase, display);
          });
        } else {
          const newCredits = credits - totalPrice;
          creditsScoreboard.setScore("world", parseInt(newCredits));

          const nextForm = new ModalFormData();
          nextForm.title(`Terminal ${newCredits}`);

          display += `\n\nPurchased ${itemName}.\nYour new balance is  ${newCredits}.\n\n`;
          if (itemName == "teleporter") {
            world.setDynamicProperty('js:teleporter', true)
          }
          if (itemName == "inverse_teleporter") {
            world.setDynamicProperty('js:inverse_teleporter', true)
          }
          system.run(() => {
            updateProfitDisplay()
          })

          nextForm.textField(display, "Enter Command");

          nextForm.show(player).then((response) => {
            if (response.canceled) {
              exitTerminal(player);
              return;
            }
            const userInput = response.formValues[0];
            const inputLowerCase = guessCommand(userInput);

            inputs(player, inputLowerCase, display);
          });
        }
      }
      if (success == 2) {
        display += `\n\nThe delivery vehicle cannot hold more than 12 items at a time. Please pick up your items when they land!`;
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        const nextForm = new ModalFormData();
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
      if (success == 3) {
        display += `\n\nYou have already purchased the ${itemName}!`;
        player.playSound("misc.terminal.error", SOUND_OPTIONS);

        const nextForm = new ModalFormData();
        nextForm.title(`Terminal ${credits}`);

        nextForm.textField(display, "Enter Command");

        nextForm.show(player).then((response) => {
          if (response.canceled) {
            exitTerminal(player);
            return;
          }
          const userInput = response.formValues[0];
          const inputLowerCase = guessCommand(userInput);

          inputs(player, inputLowerCase, display);
        });
      }
    }
    if (inputLowerCase == "deny") {
      display += `\n\nYou have cancelled the order.`;

      const nextForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      nextForm.title(`Terminal${credits}`);
      nextForm.textField(display, "Enter Command");

      nextForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }
        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });
    }
    if (inputLowerCase !== "confirm" && inputLowerCase !== "deny") {
      terminalErrorForm(player);
    }
  });
}

function displayHelp(player) {
  const helpForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  helpForm.title(`Terminal ${credits}`);

  let display = `§a>MOONS \nTo see the list of moons the autopilot can route to.\n\n>STORE \nTo see the company store's selection of useful items.\n\n>INFO \nINFO [NAME] to view information on an item.\n\n>CREDITS \nTo view this map's credits.\n\n>SHUT \nTo shush company automated messages.\n\n>ARACHNOPHOBIA \nTo toggle arachnophobia mode.\n\n>SCAN \nScans for objects outside the ship.\n\n>SWITCH \nSWITCH [NAME] to switch monitor display target.\n\n>RESET \nTo fully reset the map`;

  const deliveryShipContentsString = world.getDynamicProperty("deliveryShip");
  const deliveryShipContentsQuery = JSON.parse(deliveryShipContentsString);

  let totalPurchasedOnRoute = 0;

  for (const deliveryItem of deliveryShipContentsQuery) {
    // Add the amount of the current item to the total amount counter
    totalPurchasedOnRoute += deliveryItem.amount;
  }

  if (totalPurchasedOnRoute > 0) {
    display += `\n\n${totalPurchasedOnRoute} items purchased on route.`;
  }

  helpForm.textField(display, "Enter Command");

  helpForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }

    const userInput = response.formValues[0];
    const inputLowerCase = guessCommand(userInput);

    inputs(player, inputLowerCase, display);
  });
}

// Main terminal screen display
export function displayMainScreen(player) {
  terminal = true;
  const date = new Date();
  const dayOfWeek = date.getDay(); // Returns a number from 0 (Sunday) to 6 (Saturday)

  const daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  const dayName = daysOfWeek[dayOfWeek];

  const mainScreenForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  mainScreenForm.title(`Terminal ${credits}`);

  player.playSound("misc.terminal.enter", SOUND_OPTIONS);

  let display;
  if (isFirstDisplay) {
    const rand = Math.random() * 100;
    if (rand < 1) {
      display = `§aIt’s cold here on Earth…\n\n\n\n\n\n\n\n\n\n\n\n\n`;
    } else {
      display = `§aWelcome to the FORTUNE-9 OS\n\n                                   Courtesy of the Company\n\nHappy ${dayName}\n\nType "Help" for a list of commands\n\nNow with Vibrant Visuals support!\n\n\n\n\n\n`;
    }
  } else {
    display = `§a>MOONS \nTo see the list of moons the autopilot can route to.\n\n>STORE \nTo see the company store's selection of useful items.\n\n>INFO \nINFO [NAME] to view information on an item.\n\n>CREDITS \nTo view this map's credits.\n\n>SHUT \nTo shush company automated messages.\n\n>ARACHNOPHOBIA \nTo toggle arachnophobia mode.\n\n>SCAN \nScans for objects outside the ship.\n\n>SWITCH \nSWITCH [NAME] to switch monitor display target.\n\n>RESET \nTo fully reset the map.`;
  }

  const deliveryShipContentsString = world.getDynamicProperty("deliveryShip");
  const deliveryShipContentsQuery = JSON.parse(deliveryShipContentsString);

  let totalPurchasedOnRoute = 0;

  for (const deliveryItem of deliveryShipContentsQuery) {
    // Add the amount of the current item to the total amount counter
    totalPurchasedOnRoute += deliveryItem.amount;
  }

  if (totalPurchasedOnRoute > 0) {
    display += `\n\n${totalPurchasedOnRoute} items purchased on route.`;
  }

  mainScreenForm.textField(display, "Enter Command");

  mainScreenForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }

    const userInput = response.formValues[0];
    const inputLowerCase = guessCommand(userInput);

    inputs(player, inputLowerCase, display);
  });

  // Update isFirstDisplay after the first display
  isFirstDisplay = false;
}

function inputs(player, inputLowerCase, display) {
  const inputParts = inputLowerCase.split(" ");
  let command = inputParts[0];
  let itemName = inputParts[1];
  let itemAmount = parseInt(inputParts[2]) || 1;
  console.warn(
    `passed input:${inputLowerCase}  Command extracted: ${command}, Item Name: ${itemName}, Amount: ${itemAmount}`
  );

  if (storeItems[command] && inputParts[0]) {
    itemName = inputParts[0];
    itemAmount = parseInt(inputParts[1]) || 1;
    command = "buy";
    console.warn(`New command ${command}, Item name ${itemName}, amount ${itemAmount}`);
  }

  console.warn(`${command} ${itemName} ${itemAmount}`);
  switch (command) {
    case "help":
      displayHelp(player);
      break;

    case "moons":
      displayMoons(player);
      break;

    case "store":
      displayStore(player);
      break;

    case "shut":
      player.runCommand(`stopsound @a game.profit.intro`);
      player.runCommand(`stopsound @a game.profit.zero_days_left`);
      worldPlayers.forEach((player) => {
        player.playSound('buttons.ship.speaker_cut')
      })
      exitTerminal(player);
      break;
    // case "storage":
    //   break;
    case "switch":
      switchForm(player, inputLowerCase);
      break;

    case "reset":
      resetConfirmationForm(player);
      break;

    case "arachnophobia":
      arachnophobiaConfirmationForm(player);
      break;

    case "buy":
      buyConfirmationForm(player, itemName, itemAmount);
      break;
    case "turretDisable":

      const turrets = OVERWORLD.getEntities({location: shipEntity.location, maxDistance: 500, type: 'js:turret'})
      for (let turret of turrets) {
        const id = turret.getDynamicProperty('id')
        // console.warn(id, itemName)
        if (id && (id == itemName)) {
          turret.triggerEvent('deactivate')
        }
      }
      const turretDisableForm = new ModalFormData();
      const credits = creditsScoreboard.getScore("world");
      turretDisableForm.title(`Terminal ${credits}`);

      let display = `§a\n\nBroadcasted special code.`;
      player.playSound('misc.terminal.broadcast_code', SOUND_OPTIONS)
      turretDisableForm.textField(display, "Enter Command");

      turretDisableForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }

        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display);
      });

      break;
    case "info":
      const helpForm = new ModalFormData();
      const credits2 = creditsScoreboard.getScore("world");
      helpForm.title(`Terminal ${credits2}`);

      let display2 = `§a\n\nINVALID ITEM`;

      if (STORE_ITEMS_INFO[itemName]) {
        display2 = `§a\n\n${STORE_ITEMS_INFO[itemName].info}`;
      } else {
        display2 = `§a\n\nINVALID ITEM`;
        player.playSound("misc.terminal.error", SOUND_OPTIONS);
      }

      helpForm.textField(display2, "Enter Command");

      helpForm.show(player).then((response) => {
        if (response.canceled) {
          exitTerminal(player);
          return;
        }

        const userInput = response.formValues[0];
        const inputLowerCase = guessCommand(userInput);

        inputs(player, inputLowerCase, display2);
      });
      break;

    case "experimentation":
    case "assurance":
    case "march":
    case "titan":
    case "company":
    case "rend":
    case "artifice":
    case "embrion":
      //   case "vow":
      //   case "offense":
      //   case "adamance":
      //   case "dine":
      moonConfirmationForm(player, command);
      break;
    case "eject":
      ejectForm(player);
      break;
    case "credits":
      credits1(player);
      break;
    case "scan":
      scanForm(player);
      break;
    default:
      terminalErrorForm(player);
  }
}

const commandSynonyms = {
  moons: ["moons"],
  help: ["help"],
  //  "storage": ["storage"],
  store: ["store"],
  info: ["info"],
  //   "bestiary": ["bestiary"],

  confirm: ["c", "con"],
  deny: ["d", "den"],

  eject: ["eject"],
  reset: ["reset"],
  arachnophobia: ["arachnophobia", "ara", "arach", "arachnophobia mode"],
  credits: ["credits", "credit"],
  shut: ["shut"],

  company: ["the company", "com", "the company building", "comp"],
  experimentation: ["exp", "expe", "exper", "experi", "experim", "experime", "experimen", "experiment"],
  march: ["mar"],
  titan: ["tit"],
  rend: ["ren"],
  embrion: ["emb", "embri", "embrio"],
  artifice: ["art", "arti", "artif", "artifi", "artific"],
  assurance: ["ass"],
  // vow: ["vow"],
  // offense: ["off"],
  // adamance: ["ada", "adam", "adama", "adaman", "adamanc", "adamance"],
  // dine: ["din"],

  walkie: ["walkie-talkie", "walkie talkie", "walkie", "wal", "walk"],
  flashlight: ["flashlight", "flash", "fla"],
  pro_flashlight: ["pro-flashlight", "pro flash", "pro-flash", "pro"],
  boombox: ["boombox", "boom", "boo"],
  shovel: ["shovel", "sho", "shov"],
  jetpack: ["jetpack", "jet"],
  //  lockpicker: ["lockpicker","lock","loc"],
  //   stun_grenade: ["stun grenade", "stun", "stu"],
  //   tzp: ["tzp-inhalant", "tzp", "tzp inhalant"],
  //   zap_gun: ["zap gun", "zap"],
  //   extension_ladder: ["extension ladder", "extension", "ext"],
  //   radar_booster: ["radar-booster", "radar booster", "radar", "rad"],
  //   spray_paint: ["spray paint", "spray", "spr"],

  //   loud_horn: ["loud horn", "loud", "lou"],
  //   signal_translator: ["signal translator", "signal", "sig"],
  teleporter: ["teleporter", "tel"],
  inverse_teleporter: ["inverse teleporter", "inverse", "inv"]
};

function guessCommand(input) {
  let inputLowerCase = input.toLowerCase();

  if (inputLowerCase.startsWith("buy")) {
    inputLowerCase = inputLowerCase.slice(3).trim();
  }

  if (
    inputLowerCase.length === 2 &&
    /^[a-z][0-9]$/i.test(inputLowerCase) // Regex ensures the first is a letter and the second is a number
  ) {
    return `turretDisable ${inputLowerCase}`;
  }

  for (let i = inputLowerCase.length; i >= 0; i--) {
    const currentPart = inputLowerCase.slice(0, i);
    // console.warn(`Checking current part: ${currentPart}`);

    for (const [actualCommand, synonyms] of Object.entries(commandSynonyms)) {
      if (currentPart === actualCommand || synonyms.includes(currentPart)) {
        const restOfInput = inputLowerCase.slice(i).trim();

        //  console.warn(`Rest of input after matched command: ${restOfInput}`);

        if (restOfInput) {
          const itemAmount = parseInt(restOfInput);
          if (!isNaN(itemAmount)) {
            // console.warn(`Item amount found: ${itemAmount}`);
            return `${actualCommand} ${itemAmount}`;
          } else {
            for (const [restCommand, restSynonyms] of Object.entries(commandSynonyms)) {
              if (restSynonyms.includes(restOfInput)) {
                const matchedCommand = `${actualCommand} ${restCommand}`;
                //  console.warn(`Matched command with rest of input: ${matchedCommand}`);
                return matchedCommand;
              }
            }
          }
        }

        //  console.warn(`Matched command: ${actualCommand}`);
        return actualCommand;
      }
    }
  }

  //  console.warn(`No match found, returning original input: ${inputLowerCase}`);
  return inputLowerCase;
}

function terminalErrorForm(player) {
  const noCommandForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  noCommandForm.title(`Terminal ${credits}`);
  player.playSound("misc.terminal.error", SOUND_OPTIONS);
  let display;
  display = `§a[There was no action supplied with the word.]`;
  noCommandForm.textField(display, "Enter Command");
  noCommandForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }
    const userInput = response.formValues[0];
    const inputLowerCase = guessCommand(userInput);

    inputs(player, inputLowerCase, display);
  });
}


function scanForm(player) {
  const scanForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  scanForm.title(`Terminal ${credits}`);
  console.warn(`yeee`)
  let scrapValue = 0
  let scrapNum = 0
  const allScrap = OVERWORLD.getEntities({location: shipEntity.location, maxDistance: 800, excludeFamilies: ["equipment", "monster"] })
  for (let scrap of allScrap) {
    const scrapId = scrap.typeId.split('_ent')[0]
    if (!ITEM_LIST[scrapId]) continue
    if (scrap.getDynamicProperty('collected') == true) {
      continue;
    } else {
      let maxValue = ITEM_LIST[scrapId].value[1]
      scrapValue += maxValue
      scrapNum++
    }
  }

  const nutcrackers = OVERWORLD.getEntities({location: shipEntity.location, maxDistance: 500, type: "js:nutcracker" }) 
  for (let nut of nutcrackers) {
    scrapValue += 60
    scrapNum++
  }

  let display = `§aThere are ${scrapNum} objects outside the ship, totalling at an approximate value of  ${scrapValue}`;

  scanForm.textField(display, "Enter Command");
  scanForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }
    const userInput = response.formValues[0];
    const inputLowerCase = guessCommand(userInput);

    inputs(player, inputLowerCase, display);
  });
}


function notImplementedYetForm(player) {
  const noCommandForm = new ModalFormData();
  const credits = creditsScoreboard.getScore("world");
  noCommandForm.title(`Terminal ${credits}`);
  player.playSound("misc.terminal.error", SOUND_OPTIONS);
  let display;
  display = `§a[This command/item has not yet been added.]`;
  noCommandForm.textField(display, "Enter Command");
  noCommandForm.show(player).then((response) => {
    if (response.canceled) {
      exitTerminal(player);
      return;
    }
    const userInput = response.formValues[0];
    const inputLowerCase = guessCommand(userInput);

    inputs(player, inputLowerCase, display);
  });
}

export function exitTerminal(player) {
  player.playSound("misc.terminal.exit", SOUND_OPTIONS);
  player.setProperty("js:player_animation", 0);
  terminal = false;
}

let terminal;
let terminalLocation;

system.afterEvents.scriptEventReceive.subscribe((ev) => {
  const entity = ev.sourceEntity;
  const block = ev.sourceBlock;
  const message = ev.id;

  const command = message.split(" ")[0];
  switch (command) {
    case "js:terminal":
      if (terminal) return;
      if (entity) {
        displayMainScreen(entity);
        entity.setProperty("js:player_animation", 1);
        entity.teleport(
          { x: terminalLocation.x - 0.5, y: terminalLocation.y - 1, z: terminalLocation.z + 0.5 },
          { rotation: { x: 0, y: -90 } }
        );
      } else {
        terminalLocation = block.location;
      }
      break;
    case "js:ui":
      const uiId = ev.message;

      if (uiId == 1) {
        performanceReport(entity);
      }
      if (uiId == 2) {
        updateProfitDisplay();
      }
      if (uiId == 3) {
        tutorial1(entity, false);
      }
      if (uiId == 4) {
        tutorial1(entity, true);
      }
      break;
    case "js:check":
      const testId = ev.message;

      if (testId == 1) {
        //check delivery ship
        const storedDeliveryShipContentsString = world.getDynamicProperty("deliveryShip");
        let deliveryShipContents = JSON.parse(storedDeliveryShipContentsString);
        console.warn(JSON.stringify(deliveryShipContents));
        console.warn(world.getDynamicProperty("deliveryShipQueue"));
      }
      if (testId == 2) {
        const weatherString = JSON.stringify(weather);
        console.warn(JSON.stringify(weatherString));
      }
      break;
    case "js:changeGameState":
      const propertyId = ev.message;

      if (propertyId == 1) {
        applyDiscount();
      }
      if (propertyId == 2) {
        setWeather();
      }
      if (propertyId == 3) {
        calculateNewQuota();
      }
      if (propertyId == 4) {
        calculateOvertimeBonus();
      }
      break;
    case "js:initialize":
      const setId = ev.message;

      if (setId == 1) {
        //initialize delivery ship
        let deliveryShipContents = [];
        const deliveryShipContentsString = JSON.stringify(deliveryShipContents);
        world.setDynamicProperty("deliveryShip", deliveryShipContentsString);
        world.setDynamicProperty("deliveryShipQueue", 0);
        console.warn(`Initialized delivery ship.`);
      }
      if (setId == 2) {
        //initialize store
        const storeItemsString = JSON.stringify(storeItems);
        world.setDynamicProperty("storeItems", storeItemsString);
        console.warn(JSON.stringify(storeItems));
        console.warn(`Initialized Store Items back to default.`);
      }
      if (setId == 3) {
        //initialize weather
        const weatherString = JSON.stringify(weather);
        world.setDynamicProperty("weather", weatherString);
        console.warn(`Initialized weather back to default.`);
      }

      if (setId == 4) {
        //reset delivery ship
        deliveryShipContents = [];
        const deliveryShipContentsString = JSON.stringify(deliveryShipContents);
        world.setDynamicProperty("deliveryShip", deliveryShipContentsString);
        world.setDynamicProperty("deliveryShipQueue", 0);
      }
      break;
    case "js:spawnDelivery":
      const storedDeliveryShipContentsString = entity.getDynamicProperty("deliveryShipContents");
      let deliveryShipContents = JSON.parse(storedDeliveryShipContentsString);

      const offsets = [
        { x: 2, z: 0 },
        { x: 0, z: 2 },
        { x: -2, z: 0 },
        { x: 0, z: -2 },
      ];

      let offsetIndex = 0;

      for (const deliveryItem of deliveryShipContents) {
        const itemName = deliveryItem.item;
        const itemAmount = deliveryItem.amount;
        const entityToSpawn = "js:" + itemName + "_ent";

        // Iterate over the itemAmount and spawn each item at the next offset position
        for (let i = 0; i < itemAmount; i++) {
          // Get the current offset
          const offset = offsets[offsetIndex];

          // Calculate the spawn position relative to the entity's location
          const spawnX = entity.location.x + offset.x;
          const spawnZ = entity.location.z + offset.z;

          // Spawn the item at the calculated position
          OVERWORLD.spawnEntity(entityToSpawn, { x: spawnX, y: entity.location.y + 0.5, z: spawnZ });

          // Increment the offset index and loop back to the first offset if needed
          offsetIndex = (offsetIndex + 1) % offsets.length;
        }
      }
      /*
            deliveryShipContents = []
            const deliveryShipContentsString = JSON.stringify(deliveryShipContents);
            world.setDynamicProperty('deliveryShip', deliveryShipContentsString);

            console.warn(storedDeliveryShipContentsString)
*/

      break;
    case "js:resetDeliveryShip":
      let deliveryShipContents2 = [];
      const deliveryShipContentsString2 = JSON.stringify(deliveryShipContents2);
      world.setDynamicProperty("deliveryShip", deliveryShipContentsString2);
      break;
    default:
      break;
  }
});

let selectedPlayers;
let monitorOn = false;

export function updateProfitDisplay() {
  let centerX = -5999.5;
  let centerY = 200.5;
  let centerZ = 0.99;
  const inOrbit = world.getDynamicProperty("inOrbit");

  shipEntity.setProperty('js:teleporter', world.getDynamicProperty('js:teleporter') ?? false)
  shipEntity.setProperty('js:inverse_teleporter', world.getDynamicProperty('js:inverse_teleporter') ?? false)

  if (inOrbit == true) {
    //tp ~-2 ~44 ~-47
    if (world.getDynamicProperty('js:teleporter') == true) {
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y + 44, z: shipEntity.location.z - 47}, "ding:teleporter_collision")
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y + 44, z: shipEntity.location.z - 46}, "ding:teleporter_collision")
    }
    if (world.getDynamicProperty('js:inverse_teleporter') == true) {
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y + 44, z: shipEntity.location.z - 45}, "ding:teleporter_collision")
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y + 44, z: shipEntity.location.z - 46}, "ding:teleporter_collision")
    }
  } else {
    if (world.getDynamicProperty('js:teleporter') == true) {
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y, z: shipEntity.location.z - 7}, "ding:teleporter_collision")
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y, z: shipEntity.location.z - 6}, "ding:teleporter_collision")
    }
    if (world.getDynamicProperty('js:inverse_teleporter') == true) {
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y, z: shipEntity.location.z - 5}, "ding:teleporter_collision")
      OVERWORLD.setBlockType({x:shipEntity.location.x -2, y: shipEntity.location.y, z: shipEntity.location.z - 6}, "ding:teleporter_collision")
    }
  }
  
  const currentMoonId = world.getDynamicProperty("moon");
  let shipLocation = { x: 0, y: -60, z: 0 };
  let mapKey;
  for (const key of Object.keys(MAPS)) {
    if (MAPS[key].id === currentMoonId) {
      shipLocation = MAPS[key].shipLocation;
      mapKey = key;
      break;
    }
  }

  // console.warn(JSON.stringify(weather))
  let weatherId;
  switch (weather[mapKey]) {
    case "clear":
      weatherId = 0;
      break;
    case "foggy":
      weatherId = 1;
      break;
    case "rainy":
      weatherId = 2;
      break;
    case "flooded":
      weatherId = 3;
      break;
    case "stormy":
      weatherId = 4;
      break;
    case "eclipsed":
      weatherId = 5;
      break;
    default:
      weatherId = 0;
      break;
  }

  if (inOrbit == true) {
    shipEntity.setProperty("js:monitor", currentMoonId);

    centerX = shipLocation.x - 0.01;
    centerY = shipLocation.y + 2.63 + 44;
    centerZ = -10.86 - 40;

    monitorOn = false;
    shipEntity.setProperty("js:weather", weatherId);
    world.setDynamicProperty("currentWeather", 0);
  } else {
    centerX = shipLocation.x - 0.01;
    centerY = shipLocation.y + 2.63;
    centerZ = -10.86;

    shipEntity.setProperty("js:monitor", 12);
    shipEntity.setProperty("js:weather", 0);

    const selectedPlayersFromFamilyPlayer = OVERWORLD.getEntities({
      families: ["player"],
      tags: ["selected"],
    });

    const selectedPlayersFromFamilyBody = OVERWORLD.getEntities({
      families: ["body"],
      tags: ["selected"],
    });

    selectedPlayers = selectedPlayersFromFamilyPlayer.concat(selectedPlayersFromFamilyBody);

    if (selectedPlayers.length <= 0 || selectedPlayers.length > 1) {
      selectPlayer();
    }
    if (selectedPlayers.length > 1) {
      OVERWORLD.runCommand(`tag @e[family=player] remove selected`);
    }

    monitorOn = true;
  }

  world.setDynamicProperty("currentWeather", weatherId);

  const day = world.getDynamicProperty("day");
  shipEntity.setProperty("js:day", day);

  worldPlayers.forEach((player) => {
    player.runCommand(`scriptevent js:ambience`);
  });

  startWeather();
}

function spawnCharacterParticle(character, x, y, z, index) {
  try {
    const isLetter = /[a-zA-Z]/.test(character);

    if (isLetter) {
      // Letter particle
      const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      const position = alphabet.indexOf(character);
      const molangA = new MolangVariableMap();
      molangA.setFloat("variable.size", 0.035);
      molangA.setFloat("variable.alphabet", position);
      molangA.setColorRGB("variable.color", {
        red: 116 / 255,
        green: 251 / 255,
        blue: 248 / 255,
        alpha: 1,
      });
      OVERWORLD.spawnParticle("js:alphabet", { x: x + index * 0.041, y: y, z: z }, molangA);
    } else if (!isNaN(character)) {
      const molangL = new MolangVariableMap();
      molangL.setFloat("variable.size", 0.035);
      molangL.setFloat("variable.number", parseInt(character));
      molangL.setColorRGB("variable.color", {
        red: 116 / 255,
        green: 251 / 255,
        blue: 248 / 255,
        alpha: 1,
      });
      OVERWORLD.spawnParticle("js:number", { x: x + index * 0.041, y: y, z: z }, molangL);
    }
  } catch {}
}

function spawnNameParticles(name, x, y, z) {
  for (let i = 0; i < name.length; i++) {
    const character = name.charAt(i);
    spawnCharacterParticle(character, x, y, z, i);
  }
}

function spawnDigitParticle(digit, x, y, z, index) {
  try {
    const molang = new MolangVariableMap();
    // console.warn(`${x + index * 0.06} ${y} ${z}`)
    molang.setFloat("variable.size", 0.05);
    molang.setFloat("variable.number", digit);
    molang.setColorRGB("variable.color", {
      red: 105 / 255,
      green: 255 / 255,
      blue: 79 / 255,
      alpha: 1,
    });
    OVERWORLD.spawnParticle("js:number", { x: x + index * 0.06, y: y, z: z }, molang);
  } catch {}
}

export function calculateNewQuota() {
  const currentQuota = world.getDynamicProperty("quota");
  const quotasFulfilled = world.getDynamicProperty("quotasFulfilled");
  const timeMultiplier = Math.min(1 + Math.pow(quotasFulfilled, 2) / 16, Math.pow(10, 4));
  const randomizerOffset = 100 * timeMultiplier * (1 + Math.random(0, 1));
  const newQuota = Math.min(Math.round(currentQuota + randomizerOffset), Math.pow(10, 9));

  world.setDynamicProperty("quota", newQuota);

  updateProfitDisplay();
  return newQuota;
}

export function calculateOvertimeBonus() {
  const scrapSold = world.getDynamicProperty("scrapSold");
  const currentQuota = world.getDynamicProperty("quota");
  const day = world.getDynamicProperty("day");
  const overtimeBonus = Math.floor((scrapSold - currentQuota) / 5 + 15 * (3 - day));
  console.warn(overtimeBonus);
  return overtimeBonus;
}

const RADAR_DATA = {
  scrap: {
    particle_type: "js:radar_pip_scrap",
    color: { r: 255, g: 255, b: 0 }, // Yellow
    size: 0.2,
  },
  "minecraft:player": {
    particle_type: "js:radar_pip",
    color: { r: 0, g: 0, b: 255 }, // Blue
    size: 0.2,
  },
  "js:mine": {
    particle_type: "js:radar_pip_hazard",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.3,
  },
  "js:turret": {
    particle_type: "js:radar_pip_turret",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.025,
  },
  "js:body_ent": {
    particle_type: "js:radar_pip",
    color: { r: 0, g: 0, b: 255 }, // Blue
    size: 0.2,
  },
  "js:hoarding_bug": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.1,
  },
  "js:spore_lizard": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.25,
  },
  "js:barber": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.1,
  },
  "js:snare_flea": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.1,
  },
  "js:nutcracker": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.22, //medium
  },
  "js:jester": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.22, //medium
  },
  "js:bracken": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.22, //medium
  },
  "js:eyeless_dog": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.22,
  },
  "js:coil_head": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.17,
  },  
  "js:forest_keeper": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.32,
  },
  "js:earth_leviathan": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.75,
  },
  "js:hygrodere": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.32, //large
  },
  "js:bunker_spider": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.1,
  },
  "js:old_bird": {
    particle_type: "js:radar_pip",
    color: { r: 255, g: 0, b: 0 }, // Red
    size: 0.32,
  },
};

/**
 * @param {Player} player 
 */
function drawRadarPips(player) {
  const playerLocation = player.location;
  let centerX = -5999.5;
  let centerY = 200.5;
  let centerZ = 0.99;

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

  centerX = shipLocation.x + 0.5;
  centerY = shipLocation.y + 1.6;
  centerZ = -10.86;
  if (currentMoonId == 11) {
    centerZ += 17
  }

  const nearbyEntities = OVERWORLD.getEntities({ location: playerLocation, maxDistance: 20 });

  spawnRadarPip(
    { x: centerX, y: centerY, z: centerZ },
    RADAR_DATA["minecraft:player"].size,
    RADAR_DATA["minecraft:player"].color,
    RADAR_DATA["minecraft:player"].particle_type,
    player
  );

  const targetY = player.location.y;
  for (let entity of nearbyEntities) {
    const entityY = entity.location.y;
    if (Math.abs(targetY - entityY) > 6) continue;

    let entityId = entity.typeId;

    const familyComponent = entity.getComponent("minecraft:type_family");
    if (
      familyComponent &&
      familyComponent.hasTypeFamily("scrap") &&
      !familyComponent.hasTypeFamily("body") &&
      !familyComponent.hasTypeFamily("equipment")
    ) {
      entityId = "scrap";
    }

    if (RADAR_DATA[entityId] && entity !== player) {
      const relativeX = centerX + (entity.location.x - playerLocation.x) / 40;
      const relativeY = centerY + (entity.location.z - playerLocation.z) / 40;
      const relativeZ = centerZ;

      spawnRadarPip(
        { x: relativeX, y: relativeY, z: relativeZ },
        RADAR_DATA[entityId].size,
        RADAR_DATA[entityId].color,
        RADAR_DATA[entityId].particle_type,
        entity
      );
    }
  }
}

function spawnRadarPip(position, size, color, particleType, entity) {
  const molang = new MolangVariableMap();
  molang.setFloat("variable.size", size);
  molang.setColorRGB("variable.color", {
    red: color.r / 255,
    green: color.g / 255,
    blue: color.b / 255,
    alpha: 1,
  });
  if (particleType == "js:radar_pip_scrap") {
    molang.setFloat("variable.rotation", entity.getRotation().y);
    OVERWORLD.spawnParticle(particleType, position, molang);
  } else if (particleType == "js:radar_pip_turret") {
    const isDeactivated = entity.hasComponent("minecraft:is_sheared");

    if (isDeactivated) {
      molang.setColorRGB("variable.color", {
        red: 0 / 255,
        green: 255 / 255,
        blue: 0 / 255,
        alpha: 1,
      });
    } else {
      molang.setColorRGB("variable.color", {
        red: 255 / 255,
        green: 0 / 255,
        blue: 0 / 255,
        alpha: 1,
      });
    }
    const id = entity.getDynamicProperty('id'); 
    // console.warn(id);
    
    const letter = id.charAt(0);
    const number = id.substring(1);
    
    const letterValue = letter.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0);
    // console.warn(letterValue)
    
    // Set the variables in molang
    molang.setFloat("variable.number2", parseInt(number));
    molang.setFloat("variable.letter", parseInt(letterValue));

    OVERWORLD.spawnParticle('ding:letter', position, molang);
    OVERWORLD.spawnParticle('ding:number2', {
      x: position.x + 0.06,
      y: position.y,
      z: position.z
    }, molang);



  } else {
    OVERWORLD.spawnParticle(particleType, position, molang);
  }

  if (entity instanceof Player || entity.typeId == "js:body") {
    function vectorToYaw(direction) {
      const { x, z } = direction;

      // Calculate the yaw using atan2
      let yaw = Math.atan2(z, x);

      // Convert from radians to degrees
      yaw = yaw * (180 / Math.PI);

      // Ensure the yaw is within the range [0, 360)
      if (yaw < 0) {
        yaw += 360;
      }

      return yaw;
    }
    const viewDirection = entity.getViewDirection();
    const yaw = vectorToYaw(viewDirection);
    particleType = "js:radar_pip_direction";
    molang.setFloat("variable.size", 0.5);
    molang.setFloat("variable.rotation", yaw);
    molang.setColorRGB("variable.color", {
      red: color.r / 255,
      green: color.g / 255,
      blue: color.b / 255,
      alpha: 1,
    });
    OVERWORLD.spawnParticle(particleType, position, molang);
  }
}

export function selectPlayer(playerName = null) {
  const selectablePlayers = OVERWORLD.getEntities({
    families: ["player"],
    excludeTags: ["spectator"],
  });

  const selectableBodies = OVERWORLD.getEntities({
    families: ["body"],
  });

  const players = selectablePlayers.concat(selectableBodies);

  console.warn(`Listing players SELECT PLAYER`);
  for (let player of players) {
    player.removeTag('selected')
    if (player instanceof Player) {
      console.warn(`Player ${player.nameTag}`);
    } else {
      console.warn(`Body ${player.nameTag}`);
    }
  }

  if (players.length === 0) return;
  let selectedPlayer;
  if (playerName) {
    selectedPlayer = players.find((player) => player.name === playerName);
  }
  if (!selectedPlayer) {
    const randomIndex = Math.floor(Math.random() * players.length);
    selectedPlayer = players[randomIndex];
  }
  selectedPlayer.addTag("selected");
}

export function switchToPlayer(playerName = undefined) {

  const selectablePlayers = OVERWORLD.getEntities({
    families: ["player"],
    excludeTags: ["spectator"],
  });

  const selectableBodies = OVERWORLD.getEntities({
    families: ["body"],
  });

  const players = selectablePlayers.concat(selectableBodies);

  console.warn(`Listing players SWITCH TO PLAYER`);
  for (let player of players) {
    if (player instanceof Player) {
      console.warn(`Player ${player.nameTag}`);
    } else {
      console.warn(`Body ${player.nameTag}`);
    }
  }

  if (players.length === 0) return;

  let playerToSwitchTo;
  if (playerName) {
    playerToSwitchTo = players.find((player) => player.nameTag.toLowerCase() === playerName);
  }

  if (!playerToSwitchTo) {
    const selectedPlayer = players.find((player) => player.hasTag("selected"));
    if (!selectedPlayer) {
      players[0].addTag("selected");
      return;
    }
    const selectedIndex = players.findIndex((player) => player.hasTag("selected"));
    const nextIndex = (selectedIndex + 1) % players.length;
    playerToSwitchTo = players[nextIndex];
  }

  playerToSwitchTo.addTag("selected");

  system.run(() => {
    for (const player of players) {
      if (player !== playerToSwitchTo) {
        player.removeTag("selected");
      }
    }
    playerToSwitchTo.addTag("selected");
    updateProfitDisplay();
  })

  console.warn(`Switched to ${playerToSwitchTo.nameTag}`);

  return playerToSwitchTo;
}


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

  if (worldPlayers && worldPlayers.length > 0) {
    const cutscene = worldPlayers.filter(player => player.hasTag("cutscene"));
  
    if (cutscene.length <= 0) {
      let centerX = -5999.5;
      let centerY = 200.5;
      let centerZ = 0.99;
    
      const inOrbit = world.getDynamicProperty("inOrbit");
      if (inOrbit == true) {
        centerX = shipLocation.x - 0.01;
        centerY = shipLocation.y + 2.63 + 44;
        centerZ = -10.86 - 40;
      } else {
        centerX = shipLocation.x - 0.01;
        centerY = shipLocation.y + 2.63;
        centerZ = -10.86;
      }
    
      if (currentMoonId == 11) {
        centerZ += 17
      }
    
      const scrapSold = world.getDynamicProperty("scrapSold").toString();
      const quota = world.getDynamicProperty("quota").toString();
    
      spawnDigitParticle(11, centerX, centerY, centerZ, 0);
      for (let i = 0; i < scrapSold.length; i++) {
        const digit = scrapSold.charAt(i);
        spawnDigitParticle(parseInt(digit), centerX + 0.04, centerY, centerZ, i);
      }
      spawnDigitParticle(10, centerX + 0.04, centerY, centerZ, scrapSold.length);
    
      spawnDigitParticle(11, centerX, centerY - 0.1, centerZ, 0);
      for (let i = 0; i < quota.length; i++) {
        const digit = quota.charAt(i);
        spawnDigitParticle(parseInt(digit), centerX + 0.04, centerY - 0.1, centerZ, i);
      }
    
      if (monitorOn == false) return;
    
      const targets = OVERWORLD.getEntities({ excludeFamilies: ['inanimate'], tags: ["selected"] });
    
      if (targets.length > 0) {
        for (let target of targets) {
          if (target.hasTag("spectator")) {
            selectPlayer();
          }
          drawRadarPips(target);
    
          const centerX2 = centerX + 0.45;
          const centerY2 = centerY - 0.4225;
          const centerZ2 = centerZ;
          spawnNameParticles(target.nameTag, centerX2, centerY2, centerZ2);
        }
      } else {
        // console.warn(`yee`)
        selectPlayer();
      }
    }
  }
}, 3);
