import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';
import { RouterLink } from '@angular/router';
import { BreadcrumbService, LangService } from '@aurora';
import { provideTranslocoScope, TranslocoDirective, TranslocoService } from '@jsverse/transloco';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
  lucideCheck,
  lucideLanguages,
  lucideMaximize,
  lucideMinimize,
  lucideMonitor,
  lucideMoon,
  lucideSun,
} from '@ng-icons/lucide';
import { HlmBreadcrumbImports } from '@spartan-ng/helm/breadcrumb';
import { HlmButtonImports } from '@spartan-ng/helm/button';
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';
import { HlmIconImports } from '@spartan-ng/helm/icon';
import { HlmSeparatorImports } from '@spartan-ng/helm/separator';
import { HlmSidebarImports } from '@spartan-ng/helm/sidebar';
import { HlmTooltipImports } from '@spartan-ng/helm/tooltip';

type Theme = 'light' | 'dark' | 'system';

@Component({
  selector: 'app-site-header',
  imports: [
    RouterLink,
    TranslocoDirective,
    NgIcon,
    HlmSidebarImports,
    HlmSeparatorImports,
    HlmBreadcrumbImports,
    HlmButtonImports,
    HlmDropdownMenuImports,
    HlmIconImports,
    HlmTooltipImports,
  ],
  providers: [
    provideTranslocoScope('navigation'),
    provideIcons({
      lucideCheck,
      lucideLanguages,
      lucideMaximize,
      lucideMinimize,
      lucideMoon,
      lucideMonitor,
      lucideSun,
    }),
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <header class="flex h-16 shrink-0 items-center justify-between gap-2 px-4">
      <div class="flex items-center gap-2">
        <button hlmSidebarTrigger></button>
        <hlm-separator
          class="mr-2 data-[orientation=vertical]:h-4"
          orientation="vertical"
        />
        @if (breadcrumbs().length) {
          <nav
            *transloco="let t"
            hlmBreadcrumb
          >
            <ol hlmBreadcrumbList>
              @for (crumb of breadcrumbs(); track $index; let last = $last) {
                <li
                  class="hidden sm:block"
                  hlmBreadcrumbItem
                >
                  @if (last) {
                    <a hlmBreadcrumbPage>{{ t(crumb.translation) }}</a>
                  } @else {
                    <a
                      [link]="crumb.link ?? '.'"
                      hlmBreadcrumbLink
                    >
                      {{ t(crumb.translation) }}
                    </a>
                  }
                </li>
                @if (!last) {
                  <li
                    class="hidden sm:block"
                    hlmBreadcrumbSeparator
                  ></li>
                }
              }
            </ol>
          </nav>
        }
      </div>

      <div class="flex items-center gap-1">
        <!-- Language -->
        <button
          [hlmDropdownMenuTrigger]="langMenu"
          [hlmTooltip]="'Language'"
          position="bottom"
          hlmBtn
          variant="ghost"
          size="icon-sm"
        >
          <ng-icon
            name="lucideLanguages"
            hlm
            size="sm"
          />
        </button>
        <ng-template #langMenu>
          <hlm-dropdown-menu class="w-36">
            @for (lang of langs(); track lang.id) {
              <button
                hlmDropdownMenuItem
                (click)="setLang(lang.iso6392)"
              >
                <ng-icon
                  name="lucideCheck"
                  class="mr-2"
                  [class.invisible]="currentLang() !== lang.iso6392"
                  hlm
                  size="sm"
                />
                {{ lang.name }}
              </button>
            }
          </hlm-dropdown-menu>
        </ng-template>

        <!-- Fullscreen -->
        <button
          [hlmTooltip]="isFullscreen() ? 'Exit fullscreen' : 'Fullscreen'"
          position="bottom"
          hlmBtn
          variant="ghost"
          size="icon-sm"
          (click)="toggleFullscreen()"
        >
          <ng-icon
            [name]="isFullscreen() ? 'lucideMinimize' : 'lucideMaximize'"
            hlm
            size="sm"
          />
        </button>

        <!-- Theme -->
        <button
          [hlmDropdownMenuTrigger]="themeMenu"
          [hlmTooltip]="'Theme'"
          position="bottom"
          hlmBtn
          variant="ghost"
          size="icon-sm"
        >
          <ng-icon
            [name]="themeIcon()"
            hlm
            size="sm"
          />
        </button>
        <ng-template #themeMenu>
          <hlm-dropdown-menu class="w-36">
            <button
              [checked]="theme() === 'light'"
              hlmDropdownMenuCheckbox
              (triggered)="setTheme('light')"
            >
              <ng-icon
                name="lucideSun"
                class="mr-2"
                hlm
                size="sm"
              />
              Light
            </button>
            <button
              [checked]="theme() === 'dark'"
              hlmDropdownMenuCheckbox
              (triggered)="setTheme('dark')"
            >
              <ng-icon
                name="lucideMoon"
                class="mr-2"
                hlm
                size="sm"
              />
              Dark
            </button>
            <button
              [checked]="theme() === 'system'"
              hlmDropdownMenuCheckbox
              (triggered)="setTheme('system')"
            >
              <ng-icon
                name="lucideMonitor"
                class="mr-2"
                hlm
                size="sm"
              />
              System
            </button>
          </hlm-dropdown-menu>
        </ng-template>
      </div>
    </header>
  `,
})
export class SiteHeader {
  // injections
  private readonly document = inject(DOCUMENT);
  private readonly breadcrumbService = inject(BreadcrumbService);
  private readonly transloco = inject(TranslocoService);
  private readonly langService = inject(LangService);

  // signals
  readonly currentLang = signal(this.transloco.getActiveLang());
  readonly langs = this.langService.active;
  readonly isFullscreen = signal(false);
  readonly theme = signal<Theme>((localStorage.getItem('theme') as Theme) ?? 'system');

  // public variables
  readonly breadcrumbs = this.breadcrumbService.items;

  protected readonly themeIcon = () => {
    switch (this.theme()) {
      case 'light':
        return 'lucideSun';
      case 'dark':
        return 'lucideMoon';
      default:
        return 'lucideMonitor';
    }
  };

  constructor() {
    this.applyTheme(this.theme());

    this.document.addEventListener('fullscreenchange', () => {
      this.isFullscreen.set(!!this.document.fullscreenElement);
    });
  }

  setLang(lang: string) {
    this.transloco.setActiveLang(lang);
    this.currentLang.set(lang);
  }

  toggleFullscreen() {
    if (this.document.fullscreenElement) {
      this.document.exitFullscreen();
    } else {
      this.document.documentElement.requestFullscreen();
    }
  }

  setTheme(theme: Theme) {
    this.theme.set(theme);
    localStorage.setItem('theme', theme);
    this.applyTheme(theme);
  }

  private applyTheme(theme: Theme) {
    const root = this.document.documentElement;
    if (theme === 'system') {
      const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
      root.classList.toggle('dark', prefersDark);
    } else {
      root.classList.toggle('dark', theme === 'dark');
    }
  }
}
