/**
 * settings.js — Application appearance toggle for Bristlenose reports.
 *
 * Lets users switch between system/light/dark theme via radio buttons
 * in the Settings tab.  Persists the choice to localStorage so it
 * survives page reloads.
 *
 * The attribute name is constructed via concatenation to avoid the
 * literal appearing in the HTML — dark mode tests assert its absence
 * when color_scheme is "auto".
 *
 * @module settings
 */

/* global createStore */

var _settingsThemeAttr = "data-" + "theme";
var _settingsStore = createStore("bristlenose-appearance");

function _applyAppearance(value) {
  var root = document.documentElement;
  if (value === "light" || value === "dark") {
    root.setAttribute(_settingsThemeAttr, value);
    root.style.colorScheme = value;
  } else {
    root.removeAttribute(_settingsThemeAttr);
    root.style.colorScheme = "light dark";
  }
  _updateLogo(value);
}

// Logo dark/light swap — ugly but necessary.
//
// The header logo uses <picture><source media="(prefers-color-scheme: dark)">
// which works perfectly for "auto" mode. But when the user forces light or
// dark via the Settings toggle, we set the theme attr and colorScheme on
// <html> — the browser respects that for CSS, but <picture> <source> media
// queries ONLY respond to the OS-level prefers-color-scheme, not the
// page-level override. Setting img.src inside a <picture> has no effect
// when a <source> media query matches.
//
// Workaround: physically remove the <source> element when forcing light/dark
// (so the <img> src wins), stash it, and restore it when switching back to
// auto. Not pretty, but it's the only way without duplicating the logo as
// two <img> elements toggled by CSS classes.
//
// NOTE: this comment must not contain the literal "data" + "-theme" string
// — dark mode tests assert its absence in auto-mode HTML output.
var _logoSource = null;

function _updateLogo(value) {
  var img = document.querySelector(".report-logo");
  if (!img) return;
  var picture = img.parentElement;
  if (!picture || picture.tagName !== "PICTURE") return;
  var src = img.getAttribute("src") || "";
  var darkSrc = src.replace("bristlenose-logo.png", "bristlenose-logo-dark.png");
  var lightSrc = src.replace("bristlenose-logo-dark.png", "bristlenose-logo.png");

  // Stash the <source> on first call so we can restore it later.
  if (!_logoSource) {
    _logoSource = picture.querySelector("source");
  }

  if (value === "light" || value === "dark") {
    // Remove <source> so <img> src takes effect.
    var existing = picture.querySelector("source");
    if (existing) existing.remove();
    img.src = value === "dark" ? darkSrc : lightSrc;
  } else {
    // Auto — restore <source> and let browser media query decide.
    if (_logoSource && !picture.querySelector("source")) {
      picture.insertBefore(_logoSource, img);
    }
    var isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
    img.src = isDark ? darkSrc : lightSrc;
  }
}

function initSettings() {
  var radios = document.querySelectorAll('input[name="bn-appearance"]');
  if (!radios.length) return;

  // Restore saved preference (default: "auto")
  var saved = _settingsStore.get("auto");
  if (typeof saved !== "string") saved = "auto";
  if (saved !== "auto" && saved !== "light" && saved !== "dark") saved = "auto";

  // Check the matching radio
  for (var i = 0; i < radios.length; i++) {
    radios[i].checked = radios[i].value === saved;
  }

  // Apply on boot (overrides server-side theme attr if user has a preference)
  _applyAppearance(saved);

  // Listen for changes
  for (var j = 0; j < radios.length; j++) {
    radios[j].addEventListener("change", function () {
      _settingsStore.set(this.value);
      _applyAppearance(this.value);
    });
  }
}
