/**
 * Live SpaceX (SPCX) stock data from Yahoo Finance.
 */
(function () {
  "use strict";

  var SYMBOL = "SPCX";
  var IPO_PRICE = 135;
  var IPO_VALUATION = 1.77e12;
  var REFRESH_MS = 60000;
  var QUOTE_ENDPOINT = "stock-quote.php";

  function $(id) {
    return document.getElementById(id);
  }

  function formatPrice(value) {
    return "$" + value.toFixed(2);
  }

  function formatCompact(value) {
    if (value >= 1e12) {
      return "$" + (value / 1e12).toFixed(2) + "T";
    }
    if (value >= 1e9) {
      return "$" + (value / 1e9).toFixed(2) + "B";
    }
    if (value >= 1e6) {
      return "$" + (value / 1e6).toFixed(2) + "M";
    }
    return formatPrice(value);
  }

  function formatVolume(value) {
    if (value >= 1e9) {
      return (value / 1e9).toFixed(2) + "B";
    }
    if (value >= 1e6) {
      return (value / 1e6).toFixed(2) + "M";
    }
    return value.toLocaleString();
  }

  function setText(id, text) {
    var el = $(id);
    if (el) {
      el.textContent = text;
    }
  }

  function setChangeClass(el, change) {
    if (!el) return;
    el.classList.remove("stock__change--up", "stock__change--down", "stock__change--flat");
    if (change > 0) {
      el.classList.add("stock__change--up");
    } else if (change < 0) {
      el.classList.add("stock__change--down");
    } else {
      el.classList.add("stock__change--flat");
    }
  }

  function fetchQuote() {
    return fetch(QUOTE_ENDPOINT)
      .then(function (res) {
        if (!res.ok) {
          throw new Error("Quote request failed");
        }
        return res.json();
      })
      .then(function (data) {
        var result = data.chart && data.chart.result && data.chart.result[0];
        if (!result || !result.meta) {
          throw new Error("Invalid quote response");
        }
        return result.meta;
      });
  }

  function renderQuote(meta) {
    var price = meta.regularMarketPrice;
    var prevClose = meta.chartPreviousClose || meta.previousClose || price;
    var change = price - prevClose;
    var changePct = prevClose ? (change / prevClose) * 100 : 0;
    var dayHigh = meta.regularMarketDayHigh;
    var dayLow = meta.regularMarketDayLow;
    var weekHigh = meta.fiftyTwoWeekHigh;
    var weekLow = meta.fiftyTwoWeekLow;
    var volume = meta.regularMarketVolume;
    var marketCap = (price / IPO_PRICE) * IPO_VALUATION;
    var rangePct =
      weekHigh > weekLow ? ((price - weekLow) / (weekHigh - weekLow)) * 100 : 0;

    var changeSign = change >= 0 ? "+" : "";
    var changeText =
      changeSign +
      change.toFixed(2) +
      " (" +
      changeSign +
      changePct.toFixed(2) +
      "%)";

    setText("spcx-price", formatPrice(price));
    setText("spcx-last-price", formatPrice(price));
    setText("spcx-change", changeText);
    setText("spcx-change-detail", changeText);
    setText("spcx-day-high", formatPrice(dayHigh));
    setText("spcx-day-low", formatPrice(dayLow));
    setText("spcx-52w-high", formatPrice(weekHigh));
    setText("spcx-52w-low", formatPrice(weekLow));
    setText("spcx-52w-range", formatPrice(weekLow) + " – " + formatPrice(weekHigh));
    setText("spcx-volume", formatVolume(volume));
    setText("spcx-market-cap", formatCompact(marketCap) + " (est.)");
    setText("spcx-company", meta.longName || "Space Exploration Technologies Corp.");
    setText("spcx-symbol", meta.symbol || SYMBOL);
    setText(
      "spcx-exchange",
      (meta.fullExchangeName || "Nasdaq").replace("NasdaqGS", "Nasdaq")
    );

    var updated = meta.regularMarketTime
      ? new Date(meta.regularMarketTime * 1000)
      : new Date();
    setText(
      "spcx-updated",
      updated.toLocaleString(undefined, {
        month: "short",
        day: "numeric",
        year: "numeric",
        hour: "numeric",
        minute: "2-digit",
      })
    );

    setChangeClass($("spcx-change"), change);
    setChangeClass($("spcx-change-detail"), change);

    var bar = $("spcx-range-bar");
    if (bar) {
      bar.style.width = Math.min(100, Math.max(0, rangePct)).toFixed(1) + "%";
      bar.parentElement.setAttribute("aria-valuenow", rangePct.toFixed(0));
    }
  }

  function showError() {
    setText("spcx-change", "Unable to load live data");
    setText("spcx-change-detail", "—");
  }

  function loadQuote() {
    fetchQuote()
      .then(renderQuote)
      .catch(function () {
        showError();
      });
  }

  if (document.getElementById("stock-info")) {
    loadQuote();
    setInterval(loadQuote, REFRESH_MS);
  }
})();
