---
type Props = {
  defaultTheme?: "auto" | "dark" | "light" | undefined;
};

const { defaultTheme = "auto" } = Astro.props;
---

<script is:inline data-default-theme={defaultTheme}>
  window.theme ??= (() => {
    const defaultTheme =
      document.currentScript.getAttribute("data-default-theme");
    const storageKey = "theme";
    const store =
      typeof localStorage !== "undefined"
        ? localStorage
        : { getItem: () => null, setItem: () => {} };

    const mediaMatcher = window.matchMedia("(prefers-color-scheme: light)");
    let systemTheme = mediaMatcher.matches ? "light" : "dark";
    mediaMatcher.addEventListener("change", (event) => {
      systemTheme = event.matches ? "light" : "dark";
      applyTheme(getTheme());
    });

    function applyTheme(theme) {
      const resolvedTheme = theme === "auto" ? systemTheme : theme;
      document.documentElement.dataset.theme = resolvedTheme;
      document.documentElement.style.colorScheme = resolvedTheme;
      document.dispatchEvent(
        new CustomEvent("theme-changed", {
          detail: { theme, systemTheme, defaultTheme }
        })
      );
    }

    function setTheme(theme = defaultTheme) {
      store.setItem(storageKey, theme);
      applyTheme(theme);
    }

    function getTheme() {
      return store.getItem(storageKey) || defaultTheme;
    }

    function getSystemTheme() {
      return systemTheme;
    }

    function getDefaultTheme() {
      return defaultTheme;
    }

    return { setTheme, getTheme, getSystemTheme, getDefaultTheme };
  })();
  theme.setTheme(theme.getTheme());
</script>
<script>
  document.addEventListener("astro:after-swap", () =>
    window.theme.setTheme(window.theme.getTheme())
  );
</script>
