const header = document.querySelector("[data-header]");
const menuToggle = document.querySelector("[data-menu-toggle]");
const navLinks = document.querySelector("[data-nav-links]");
const toast = document.querySelector("[data-toast]");
const downloadLinks = [...document.querySelectorAll("[data-download-link]")];
const downloadLabels = [...document.querySelectorAll("[data-download-label]")];
const releaseNotes = [...document.querySelectorAll("[data-release-note]")];
const scrollProgress = document.querySelector("[data-scroll-progress]");
let toastTimer;

const setMenu = (open) => {
  if (!(menuToggle instanceof HTMLButtonElement) || !(navLinks instanceof HTMLElement)) return;
  menuToggle.setAttribute("aria-expanded", String(open));
  menuToggle.setAttribute("aria-label", open ? "Fermer le menu" : "Ouvrir le menu");
  navLinks.classList.toggle("is-open", open);
  document.body.classList.toggle("menu-open", open);
};

menuToggle?.addEventListener("click", () => {
  setMenu(menuToggle.getAttribute("aria-expanded") !== "true");
});

navLinks?.querySelectorAll("a").forEach((link) => {
  link.addEventListener("click", () => setMenu(false));
});

window.addEventListener("resize", () => {
  if (window.innerWidth > 920) setMenu(false);
});

const updateScrollState = () => {
  header?.classList.toggle("is-scrolled", window.scrollY > 14);
  if (!(scrollProgress instanceof HTMLElement)) return;
  const distance = document.documentElement.scrollHeight - window.innerHeight;
  const ratio = distance > 0 ? Math.min(1, Math.max(0, window.scrollY / distance)) : 0;
  scrollProgress.style.transform = `scaleX(${ratio})`;
};

const updateHeader = updateScrollState;
updateHeader();
window.addEventListener("scroll", updateHeader, { passive: true });
window.addEventListener("resize", updateScrollState);

const showToast = (message, warning = false) => {
  if (!(toast instanceof HTMLElement)) return;
  window.clearTimeout(toastTimer);
  toast.textContent = message;
  toast.classList.toggle("is-warning", warning);
  toast.hidden = false;
  toastTimer = window.setTimeout(() => {
    toast.hidden = true;
  }, 3400);
};

const copyText = async (value) => {
  try {
    await navigator.clipboard.writeText(value);
  } catch {
    const input = document.createElement("textarea");
    input.value = value;
    input.setAttribute("readonly", "");
    input.style.position = "fixed";
    input.style.opacity = "0";
    document.body.append(input);
    input.select();
    document.execCommand("copy");
    input.remove();
  }
  showToast(`Adresse copiée : ${value}`);
};

document.querySelectorAll("[data-copy]").forEach((button) => {
  button.addEventListener("click", () => copyText(button.getAttribute("data-copy") ?? ""));
});

const updateReleaseNotes = (release) => {
  releaseNotes.forEach((note) => {
    if (!(note instanceof HTMLElement)) return;
    note.classList.toggle("is-ready", release.downloadEnabled === true && release.distributionMode !== "preview");
    const message = note.matches(".download-warning") ? note.querySelector("p") : note.querySelector("span");
    if (!message) return;
    message.textContent = release.downloadEnabled === true && release.distributionMode !== "preview"
      ? `v${release.version} · ${release.platform} · SHA-256 vérifié`
      : release.statusMessage;
  });
};

const setDownloadState = (release) => {
  downloadLinks.forEach((link) => {
    if (!(link instanceof HTMLAnchorElement)) return;
    if (release.downloadEnabled === true) {
      link.href = release.url;
      link.download = release.fileName;
      link.classList.remove("is-disabled");
      link.removeAttribute("aria-disabled");
    } else {
      link.classList.add("is-disabled");
      link.setAttribute("aria-disabled", "true");
    }
  });

  downloadLabels.forEach((label) => {
    label.textContent = release.downloadEnabled === true
      ? `Télécharger le .EXE · ${release.sizeLabel}`
      : "Bientôt disponible";
  });

  document.querySelectorAll("[data-release-version]").forEach((value) => {
    value.textContent = release.version ? `v${release.version}` : "—";
  });
  document.querySelectorAll("[data-release-size]").forEach((value) => {
    value.textContent = release.sizeLabel || "—";
  });
  document.querySelectorAll("[data-release-sha]").forEach((value) => {
    value.textContent = release.sha256 || "Indisponible";
    if (release.sha256) value.setAttribute("title", release.sha256);
  });

  updateReleaseNotes(release);
};

downloadLinks.forEach((downloadLink) => {
  downloadLink.addEventListener("click", (event) => {
    if (downloadLink.getAttribute("aria-disabled") !== "true") return;
    event.preventDefault();
    showToast("Le téléchargement ouvrira dès que la build sera disponible.", true);
  });
});

fetch("./release.json", { cache: "no-store" })
  .then((response) => {
    if (!response.ok) throw new Error(`Release metadata unavailable (${response.status})`);
    return response.json();
  })
  .then(setDownloadState)
  .catch(() => {
    setDownloadState({
      downloadEnabled: false,
      version: null,
      sizeLabel: null,
      sha256: null,
      statusMessage: "Les informations de la release sont momentanément indisponibles.",
    });
  });

const revealElements = document.querySelectorAll(".reveal");
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (!reducedMotion && "IntersectionObserver" in window) {
  const revealObserver = new IntersectionObserver(
    (entries, observer) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) return;
        entry.target.classList.add("is-visible");
        observer.unobserve(entry.target);
      });
    },
    { rootMargin: "0px 0px -6%", threshold: 0.08 },
  );
  revealElements.forEach((element) => revealObserver.observe(element));
} else {
  revealElements.forEach((element) => element.classList.add("is-visible"));
}

document.querySelectorAll(".faq details").forEach((details) => {
  details.addEventListener("toggle", () => {
    if (!details.open) return;
    document.querySelectorAll(".faq details[open]").forEach((other) => {
      if (other !== details) other.open = false;
    });
  });
});

document.querySelectorAll("[data-year]").forEach((element) => {
  element.textContent = String(new Date().getFullYear());
});
