<script lang="ts">
  import { browser } from '$app/environment';
  import { afterNavigate } from '$app/navigation';
  import { onMount } from 'svelte';
  import { page } from '$app/stores';

  import '../app.css';
  import Sidebar from '$lib/components/Sidebar.svelte';
  import SearchBar from '$lib/components/SearchBar.svelte';

  type ThemeMode = 'light' | 'dark';
  type PaletteVar =
    | 'bg'
    | 'bg-elevated'
    | 'sidebar-bg'
    | 'card-bg'
    | 'input-bg'
    | 'hover-bg'
    | 'border'
    | 'text'
    | 'text-muted'
    | 'accent'
    | 'accent-dark'
    | 'accent-glow'
    | 'accent-gradient'
    | 'header-bg';

  type PaletteTheme = Record<PaletteVar, string>;

  type Palette = {
    slug: string;
    label: string;
    light: PaletteTheme;
    dark: PaletteTheme;
  };

  const palettes: Palette[] = [
    {
      slug: 'classic',
      label: 'Classic',
      light: {
        bg: '#f8fafc',
        'bg-elevated': '#ffffff',
        'sidebar-bg': '#ffffff',
        'card-bg': '#ffffff',
        'input-bg': 'rgba(15, 23, 42, 0.04)',
        'hover-bg': 'rgba(15, 23, 42, 0.08)',
        border: 'rgba(15, 23, 42, 0.12)',
        text: '#0f172a',
        'text-muted': '#475569',
        accent: '#10b981',
        'accent-dark': '#059669',
        'accent-glow': 'rgba(16, 185, 129, 0.15)',
        'accent-gradient': 'linear-gradient(135deg, #10b981, #06b6d4)',
        'header-bg': 'rgba(255, 255, 255, 0.95)',
      },
      dark: {
        bg: '#0c0f14',
        'bg-elevated': '#12161e',
        'sidebar-bg': '#10141b',
        'card-bg': 'rgba(18, 22, 30, 0.85)',
        'input-bg': 'rgba(255, 255, 255, 0.04)',
        'hover-bg': 'rgba(255, 255, 255, 0.06)',
        border: 'rgba(255, 255, 255, 0.08)',
        text: '#e8ecf4',
        'text-muted': '#7b8498',
        accent: '#10b981',
        'accent-dark': '#059669',
        'accent-glow': 'rgba(16, 185, 129, 0.15)',
        'accent-gradient': 'linear-gradient(135deg, #10b981, #06b6d4)',
        'header-bg': 'rgba(12, 15, 20, 0.85)',
      },
    },
    {
      slug: 'emerald',
      label: 'Emerald',
      light: {
        'bg': '#f6fbf9',
        'bg-elevated': '#ffffff',
        'sidebar-bg': '#ffffff',
        'card-bg': '#ffffff',
        'input-bg': '#ecf7f1',
        'hover-bg': '#d5f0df',
        'border': 'rgba(4, 120, 87, 0.25)',
        'text': '#0b2c1f',
        'text-muted': '#4a6b5c',
        'accent': '#047857',
        'accent-dark': '#065f46',
        'accent-glow': 'rgba(4, 120, 87, 0.2)',
        'accent-gradient': 'linear-gradient(135deg, #047857, #0ea5e9)',
        'header-bg': 'rgba(255, 255, 255, 0.95)',
      },
      dark: {
        'bg': '#0b1313',
        'bg-elevated': 'rgba(4, 20, 15, 0.85)',
        'sidebar-bg': '#08110f',
        'card-bg': 'rgba(6, 19, 13, 0.75)',
        'input-bg': 'rgba(16, 185, 129, 0.08)',
        'hover-bg': 'rgba(16, 185, 129, 0.12)',
        'border': 'rgba(16, 185, 129, 0.35)',
        'text': '#e9fcea',
        'text-muted': '#9fdac4',
        'accent': '#10b981',
        'accent-dark': '#059669',
        'accent-glow': 'rgba(16, 185, 129, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #10b981, #0ea5e9)',
        'header-bg': 'rgba(12, 15, 20, 0.85)',
      },
    },
    {
      slug: 'sunset',
      label: 'Sunset',
      light: {
        'bg': '#fff8f2',
        'bg-elevated': '#ffffff',
        'sidebar-bg': '#ffffff',
        'card-bg': '#fff4ef',
        'input-bg': '#ffe3d8',
        'hover-bg': '#ffd3bf',
        'border': 'rgba(249, 115, 22, 0.25)',
        'text': '#3d1b0b',
        'text-muted': '#7a4a37',
        'accent': '#f97316',
        'accent-dark': '#c2410c',
        'accent-glow': 'rgba(249, 115, 22, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #f97316, #ec4899)',
        'header-bg': 'rgba(255, 255, 255, 0.96)',
      },
      dark: {
        'bg': '#0f0505',
        'bg-elevated': 'rgba(15, 5, 5, 0.85)',
        'sidebar-bg': '#0c0404',
        'card-bg': 'rgba(19, 6, 6, 0.7)',
        'input-bg': 'rgba(251, 113, 133, 0.08)',
        'hover-bg': 'rgba(251, 113, 133, 0.14)',
        'border': 'rgba(251, 113, 133, 0.35)',
        'text': '#ffe7e0',
        'text-muted': '#f9a6aa',
        'accent': '#fb7185',
        'accent-dark': '#be123c',
        'accent-glow': 'rgba(251, 113, 133, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #fb7185, #f97316)',
        'header-bg': 'rgba(12, 8, 6, 0.85)',
      },
    },
    {
      slug: 'ocean',
      label: 'Ocean',
      light: {
        'bg': '#f4fbff',
        'bg-elevated': '#ffffff',
        'sidebar-bg': '#ffffff',
        'card-bg': '#f0f7ff',
        'input-bg': '#dcefff',
        'hover-bg': '#cae8ff',
        'border': 'rgba(14, 165, 233, 0.25)',
        'text': '#06274e',
        'text-muted': '#4d6993',
        'accent': '#0ea5e9',
        'accent-dark': '#0369a1',
        'accent-glow': 'rgba(14, 165, 233, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #0ea5e9, #4753ff)',
        'header-bg': 'rgba(255, 255, 255, 0.95)',
      },
      dark: {
        'bg': '#030b12',
        'bg-elevated': 'rgba(2, 9, 20, 0.85)',
        'sidebar-bg': '#050c16',
        'card-bg': 'rgba(3, 13, 26, 0.75)',
        'input-bg': 'rgba(14, 165, 233, 0.08)',
        'hover-bg': 'rgba(14, 165, 233, 0.15)',
        'border': 'rgba(14, 165, 233, 0.4)',
        'text': '#e6f6ff',
        'text-muted': '#a1c4e8',
        'accent': '#38bdf8',
        'accent-dark': '#0369a1',
        'accent-glow': 'rgba(14, 165, 233, 0.35)',
        'accent-gradient': 'linear-gradient(135deg, #38bdf8, #0f172a)',
        'header-bg': 'rgba(6, 15, 30, 0.85)',
      },
    },
    {
      slug: 'orchid',
      label: 'Orchid',
      light: {
        'bg': '#fdf6ff',
        'bg-elevated': '#ffffff',
        'sidebar-bg': '#ffffff',
        'card-bg': '#fdf2ff',
        'input-bg': '#f5e4ff',
        'hover-bg': '#e9d4ff',
        'border': 'rgba(168, 85, 247, 0.25)',
        'text': '#2c0a3a',
        'text-muted': '#6a5277',
        'accent': '#a855f7',
        'accent-dark': '#6d28d9',
        'accent-glow': 'rgba(168, 85, 247, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #c084fc, #a855f7)',
        'header-bg': 'rgba(255, 255, 255, 0.97)',
      },
      dark: {
        'bg': '#0c0215',
        'bg-elevated': 'rgba(10, 3, 30, 0.85)',
        'sidebar-bg': '#090118',
        'card-bg': 'rgba(12, 2, 25, 0.75)',
        'input-bg': 'rgba(168, 85, 247, 0.08)',
        'hover-bg': 'rgba(168, 85, 247, 0.16)',
        'border': 'rgba(168, 85, 247, 0.35)',
        'text': '#f5e6ff',
        'text-muted': '#c5a3e8',
        'accent': '#d946ef',
        'accent-dark': '#831843',
        'accent-glow': 'rgba(217, 70, 239, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #d946ef, #fb7185)',
        'header-bg': 'rgba(13, 6, 23, 0.95)',
      },
    },
    {
      slug: 'citrus',
      label: 'Citrus',
      light: {
        'bg': '#fffdf5',
        'bg-elevated': '#ffffff',
        'sidebar-bg': '#ffffff',
        'card-bg': '#fffaf0',
        'input-bg': '#fff4d8',
        'hover-bg': '#ffeec1',
        'border': 'rgba(250, 204, 21, 0.25)',
        'text': '#1f1505',
        'text-muted': '#5b4a1e',
        'accent': '#fbbf24',
        'accent-dark': '#c2410c',
        'accent-glow': 'rgba(250, 204, 21, 0.3)',
        'accent-gradient': 'linear-gradient(135deg, #fbbf24, #d97706)',
        'header-bg': 'rgba(255, 255, 255, 0.98)',
      },
      dark: {
        'bg': '#1a1203',
        'bg-elevated': 'rgba(26, 18, 3, 0.9)',
        'sidebar-bg': '#130e02',
        'card-bg': 'rgba(26, 18, 3, 0.75)',
        'input-bg': 'rgba(250, 204, 21, 0.08)',
        'hover-bg': 'rgba(250, 204, 21, 0.14)',
        'border': 'rgba(250, 204, 21, 0.35)',
        'text': '#fff8e7',
        'text-muted': '#f6dea1',
        'accent': '#fbbf24',
        'accent-dark': '#b45309',
        'accent-glow': 'rgba(250, 204, 21, 0.25)',
        'accent-gradient': 'linear-gradient(135deg, #fbbf24, #f97316)',
        'header-bg': 'rgba(15, 9, 2, 0.9)',
      },
    },
  ];
  const matomoContainerSrc = 'https://matomo.howdoyouconvert.com/js/container_B3r877Kn.js';

  type WindowWithAnalytics = Window & {
    _mtm?: Array<Record<string, unknown>>;
    requestIdleCallback?: (callback: () => void, options?: { timeout: number }) => number;
    cancelIdleCallback?: (handle: number) => void;
  };

  let sidebarOpen = false;
  let headerSearchOpen = false;
  let isMobileHeader = false;
  let theme: ThemeMode = 'dark';
  let selectedPaletteIndex = 0;
  $: isHomepage = $page.url.pathname === '/';
  $: if (isHomepage && (sidebarOpen || headerSearchOpen)) {
    sidebarOpen = false;
    headerSearchOpen = false;
  }
  $: if (!isMobileHeader && headerSearchOpen) {
    headerSearchOpen = false;
  }

  const applyPalette = (index: number, persist = false) => {
    const normalizedIndex = Math.max(0, Math.min(index, palettes.length - 1));
    selectedPaletteIndex = normalizedIndex;
    if (!browser) return;
    const slug = palettes[normalizedIndex].slug;
    document.documentElement.dataset.palette = slug;
    if (persist) {
      window.localStorage.setItem('palette', slug);
    }
  };

  const updateTheme = (value: ThemeMode, persist = false) => {
    theme = value;
    if (!browser) return;
    document.documentElement.dataset.theme = value;
    if (persist) {
      window.localStorage.setItem('theme', value);
    }
  };

  const toggleTheme = () => {
    const nextTheme: ThemeMode = theme === 'dark' ? 'light' : 'dark';
    updateTheme(nextTheme, true);
  };

  const setPalette = (index: number) => {
    applyPalette(index, true);
  };

  const toggleHeaderSearch = () => {
    headerSearchOpen = !headerSearchOpen;
    if (headerSearchOpen) {
      sidebarOpen = false;
    }
  };

  const loadMatomoContainer = () => {
    if (!browser) return;
    if (document.querySelector(`script[src="${matomoContainerSrc}"]`)) return;

    const appWindow = window as WindowWithAnalytics;
    const queue = appWindow._mtm ?? [];
    appWindow._mtm = queue;
    queue.push({ 'mtm.startTime': Date.now(), event: 'mtm.Start' });

    const script = document.createElement('script');
    script.async = true;
    script.src = matomoContainerSrc;
    script.setAttribute('data-cfasync', 'false');
    document.head.appendChild(script);
  };

  afterNavigate(() => {
    sidebarOpen = false;
    headerSearchOpen = false;
  });

  onMount(() => {
    if (!browser) return;
    const appWindow = window as WindowWithAnalytics;
    let idleCallbackId: number | null = null;
    let fallbackTimeoutId: number | null = null;

    const savedTheme = window.localStorage.getItem('theme') as ThemeMode | null;
    const savedPalette = window.localStorage.getItem('palette');
    const paletteIndex = palettes.findIndex(palette => palette.slug === savedPalette);
    const initialPaletteIndex = paletteIndex >= 0 ? paletteIndex : 0;
    applyPalette(initialPaletteIndex, Boolean(savedPalette));

    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const initialTheme: ThemeMode = savedTheme ?? (mediaQuery.matches ? 'dark' : 'light');
    updateTheme(initialTheme, Boolean(savedTheme));

    const handlePreferenceChange = (event: MediaQueryListEvent) => {
      if (window.localStorage.getItem('theme')) return;
      updateTheme(event.matches ? 'dark' : 'light');
    };

    const navBreakpoint = window.matchMedia('(max-width: 1024px)');
    const handleNavBreakpoint = (event: MediaQueryListEvent) => {
      if (event.matches) {
        sidebarOpen = false;
      }
    };
    const headerBreakpoint = window.matchMedia('(max-width: 768px)');
    const updateHeaderBreakpoint = (event?: MediaQueryListEvent) => {
      const isCompact = event?.matches ?? headerBreakpoint.matches;
      isMobileHeader = isCompact;
      if (!isCompact) {
        headerSearchOpen = false;
      }
    };
    const handleHeaderBreakpoint = (event: MediaQueryListEvent) => {
      updateHeaderBreakpoint(event);
    };

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        sidebarOpen = false;
        headerSearchOpen = false;
      }
    };
    window.addEventListener('keydown', handleEscape);

    if (navBreakpoint.matches) {
      sidebarOpen = false;
    }
    updateHeaderBreakpoint();
    if (typeof appWindow.requestIdleCallback === 'function') {
      idleCallbackId = appWindow.requestIdleCallback(loadMatomoContainer, { timeout: 3000 });
    } else {
      fallbackTimeoutId = window.setTimeout(loadMatomoContainer, 1200);
    }

    const cleanup = () => {
      if ('removeEventListener' in mediaQuery) {
        mediaQuery.removeEventListener('change', handlePreferenceChange);
      } else {
        mediaQuery.removeListener(handlePreferenceChange);
      }
      if ('removeEventListener' in navBreakpoint) {
        navBreakpoint.removeEventListener('change', handleNavBreakpoint);
      } else {
        navBreakpoint.removeListener(handleNavBreakpoint);
      }
      if ('removeEventListener' in headerBreakpoint) {
        headerBreakpoint.removeEventListener('change', handleHeaderBreakpoint);
      } else {
        headerBreakpoint.removeListener(handleHeaderBreakpoint);
      }
      if (idleCallbackId !== null && typeof appWindow.cancelIdleCallback === 'function') {
        appWindow.cancelIdleCallback(idleCallbackId);
      }
      if (fallbackTimeoutId !== null) {
        window.clearTimeout(fallbackTimeoutId);
      }
      window.removeEventListener('keydown', handleEscape);
    };

    if ('addEventListener' in mediaQuery) {
      mediaQuery.addEventListener('change', handlePreferenceChange);
    } else {
      mediaQuery.addListener(handlePreferenceChange);
    }

    if ('addEventListener' in navBreakpoint) {
      navBreakpoint.addEventListener('change', handleNavBreakpoint);
    } else {
      navBreakpoint.addListener(handleNavBreakpoint);
    }
    if ('addEventListener' in headerBreakpoint) {
      headerBreakpoint.addEventListener('change', handleHeaderBreakpoint);
    } else {
      headerBreakpoint.addListener(handleHeaderBreakpoint);
    }

    return cleanup;
  });
