import "./style.css";

const app = document.querySelector("#app");

app.innerHTML = `
  <section class="layout">
    <aside class="logbook">
      <ul data-role="log"></ul>
    </aside>
    <div class="stage">
      <img class="background-back" src="/Alice_close_up_sheath_background.png" alt="Tank background" />
      <img class="background-fore" src="/Alice_close_up_sheath_shot.png" alt="Tank overlay" />
      <div class="artist-tag">
        <a href="https://x.com/Raven4Seth" target="_blank" rel="noreferrer noopener" aria-label="Art by SethRaven4"></a>
      </div>
    </div>
    <div class="home-link">
      <a href="https://snowsune.net" title="Back to snowsune.net">
        <img src="https://snowsune.net/static/stickers/bep_bounce.gif" alt="Home" width="20" height="20" />
        Back to snowsune.net!
      </a>
    </div>
  </section>
  <footer>
    Art by <a href="https://x.com/Raven4Seth" target="_blank" rel="noreferrer noopener">SethRaven4</a>
    &bull; Contact <a href="mailto:vixi@snowsune.net">vixi@snowsune.net</a>
  </footer>
`;

const stage = app.querySelector(".stage");
const logList = app.querySelector("[data-role='log']");
let tankData;

async function loadData() {
  try {
    const response = await fetch("/data.json");
    tankData = await response.json();
    renderTank();
  } catch (error) {
    console.error("Failed to load tank data", error);
  }
}

function renderTank() {
  if (!tankData) return;

  clearLayers();
  drawLayers();
  drawLogbook();
}

function clearLayers() {
  stage.querySelectorAll(".liquid-layer").forEach((node) => node.remove());
}

function drawLayers() {
  const { settings, liquids } = tankData;
  const height = stage.offsetHeight;
  const tankHeight = Math.max(
    0,
    height - settings.tankTopOffset - settings.tankBottomOffset
  );

  let offset = 0;
  let cumulative = 0;

  liquids.forEach((liquid) => {
    const layer = document.createElement("div");
    layer.className = "liquid-layer";
    layer.style.bottom = `${settings.tankBottomOffset + offset}px`;

    const layerHeight = (liquid.volume / 100) * tankHeight;
    layer.style.height = `${layerHeight}px`;
    offset += layerHeight;

    if (liquid.image) {
      layer.style.backgroundImage = `url(${liquid.image})`;
      layer.style.backgroundSize = "800px";
      layer.style.backgroundRepeat = "no-repeat";
      layer.style.backgroundPosition = "right 50px top 0";
      layer.style.backgroundColor = liquid.color ?? "transparent";
    } else {
      layer.style.backgroundColor = liquid.color ?? "#fff";
    }

    const label = liquid.url
      ? document.createElement("a")
      : document.createElement("span");
    label.className = "liquid-label";
    label.textContent = `${liquid.name} (${liquid.volume}%)`;
    if (liquid.url) {
      label.href = liquid.url;
      label.target = "_blank";
      label.rel = "noreferrer noopener";
    }

    cumulative += liquid.volume;
    if (cumulative < 20) {
      label.style.left = "18%";
      label.style.transform = "translate(-30%, -50%)";
    }

    layer.appendChild(label);
    stage.appendChild(layer);
  });
}

function drawLogbook() {
  const now = Date.now();
  logList.innerHTML = "";

  tankData.logs?.forEach((log) => {
    const li = document.createElement("li");
    const epochMs =
      typeof log.date === "number" ? log.date * 1000 : Date.parse(log.date);
    const ageHours = (now - epochMs) / (1000 * 60 * 60);

    li.textContent = `${formatRelative(epochMs)} — ${log.text}`;
    li.style.color = mixColor(ageHours);
    if (ageHours < 8) li.classList.add("log-new");

    logList.appendChild(li);
  });

  const container = logList.parentElement;
  container.scrollTo({ top: container.scrollHeight });
}

function formatRelative(epochMs) {
  const diffSeconds = Math.round((epochMs - Date.now()) / 1000);
  const divisions = [
    { amount: 60, unit: "second" },
    { amount: 60, unit: "minute" },
    { amount: 24, unit: "hour" },
    { amount: 7, unit: "day" },
    { amount: 4.34524, unit: "week" },
    { amount: 12, unit: "month" },
    { amount: Number.POSITIVE_INFINITY, unit: "year" }
  ];

  let duration = diffSeconds;
  for (const division of divisions) {
    if (Math.abs(duration) < division.amount) {
      return new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(
        Math.round(duration),
        division.unit
      );
    }
    duration /= division.amount;
  }
}

function mixColor(hours) {
  if (hours <= 0) return "#ffffff";
  if (hours >= 8) return "#888888";
  const t = hours / 8;
  const channel = Math.round(255 + (136 - 255) * t);
  return `rgb(${channel},${channel},${channel})`;
}

window.addEventListener("resize", () => {
  if (!tankData) return;
  requestAnimationFrame(renderTank);
});

loadData();
