<script lang="ts">
  import { onMount } from 'svelte';

  type ThemeMode = 'light' | 'dark' | 'system';
  type ResolvedTheme = 'light' | 'dark';

  interface ThemeChangeDetail {
    mode: ThemeMode;
    resolved: ResolvedTheme;
  }

  interface ThemeLabels {
    toggle: string;
    system: string;
    light: string;
    dark: string;
  }

  interface ThemeApi {
    getMode(): ThemeMode;
    resolveTheme(mode: ThemeMode): ResolvedTheme;
    applyTheme(mode: ThemeMode): ThemeChangeDetail;
    syncTheme(): ThemeChangeDetail;
  }

  declare global {
    interface Window {
      __termiTheme?: ThemeApi;
    }
  }

  export let labels: ThemeLabels;

  let mode: ThemeMode = 'system';
  let resolved: ResolvedTheme = 'light';

  const themeMeta: Record<ThemeMode, { iconClass: string; color: string }> = {
    light: {
      iconClass: 'fas fa-sun text-sm',
      color: 'var(--secondary)',
    },
    dark: {
      iconClass: 'fas fa-moon text-sm',
      color: 'var(--primary)',
    },
    system: {
      iconClass: 'fas fa-desktop text-sm',
      color: 'var(--text-secondary)',
    },
  };

  function syncTheme(detail?: ThemeChangeDetail) {
    const themeApi = window.__termiTheme;
    if (!themeApi) {
      return;
    }

    const nextState = detail ?? themeApi.syncTheme();
    mode = nextState.mode;
    resolved = nextState.resolved;
  }

  function cycleTheme() {
    const themeApi = window.__termiTheme;
    if (!themeApi) {
      return;
    }

    const currentMode = themeApi.getMode();
    const nextMode: ThemeMode =
      currentMode === 'system' ? 'light' : currentMode === 'light' ? 'dark' : 'system';

    syncTheme(themeApi.applyTheme(nextMode));
  }

  onMount(() => {
    syncTheme();

    const handleThemeChange = (event: Event) => {
      syncTheme((event as CustomEvent<ThemeChangeDetail>).detail);
    };

    window.addEventListener('termi:theme-change', handleThemeChange);

    return () => {
      window.removeEventListener('termi:theme-change', handleThemeChange);
    };
  });

  $: modeLabel =
    mode === 'light' ? labels.light : mode === 'dark' ? labels.dark : labels.system;
  $: resolvedLabel = resolved === 'dark' ? labels.dark : labels.light;
  $: iconClass = themeMeta[mode].iconClass;
  $: iconColor = themeMeta[mode].color;
  $: toggleTitle = `${labels.toggle} · ${modeLabel} / ${resolvedLabel}`;
</script>

<button
  class="theme-toggle terminal-toolbar-iconbtn h-8 w-8 shrink-0"
  aria-label={toggleTitle}
  title={toggleTitle}
  on:click|preventDefault={cycleTheme}
>
  <i class={iconClass} style:color={iconColor}></i>
  <span class="sr-only">{modeLabel} / {resolvedLabel}</span>
</button>