</script>

<svelte:head>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg?v=2" />
</svelte:head>

<a href="#main-content" class="skip-link">Skip to main content</a>

<header class="site-header">
  <div class="header-left">
    {#if !isHomepage}
      <button
        type="button"
        class="hamburger"
        on:click={() => {
          sidebarOpen = !sidebarOpen;
          if (sidebarOpen) {
            headerSearchOpen = false;
          }
        }}
        aria-label="Toggle menu"
        aria-controls="site-navigation"
        aria-expanded={sidebarOpen ? 'true' : 'false'}
      >
        ☰
      </button>
    {/if}
    <a href="/" class="site-logo">
      <span>How Do You</span><span class="logo-accent">Convert</span><span class="logo-domain">.com</span>
    </a>
  </div>
  <div class="header-right">
    {#if !isHomepage}
      <div class="desktop-header-search">
        <SearchBar idPrefix="header-search" />
      </div>
      <button
        type="button"
        class="header-icon-btn search-toggle"
        on:click={toggleHeaderSearch}
        aria-controls="mobile-header-search"
        aria-expanded={headerSearchOpen ? 'true' : 'false'}
        aria-label={headerSearchOpen ? 'Close search' : 'Open search'}
      >
        <span aria-hidden="true">🔍</span>
      </button>
    {/if}
  </div>
</header>

{#if !isHomepage}
  <div id="mobile-header-search" class="mobile-header-search" class:open={headerSearchOpen} hidden={!headerSearchOpen}>
    <SearchBar idPrefix="mobile-header-search" />
  </div>
{/if}

<div class="site-body">
  {#if !isHomepage}
    <Sidebar bind:open={sidebarOpen} />
  {/if}
  <main id="main-content" class="main-content" tabindex="-1">
    <slot />
  </main>
</div>

<div class="floating-palette-controls" role="group" aria-label="Theme and palette controls">
  <div class="palette-dots">
    {#each palettes as palette, index}
      <button
        type="button"
        class="palette-dot"
        class:active={index === selectedPaletteIndex}
        aria-pressed={index === selectedPaletteIndex}
        aria-label={`Switch to ${palette.label} palette`}
        style={`background-image: ${palette[theme]['accent-gradient']};`}
        on:click={() => setPalette(index)}
      ></button>
    {/each}
  </div>
  <button
    type="button"
    class="theme-toggle"
    on:click={toggleTheme}
    aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}
  >
    <span aria-hidden="true">{theme === 'dark' ? '☀️' : '🌙'}</span>
  </button>
</div>

<footer class="site-footer">
  © {new Date().getFullYear()} HowDoYouConvert.com — Free unit conversion calculators. All rights reserved.
</footer>
