---
import '@/styles/global.css';
import SEO from '@/components/seo/SEO.astro';
import JsonLd from '@/components/seo/JsonLd.astro';
import Analytics from '@/components/layout/Analytics.astro';
import ConsentBanner from '@/components/ui/overlay/ConsentBanner';
import { ClientRouter } from 'astro:transitions';
import { createWebsiteSchema, createOrganizationSchema, createPersonSchema, createProfessionalServiceSchema } from '@/lib/schema';
import type { WebSite, Organization, Person, WithContext } from 'schema-dts';
import siteConfig from '@/config/site.config';

interface Props {
  title?: string;
  description?: string;
  image?: string;
  imageAlt?: string;
  article?: {
    publishedTime?: Date;
    modifiedTime?: Date;
    authors?: string[];
    tags?: string[];
  };
  noindex?: boolean;
  nofollow?: boolean;
  includeOrgSchema?: boolean;
  includePersonSchema?: boolean;
  includeProfessionalServiceSchema?: boolean;
}

const {
  title,
  description,
  image,
  imageAlt,
  article,
  noindex = false,
  nofollow = false,
  includeOrgSchema = false,
  includePersonSchema = false,
  includeProfessionalServiceSchema = false,
} = Astro.props;

// Build JSON-LD schemas
const schemas: Array<WithContext<WebSite> | WithContext<Organization> | WithContext<Person>> = [createWebsiteSchema()];
if (includeOrgSchema) {
  schemas.push(createOrganizationSchema());
}
if (includePersonSchema) {
  schemas.push(createPersonSchema());
}
if (includeProfessionalServiceSchema) {
  schemas.push(createProfessionalServiceSchema());
}
---

