---
import { getPublicConfig } from "../lib/config";

type Props = {
  title: string;
  description: string;
  canonicalPath: string;
  ogImageUrl?: string;
};

const { title, description, canonicalPath, ogImageUrl } = Astro.props;
const cfg = getPublicConfig();

const siteUrl = (cfg.siteUrl || "http://localhost:4321").replace(/\/$/, "");
const canonicalUrl = `${siteUrl}${canonicalPath.startsWith("/") ? canonicalPath : `/${canonicalPath}`}`;

const assetSuffix = cfg.assetVersion ? `?v=${encodeURIComponent(cfg.assetVersion)}` : "";
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="generator" content={Astro.generator} />

    <title>{title}</title>
    <meta name="description" content={description} />
    <link rel="canonical" href={canonicalUrl} />

    <meta property="og:type" content="website" />
    <meta property="og:title" content={title} />
    <meta property="og:description" content={description} />
    <meta property="og:url" content={canonicalUrl} />
    {ogImageUrl ? <meta property="og:image" content={ogImageUrl} /> : null}

    <meta name="twitter:card" content={ogImageUrl ? "summary_large_image" : "summary"} />
    <meta name="twitter:title" content={title} />
    <meta name="twitter:description" content={description} />
    {ogImageUrl ? <meta name="twitter:image" content={ogImageUrl} /> : null}

    <link rel="icon" type="image/svg+xml" href="/favicon.png" />
    <link rel="icon" href="/favicon.png" />

    <!-- Display-friendly font (swap to avoid blocking render). -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;800&display=swap"
      rel="stylesheet"
    />

    <link rel="stylesheet" href={`/styles/global.css${assetSuffix}`} />
    
    <script is:inline>
      (() => {
        const THEME_KEY = "site.theme";
        const COOKIE_KEY = "site_theme";

        const validate = (v) => (v === "dark" || v === "light" || v === "high-contrast" ? v : null);

        const readStored = () => {
          try {
            return validate(window.localStorage.getItem(THEME_KEY));
          } catch {
            return null;
          }
        };

        const readCookie = () => {
          try {
            const parts = document.cookie ? document.cookie.split(";") : [];
            for (let i = 0; i < parts.length; i++) {
              const p = parts[i].trim();
              if (!p) continue;
              if (!p.startsWith(COOKIE_KEY + "=")) continue;
              const raw = p.slice((COOKIE_KEY + "=").length);
              try {
                return validate(decodeURIComponent(raw));
              } catch {
                return validate(raw);
              }
            }
            return null;
          } catch {
            return null;
          }
        };

        const forcedColors = () => {
          try {
            return window.matchMedia && window.matchMedia("(forced-colors: active)").matches;
          } catch {
            return false;
          }
        };

        const prefersLight = () => {
          try {
            return window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches;
          } catch {
            return false;
          }
        };

        const stored = readStored() || readCookie();
        const theme = stored || (forcedColors() ? "high-contrast" : prefersLight() ? "light" : "dark");
        document.documentElement.dataset.theme = theme;
      })();
    </script>

    {
      cfg.umami ? (
        <script async defer data-website-id={cfg.umami.websiteId} src={cfg.umami.scriptUrl} />
      ) : null
    }

    {
      // Register SW only in production builds (Astro sets import.meta.env.PROD at build time).
      // Allow opting out via PUBLIC_ENABLE_SW="false".
      import.meta.env.PROD && import.meta.env.PUBLIC_ENABLE_SW !== "false" ? (
        <script is:inline define:vars={{ assetSuffix }}>
          if ("serviceWorker" in navigator) {
            // SW requires HTTPS (or localhost). In prod we expect HTTPS.
            window.addEventListener("load", () => {
              const swUrl = "/sw.js" + assetSuffix;
              navigator.serviceWorker
                .register(swUrl, { scope: "/", updateViaCache: "none" })
                .catch((err) => {
                // Progressive enhancement; keep failures non-fatal.
                console.warn("Service worker registration failed", err);
                });
            });
          }
        </script>

      ) : null
    }
  </head>
  <body>
    <a class="skip-link" href="#main-content">Skip to content</a>
    <header class="site-header">
      <a
        class="brand"
        href="/"
        data-umami-event="click"
        data-umami-event-target_id="nav.brand"
        data-umami-event-placement="nav"
        data-umami-event-target_url="/"
      >
        SanthoshJ
      </a>
      <button
        class="nav-toggle"
        type="button"
        aria-controls="primary-nav"
        aria-expanded="false"
        aria-label="Open menu"
        data-nav-toggle
      >
        <span class="nav-toggle-icon" aria-hidden="true"></span>
      </button>

      <nav class="nav" id="primary-nav" data-open="false">
        <a
          href="/videos"
          data-umami-event="click"
          data-umami-event-target_id="nav.videos"
          data-umami-event-placement="nav"
          data-umami-event-target_url="/videos"
        >
          Videos
        </a>
        <a
          href="/podcast"
          data-umami-event="click"
          data-umami-event-target_id="nav.podcast"
          data-umami-event-placement="nav"
          data-umami-event-target_url="/podcast"
        >
          Podcast
        </a>
        <a
          href="/blog"
          data-umami-event="click"
          data-umami-event-target_id="nav.blog"
          data-umami-event-placement="nav"
          data-umami-event-target_url="/blog"
        >
          Blog
        </a>
        
      </nav>
    </header>

    <aside class="theme-notch" aria-label="Theme" data-theme-notch data-open="false">
      <div
        class="theme-notch-panel"
        id="theme-notch-panel"
        role="radiogroup"
        aria-label="Theme selector"
      >
        <button type="button" class="theme-notch-option" data-theme-option="dark" role="radio" aria-checked="false">
          <span class="theme-notch-dot" aria-hidden="true"></span>
          <span class="theme-notch-text">Dark</span>
        </button>
        <button type="button" class="theme-notch-option" data-theme-option="light" role="radio" aria-checked="false">
          <span class="theme-notch-dot" aria-hidden="true"></span>
          <span class="theme-notch-text">Light</span>
        </button>
        <button
          type="button"
          class="theme-notch-option"
          data-theme-option="high-contrast"
          role="radio"
          aria-checked="false"
        >
          <span class="theme-notch-dot" aria-hidden="true"></span>
          <span class="theme-notch-text">Contrast</span>
        </button>
      </div>
      <button
        type="button"
        class="theme-notch-handle"
        aria-label="Theme"
        aria-controls="theme-notch-panel"
        aria-expanded="false"
        data-theme-notch-handle
      >
        <span class="theme-notch-glyph" aria-hidden="true">
          <svg
            width="18"
            height="18"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <line x1="4" y1="6" x2="20" y2="6"></line>
            <line x1="4" y1="12" x2="20" y2="12"></line>
            <line x1="4" y1="18" x2="20" y2="18"></line>
            <circle cx="9" cy="6" r="2"></circle>
            <circle cx="15" cy="12" r="2"></circle>
            <circle cx="11" cy="18" r="2"></circle>
          </svg>
        </span>
      </button>
    </aside>

    <main class="container" id="main-content">
      <slot />
    </main>

    <footer class="site-footer">
      <p class="muted">&copy; {new Date().getFullYear()} SanthoshJ</p>
    </footer>

    <script is:inline>
      (() => {
        const toggle = document.querySelector("[data-nav-toggle]");
        if (!toggle) return;
        const controlsId = toggle.getAttribute("aria-controls");
        if (!controlsId) return;
        const panel = document.getElementById(controlsId);
        if (!panel) return;

        const mql = window.matchMedia("(max-width: 760px)");

        const setOpen = (open) => {
          toggle.setAttribute("aria-expanded", open ? "true" : "false");
          toggle.setAttribute("aria-label", open ? "Close menu" : "Open menu");

          panel.dataset.open = open ? "true" : "false";

          // Only hide/disable the nav panel in mobile mode. On desktop, nav is always visible/clickable.
          if (mql.matches) {
            panel.setAttribute("aria-hidden", open ? "false" : "true");
            if (open) panel.removeAttribute("inert");
            else panel.setAttribute("inert", "");
          } else {
            panel.removeAttribute("aria-hidden");
            panel.removeAttribute("inert");
          }

          if (!open) toggle.focus({ preventScroll: true });
        };

        // Default state: closed on mobile, open on desktop.
        setOpen(!mql.matches);

        toggle.addEventListener("click", () => {
          const isOpen = toggle.getAttribute("aria-expanded") === "true";
          setOpen(!isOpen);
          if (!isOpen) {
            const firstLink = panel.querySelector("a");
            if (firstLink) firstLink.focus({ preventScroll: true });
          }
        });

        document.addEventListener("keydown", (e) => {
          if (e.key !== "Escape") return;
          if (toggle.getAttribute("aria-expanded") !== "true") return;
          setOpen(false);
        });

        panel.addEventListener("click", (e) => {
          const t = e.target;
          if (t && t.closest && t.closest("a")) setOpen(false);
        });

        document.addEventListener("click", (e) => {
          if (toggle.getAttribute("aria-expanded") !== "true") return;
          const t = e.target;
          if (!t || !t.closest) return;
          if (t.closest("[data-nav-toggle]")) return;
          if (t.closest("#" + CSS.escape(controlsId))) return;
          setOpen(false);
        });

        // If viewport changes, keep desktop usable and default mobile to closed.
        mql.addEventListener("change", () => setOpen(!mql.matches));
      })();
    </script>

    <script is:inline>
      (() => {
        const THEME_KEY = "site.theme";
        const COOKIE_KEY = "site_theme";
        const ONE_YEAR_SECONDS = 31536000;

        const validate = (v) => (v === "dark" || v === "light" || v === "high-contrast" ? v : null);

        const setCookieTheme = (theme) => {
          const v = validate(theme);
          if (!v) return;
          const secure = window.location && window.location.protocol === "https:" ? "; Secure" : "";
          const cookie = `${COOKIE_KEY}=${encodeURIComponent(v)}; Max-Age=${ONE_YEAR_SECONDS}; Path=/; SameSite=Lax${secure}`;
          document.cookie = cookie;
        };

        const setTheme = (next, opts) => {
          const theme = validate(next);
          if (!theme) return;

          const prevTheme = validate(document.documentElement.dataset.theme);
          if (prevTheme === theme) return;

          if (opts && opts.withTransition) {
            document.documentElement.dataset.themeTransition = "on";
          }

          document.documentElement.dataset.theme = theme;

          try {
            window.localStorage.setItem(THEME_KEY, theme);
          } catch {
            // ignore
          }

          try {
            setCookieTheme(theme);
          } catch {
            // ignore
          }

          try {
            if (typeof window.umami !== "undefined") {
              const payload = {
                target_id: `theme.switch.${theme}`,
                placement: "theme_notch",
                theme,
              };
              if (prevTheme) payload.prev_theme = prevTheme;
              window.umami.track("theme_switch", payload);
            }
          } catch {
            // ignore
          }

          if (opts && opts.withTransition) {
            window.setTimeout(() => {
              delete document.documentElement.dataset.themeTransition;
            }, 260);
          }
        };

        const notch = document.querySelector("[data-theme-notch]");
        const handle = document.querySelector("[data-theme-notch-handle]");

        const syncRadios = (theme) => {
          const options = document.querySelectorAll(".theme-notch-option[data-theme-option]");
          for (let i = 0; i < options.length; i++) {
            const el = options[i];
            const v = el.getAttribute("data-theme-option");
            el.setAttribute("aria-checked", v === theme ? "true" : "false");
          }
        };

        const setOpen = (open) => {
          if (!notch || !handle) return;
          notch.dataset.open = open ? "true" : "false";
          handle.setAttribute("aria-expanded", open ? "true" : "false");
        };

        const updateNotchTop = () => {
          const header = document.querySelector(".site-header");
          const subnav = document.querySelector(".subnav");
          const headerRect = header ? header.getBoundingClientRect() : null;
          const headerH = headerRect ? headerRect.height : 0;
          let top = headerH + 12;

          if (subnav) {
            const r = subnav.getBoundingClientRect();
            if (r.top >= 0 && r.top < headerH + 140) {
              top = Math.max(top, r.bottom + 12);
            }
          }

          document.documentElement.style.setProperty("--theme-notch-top", `${Math.round(top)}px`);
        };

        const initialTheme = validate(document.documentElement.dataset.theme) || "dark";
        syncRadios(initialTheme);
        updateNotchTop();

        window.addEventListener("resize", () => updateNotchTop());
        window.addEventListener("scroll", () => updateNotchTop(), { passive: true });

        if (handle) {
          handle.addEventListener("click", () => {
            const open = notch && notch.dataset.open === "true";
            setOpen(!open);
            if (!open) {
              const first = notch && notch.querySelector(".theme-notch-option");
              if (first instanceof HTMLElement) first.focus({ preventScroll: true });
            }
          });
        }

        document.addEventListener("keydown", (e) => {
          if (e.key === "Escape") {
            setOpen(false);
            if (handle) handle.focus({ preventScroll: true });
            return;
          }

          const active = document.activeElement;
          if (!active || !(active instanceof HTMLElement)) return;
          if (!active.classList.contains("theme-notch-option")) return;
          if (e.key !== "ArrowDown" && e.key !== "ArrowUp" && e.key !== "ArrowRight" && e.key !== "ArrowLeft") return;
          e.preventDefault();
          const options = Array.from(
            document.querySelectorAll(".theme-notch-option[data-theme-option]"),
          );
          const idx = options.indexOf(active);
          if (idx < 0) return;
          const dir = e.key === "ArrowDown" || e.key === "ArrowRight" ? 1 : -1;
          const nextEl = options[(idx + dir + options.length) % options.length];
          nextEl.focus({ preventScroll: true });
          const v = nextEl.getAttribute("data-theme-option");
          setTheme(v, { withTransition: true });
          const theme = validate(document.documentElement.dataset.theme) || "dark";
          syncRadios(theme);
        });

        document.addEventListener("click", (e) => {
          const t = e.target;
          if (!t || !t.closest) return;

          const opt = t.closest(".theme-notch-option[data-theme-option]");
          if (opt) {
            const next = opt.getAttribute("data-theme-option");
            setTheme(next, { withTransition: true });
            const active = validate(document.documentElement.dataset.theme) || "dark";
            syncRadios(active);
            return;
          }

          if (notch && notch.dataset.open === "true") {
            if (handle && t.closest("[data-theme-notch-handle]")) return;
            if (t.closest("[data-theme-notch]")) return;
            setOpen(false);
          }
        });
      })();
    </script>

    <script is:inline>
      (() => {
        function reveal(img) {
          img.classList.remove("img-loading");
          img.classList.add("img-loaded");
          var wrap = img.closest(".img-shimmer-wrap");
          if (wrap) wrap.classList.add("img-loaded");
        }
        var imgs = document.querySelectorAll("img.img-loading");
        for (var i = 0; i < imgs.length; i++) {
          (function(img) {
            if (img.complete && img.naturalWidth > 0) {
              reveal(img);
              return;
            }
            img.addEventListener("load", function() { reveal(img); });
            img.addEventListener("error", function() {
              var wrap = img.closest(".img-shimmer-wrap");
              if (wrap) wrap.classList.add("img-error");
            });
          })(imgs[i]);
        }
      })();
    </script>
  </body>
</html>
