Adjusting position and ranking in a dynamic table

I have created a piece of code that works with a JSON file to store table data, one of the things the user can do when adding entries is set the rank of their entry. Say we have 5 entries:

Rank = 1 (A),2 (B),3 (C),4 (D),5 (E) respectively then they add an entry with Rank = 18 it should automatically become Rank = 6 (F) to follow the sequential order. Now alternatively if they now edit an existing entry (F) with Rank = 6 and edit its rank to become 1 then the new order should be:

Rank = 1 (F)
Rank = 2 (A)
Rank = 3 (B)
Rank = 4 (C)
Rank = 5 (D)
Rank = 6 (E)

But in my implementation this behavior is not observed instead the ranks don’t seem to swap at all.

This is my current code that I am working on:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Mowie Ranking</title>
    <style>
      :root {
        --background-color: #1c1c1c;
        --text-color: #f4f4f4;
        --header-background: #e67e22;
        --header-border: #d35400;
        --container-background: #333;
        --textarea-background: #2c2c2c;
        --border-color: #e67e22;
        --status-text-color: #f1c40f;
        --saved-text-color: #e74c3c;
        --scrollbar-thumb: #e67e22;
        --scrollbar-track: #333;
        --button-background: #d35400;
        --button-text-color: #fff;
        --button-border-color: #e67e22;
        --button-hover-background: #e67e22;
        --button-hover-text-color: #fff;
        --button-delete-background: #c0392b;
        --button-delete-text-color: #fff;
        --button-delete-hover-background: #e74c3c;
        --button-delete-hover-text-color: #fff;
        --input-background: #2c2c2c;
        --input-border-color: #e67e22;
        --input-text-color: #fff;
      }

      body {
        font-family: "Arial", sans-serif;
        margin: 0;
        padding: 0;
        background: var(--background-color);
        color: var(--text-color);
        text-align: center;
      }

      header {
        background-color: var(--header-background);
        color: #fff;
        padding: 20px;
        font-size: 2.5em;
        border-bottom: 3px solid var(--header-border);
        box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
        position: relative;
        overflow: hidden;
        z-index: 1;
      }

      header::before {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: url("https://www.example.com/halloween-pattern.png")
          no-repeat center center;
        background-size: cover;
        opacity: 0.2;
        z-index: -1;
      }

      .container {
        max-width: 800px;
        margin: 40px auto;
        padding: 20px;
        background: var(--container-background);
        border-radius: 12px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        overflow: hidden;
        text-align: left;
      }

      table {
        width: 100%;
        border-collapse: collapse;
        margin: 20px 0;
      }

      th,
      td {
        border: 1px solid var(--border-color);
        padding: 8px;
        text-align: center;
      }

      th {
        background-color: var(--header-background);
        color: #fff;
      }

      td input {
        width: 100%;
        box-sizing: border-box;
        background-color: var(--input-background);
        border: 1px solid var(--input-border-color);
        color: var(--input-text-color);
        padding: 8px;
        border-radius: 4px;
      }

      .add-entry {
        margin-bottom: 20px;
      }

      .add-entry input,
      .add-entry button {
        margin: 5px 0;
        padding: 10px;
        border-radius: 6px;
        border: 1px solid var(--button-border-color);
        background-color: var(--input-background);
        color: var(--input-text-color);
      }

      .add-entry button {
        background-color: var(--button-background);
        color: var(--button-text-color);
        cursor: pointer;
        transition: background-color 0.3s ease, border-color 0.3s ease;
      }

      .add-entry button:hover {
        background-color: var(--button-hover-background);
        border-color: var(--button-hover-background);
      }

      .delete-btn {
        background-color: var(--button-delete-background);
        color: var(--button-delete-text-color);
        border: none;
        padding: 5px 10px;
        border-radius: 6px;
        cursor: pointer;
        transition: background-color 0.3s ease;
      }

      .delete-btn:hover {
        background-color: var(--button-delete-hover-background);
        color: var(--button-delete-text-color);
      }

      ::-webkit-scrollbar {
        width: 12px;
      }

      ::-webkit-scrollbar-track {
        background: var(--scrollbar-track);
        border-radius: 10px;
      }

      ::-webkit-scrollbar-thumb {
        background: var(--scrollbar-thumb);
        border-radius: 10px;
      }

      ::-webkit-scrollbar-thumb:hover {
        background: #d35400;
      }

      body {
        scrollbar-width: thin;
        scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
      }

      .actions-column {
        width: 60px;
      }

      .mowie-column {
        width: calc(100% - 160px);
      }

      th,
      td {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <header>Mowie Ranking</header>

    <div class="container">
      <div class="add-entry">
        <input type="number" id="rank" placeholder="Rank" min="1" />
        <input type="text" id="mowie" placeholder="Mowie Name" />
        <input
          type="number"
          id="rating"
          placeholder="Rating (1-10)"
          min="1"
          max="10"
        />
        <input type="text" id="genre" placeholder="Genre" />
        <button id="add-entry">Add Entry</button>
      </div>
      <table>
        <thead>
          <tr>
            <th class="actions-column">Actions</th>
            <th>Rank</th>
            <th class="mowie-column">Mowie</th>
            <th>Rating</th>
            <th>Genre</th>
          </tr>
        </thead>
        <tbody id="table-body">
          <!-- Table rows will be dynamically inserted here -->
        </tbody>
      </table>
    </div>

    <script>
      const autosaveDelay = 1000; // Autosave delay in milliseconds

      const tableBody = document.getElementById("table-body");

      // WebSocket connection
      const socket = new WebSocket(`wss://${window.location.host}`);

      socket.addEventListener("open", function () {
        console.log("WebSocket is connected.");
      });

      socket.addEventListener("message", function (event) {
        if (event.data instanceof Blob) {
          const reader = new FileReader();
          reader.onload = function () {
            const data = JSON.parse(reader.result);
            updateTable(data);
          };
          reader.readAsText(event.data);
        } else {
          const data = JSON.parse(event.data);
          updateTable(data);
        }
      });

      // Add new entry
      document
        .getElementById("add-entry")
        .addEventListener("click", function () {
          const rank = parseInt(document.getElementById("rank").value, 10);
          const mowie = document.getElementById("mowie").value;
          const rating = document.getElementById("rating").value + "/10";
          const genre = document.getElementById("genre").value;

          if (mowie && rating && genre) {
            let nextRank = rank || tableBody.rows.length + 1;

            if (rank) {
              // Adjust ranks if a rank is provided
              const rows = Array.from(tableBody.rows);
              rows.forEach((row) => {
                const currentRank = parseInt(row.cells[1].innerText, 10);
                if (currentRank >= rank) {
                  row.cells[1].innerText = currentRank + 1;
                }
              });
            }

            const row = tableBody.insertRow();
            row.insertCell(0).innerHTML =
              '<button class="delete-btn">Delete</button>';
            row.insertCell(1).innerText = nextRank; // Assign rank
            row.insertCell(2).innerText = mowie;
            row.insertCell(3).innerText = rating;
            row.insertCell(4).innerText = genre;

            updateAndSave(); // Save the new entry
            document.getElementById("rank").value = "";
            document.getElementById("mowie").value = "";
            document.getElementById("rating").value = "";
            document.getElementById("genre").value = "";
          }
        });

      // Update and save function
      function updateAndSave() {
        const rows = Array.from(tableBody.rows);
        updateTable(updatedData);
        // Create an array to hold the updated data
        const updatedData = rows.map((row, index) => ({
          rank: index + 1, // Assign sequential ranks starting from 1
          mowie: row.cells[2].innerText,
          rating: row.cells[3].innerText,
          genre: row.cells[4].innerText,
        }));

        // Update the table with new ranks
        rows.forEach((row, index) => {
          row.cells[1].innerText = updatedData[index].rank;
        });

        // Send updated data to the server
        fetch(`/save-file`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(updatedData),
        }).catch((error) => console.error("Error saving file:", error));
      }

      // Autosave on content change
      let timeout;
      tableBody.addEventListener("input", function () {
        clearTimeout(timeout);
        timeout = setTimeout(updateAndSave, autosaveDelay); // Autosave after specified delay of inactivity
      });

      // Load the file content when the page loads
      window.onload = function () {
        fetch(`/get-file-content`)
          .then((response) => response.json())
          .then((data) => {
            updateTable(data);
          })
          .catch((error) => console.error("Error loading file:", error));
      };

      // Update table with new data
      function updateTable(data) {
        tableBody.innerHTML = "";
        data.forEach((item) => {
          const row = tableBody.insertRow();
          row.insertCell(0).innerHTML =
            '<button class="delete-btn">Delete</button>';
          row.insertCell(1).innerText = item.rank;
          row.insertCell(2).innerText = item.mowie;
          row.insertCell(3).innerText = item.rating;
          row.insertCell(4).innerText = item.genre;
        });
      }

      // Handle cell editing
      tableBody.addEventListener("dblclick", function (event) {
        const cell = event.target.closest("td");
        if (cell && cell.cellIndex > 0) {
          // Allow editing in all columns except Actions
          const originalText = cell.innerText;
          const input = document.createElement("input");
          input.value = originalText;
          input.style.width = "100%";
          input.style.boxSizing = "border-box";
          input.style.backgroundColor = "var(--input-background)";
          input.style.border = "1px solid var(--input-border-color)";
          input.style.color = "var(--input-text-color)";
          input.style.padding = "8px";
          input.style.borderRadius = "4px";

          cell.innerHTML = "";
          cell.appendChild(input);

          input.focus();
          input.addEventListener("blur", function () {
            const newValue = input.value;
            if (newValue !== originalText) {
              if (cell.cellIndex === 1) {
                // Rank column
                const newRank = parseInt(newValue, 10);
                if (!isNaN(newRank) && newRank > 0) {
                  // Update ranks for rows with rank >= newRank
                  const rows = Array.from(tableBody.rows);
                  rows.forEach((row) => {
                    const rankCell = row.cells[1];
                    const rankValue = parseInt(rankCell.innerText, 10);
                    if (rankValue >= newRank && rankCell !== cell) {
                      rankCell.innerText = rankValue + 1;
                    }
                  });

                  // Update the rank of the current cell
                  cell.innerText = newRank;

                  // Reorder and update ranks
                  sortAndReassignRanks(); // Reorder rows and update ranks
                } else {
                  cell.innerText = originalText;
                }
              } else {
                cell.innerText = newValue;
              }
              updateAndSave(); // Only update and save after changes
            } else {
              cell.innerText = originalText;
            }
          });

          input.addEventListener("keydown", function (event) {
            if (event.key === "Enter") {
              input.blur();
            }
          });
        }
      });

      // Handle row deletion
      tableBody.addEventListener("click", function (event) {
        if (event.target.classList.contains("delete-btn")) {
          const row = event.target.closest("tr");
          row.remove();

          // Adjust ranks after deletion
          updateAndSave(); // Ranks will be sequentially updated in updateAndSave
        }
      });
    </script>
  </body>
</html>