<!doctype html>
<html lang="en" class="scroll-smooth dark" data-theme="blue">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="generator" content={Astro.generator} />

    <!-- Favicon -->
    <link rel="icon" type="image/svg+xml" href={siteConfig.branding.favicon.svg} />
    <link rel="manifest" href="/manifest.webmanifest" />
    <meta name="theme-color" content={siteConfig.branding.colors.themeColor} />

    <!-- SEO -->
    <SEO
      title={title}
      description={description}
      image={image}
      imageAlt={imageAlt}
      article={article}
      noindex={noindex}
      nofollow={nofollow}
    />

    <!-- RSS Feed -->
    <link rel="alternate" type="application/rss+xml" title={`${siteConfig.name} RSS Feed`} href="/rss.xml" />

    <!-- JSON-LD Structured Data -->
    <JsonLd schema={schemas} />

    <!-- Analytics (loads if PUBLIC_GA_MEASUREMENT_ID or PUBLIC_GTM_ID is set) -->
    <Analytics />

    <!-- View Transitions (client-side routing with animated page transitions) -->
    <ClientRouter />

    <!-- Random theme per session — runs synchronously to avoid flash -->
    <script is:inline>
      (function () {
        var THEMES = ['orange','amber','lime','emerald','teal','cyan','sky','blue','indigo','violet','purple','magenta'];
        var KEY = 'color-theme';
        var theme;
        try { theme = sessionStorage.getItem(KEY); } catch (e) {}
        if (!theme) {
          theme = THEMES[Math.floor(Math.random() * THEMES.length)];
          try { sessionStorage.setItem(KEY, theme); } catch (e) {}
        }
        document.documentElement.setAttribute('data-theme', theme);
      })();
    </script>

    <!-- Dynamic favicon: syncs letter (first letter of site name) and color (brand-500) with active theme -->
    <script define:vars={{ _faviconLetter: siteConfig.name.charAt(0).toUpperCase() }}>
      (function () {
        const LETTER = _faviconLetter;

        function updateFavicon() {
          const color = getComputedStyle(document.documentElement).getPropertyValue('--brand-500').trim();
          if (!color) return;
          const svg =
            '<svg width="48" height="48" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">' +
            '<rect width="48" height="48" rx="8" fill="' + color + '"/>' +
            '<text x="24" y="24" text-anchor="middle" dominant-baseline="central" ' +
            'font-family="Outfit, system-ui, sans-serif" font-weight="700" font-size="34" fill="white">' +
            LETTER +
            '</text></svg>';
          const link = document.querySelector('link[rel="icon"]');
          if (link) link.setAttribute('href', 'data:image/svg+xml,' + encodeURIComponent(svg));
        }

        if (document.readyState === 'loading') {
          document.addEventListener('DOMContentLoaded', updateFavicon);
        } else {
          updateFavicon();
        }

        if (!window.__faviconListenerInit) {
          window.__faviconListenerInit = true;

          // Re-run whenever data-theme or dark/light class changes
          new MutationObserver(function (mutations) {
            for (let i = 0; i < mutations.length; i++) {
              if (mutations[i].attributeName === 'data-theme' || mutations[i].attributeName === 'class') {
                updateFavicon();
                break;
              }
            }
          }).observe(document.documentElement, { attributes: true });

          // Re-run after Astro view transitions swap the head
          document.addEventListener('astro:after-swap', updateFavicon);
        }
      })();
    </script>

    <!-- Theme script (runs before body paint; <html> starts with class="dark" as default) -->
    <script is:inline>
      (function () {
        const COLOR_THEMES = ['orange', 'amber', 'lime', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'magenta'];

        function applyTheme(el) {
          try {
            // Dark / light mode
            if (sessionStorage.getItem('theme') === 'light') {
              el.classList.remove('dark');
            } else {
              el.classList.add('dark');
            }
          } catch (_) { /* ignored */ }

          try {
            // Color theme — persisted in sessionStorage so it resets to blue on every new visit
            const saved = sessionStorage.getItem('color-theme');
            if (saved && COLOR_THEMES.indexOf(saved) !== -1) {
              el.setAttribute('data-theme', saved);
            }
          } catch (_) { /* ignored */ }
        }

        applyTheme(document.documentElement);

        if (!window.__themeListenersInit) {
          window.__themeListenersInit = true;

          document.addEventListener('astro:before-swap', function (e) {
            applyTheme(e.newDocument.documentElement);
          });

          document.addEventListener('astro:after-swap', function () {
            applyTheme(document.documentElement);
          });
        }
      })();
    </script>
  </head>

  <body class="min-h-screen bg-background text-foreground antialiased">
    <!-- Skip to content link -->
    <a
      href="#main-content"
      class="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-50 focus:rounded-md focus:bg-primary focus:px-4 focus:py-2 focus:text-primary-foreground"
    >
      Skip to content
    </a>

    <slot name="header" />

    <main id="main-content" class="flex-1">
      <slot />
    </main>

    <slot name="footer" />

    <ConsentBanner />

    <!-- Back to top button -->
    <button
      id="back-to-top"
      aria-label="Back to top"
      class="fixed bottom-6 right-6 z-50 flex h-10 w-10 items-center justify-center rounded-full bg-background border border-border-strong text-foreground-muted shadow-md opacity-0 translate-y-2 pointer-events-none transition-[opacity,transform] duration-200"
    >
      <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m18 15-6-6-6 6"/></svg>
    </button>

    <script is:inline>
      (function () {
        const THRESHOLD = 400;

        function initBackToTop() {
          const btn = document.getElementById('back-to-top');
          if (!btn || btn.dataset.bttInit) return;
          btn.dataset.bttInit = 'true';

          function update() {
            if (window.scrollY > THRESHOLD) {
              btn.classList.remove('opacity-0', 'translate-y-2', 'pointer-events-none');
              btn.classList.add('opacity-100', 'translate-y-0');
            } else {
              btn.classList.add('opacity-0', 'translate-y-2', 'pointer-events-none');
              btn.classList.remove('opacity-100', 'translate-y-0');
            }
          }

          window.addEventListener('scroll', update, { passive: true });
          btn.addEventListener('click', function () {
            window.scrollTo({ top: 0, behavior: 'smooth' });
          });
          update();
        }

        initBackToTop();
        document.addEventListener('astro:page-load', initBackToTop);
        document.addEventListener('astro:after-swap', initBackToTop);
      })();
    </script>

    <!-- Scroll reveal: adds .is-visible to [data-reveal] elements as they enter the viewport -->
    <script is:inline>
      (function () {
        function initReveal() {
          const els = document.querySelectorAll('[data-reveal]:not(.is-visible)');
          if (!els.length) return;
          const observer = new IntersectionObserver(function (entries) {
            entries.forEach(function (entry) {
              if (entry.isIntersecting) {
                entry.target.classList.add('is-visible');
                observer.unobserve(entry.target);
              }
            });
          }, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' });
          els.forEach(function (el) { observer.observe(el); });
        }

        if (document.readyState === 'loading') {
          document.addEventListener('DOMContentLoaded', initReveal);
        } else {
          initReveal();
        }

        document.addEventListener('astro:after-swap', initReveal);
      })();
    </script>
  </body>
</html>
