(function () {
  function updateClock(clock) {
    clock.innerHTML = new Date().toLocaleTimeString("de-DE", {
      hour: "2-digit",
      minute: "2-digit",
    });
  }

  function ensureTableSize(table, x, y) {
    // Adjust number of rows
    while (table.rows.length < x) {
      table.insertRow();
    }
    while (table.rows.length > x) {
      table.deleteRow(table.rows.length - 1);
    }

    // Ensure each row has y cells
    for (let row of table.rows) {
      while (row.cells.length < y) {
        row.insertCell();
      }
      while (row.cells.length > y) {
        row.deleteCell(row.cells.length - 1);
      }
    }
  }

  function formatWithSign(num) {
    if (num > 0) {
      return `+ ${num}`;
    } else if (num < 0) {
      return `- ${Math.abs(num)}`;
    } else {
      return "";
    }
  }

  function cssClassExists(className) {
    return Array.from(document.styleSheets).some((sheet) => {
      try {
        return Array.from(sheet.cssRules).some(
          (rule) => rule.selectorText === `.${className}`
        );
      } catch (e) {
        // Ignore CORS-restricted stylesheets
        return false;
      }
    });
  }

  function fill_table(data, table) {
    // const res = JSON.parse(result)
    const columns = {
      line: 0,
      destination: 1,
      departure_time: 2,
      departure_delay: 3,
      until_departure: 4,
    };

    // console.log(data)

    // ensureTableSize(table, Math.min(data.length, 8), 5);

    for (let i = 0; i < Math.min(data.length, table.rows.length); i++) {
      const row = table.rows[i];
      console.log(row);

      // row.classList.add("departure-table-row")
      // row.style.height = `$10%`;
      const train = Object.entries(data[i]);
      for (let [key, value] of train) {
        if (key in columns) {
          const cell = row.cells[columns[key]];
          let newContent = "";
          let newClassList = [];

          if (key in columns) {
            newClassList.push(key);
          }

          if (key == "line") {
            const lineClass = `line-${value}`;
            const appliedClass = cssClassExists(lineClass)
              ? lineClass
              : "line-default";
            newContent = `<span class="line-pill ${appliedClass}">${value}</span>`;
          }
          if (key == "destination") {
            let dest = String(value)
              .replace(/\s*\(.*?\)\s*/g, "")
              .replace(/^München\s*/i, "")
              .replace(/^[\s-]+|[\s-]+$/g, "")
              .replace("Ost", "Ostbahnhof")
              .replace("Hbf", "Hauptbahnhof")
              .replace("Gl.", "Gl. ");
            newContent = dest;
          }
          if (key == "departure_time") {
            if (train["canceled"]) {
              newContent = "Fällt aus :(";
              newClassList.push("train-canceled");
            } else {
              const date = new Date(value * 1000);
              newContent = date.toLocaleTimeString("de-DE", {
                hour: "2-digit",
                minute: "2-digit",
              });
            }
          }
          if (key == "departure_delay") {
            if (!train["canceled"]) {
              newContent = formatWithSign(value);
              if (value >= 5) newClassList.push("delay-high");
              else if (value < 0) newClassList.push("delay-neg");
            }
          }
          if (key == "until_departure") {
            if (!train["canceled"]) {
              const minutes = Math.round((value + 0) / 60);
              newContent = String(minutes) + " min";
              if (minutes <= 6) newClassList.push("until-low");
              else if (minutes <= 10) newClassList.push("until-medium");
            }
          }

          // Only update if content changed
          if (
            (cell.innerHTML !== newContent && key === "line") ||
            (cell.textContent !== newContent && key !== "line")
          ) {
            if (key === "line") {
              cell.innerHTML = newContent;
            } else {
              cell.textContent = newContent;
            }
          }

          // Update classes only if changed
          cell.className = ""; // Clear all classes
          for (const cls of newClassList) cell.classList.add(cls);
        }
      }
    }
    // document.querySelector('.departure-table')
    //     .style.setProperty('--row-count', table.rows.length);
  }

  function updateTable(table) {
    fetch("/update", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      // TODO: pass number of rows we want
    })
      .then((response) => response.json())
      .then((result) => {
        // console.log(result);
        fill_table(result.table_data, table);
        // const res = JSON.parse(result);
        // console.log(res.table_data);
        // for (const elem of res.table_data) {
        //   console.log(elem);
        // }
      });
  }

  var clockElement = document.getElementById("clock");
  var tableElement = document.getElementById("departures");

  setInterval(function () {
    updateClock(clockElement);
    updateTable(tableElement);
  }, 1000);
})();
