import { CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu';
import {
  ChangeDetectionStrategy,
  Component,
  ViewEncapsulation,
  computed,
  inject,
} from '@angular/core';
import { Icon, type IconName } from 'shared-ui';
import { LayoutStateService, type ThemeMode } from 'shared-state';

/**
 * Light / dark / auto color-scheme switcher rendered in the header.
 *
 * The trigger is a single icon button whose glyph reflects the
 * currently SELECTED mode (sun / moon / monitor — not the effective
 * theme), so the user can tell which mode they're in even when `auto`
 * happens to resolve to the same scheme as a manual pick. Clicking
 * the button opens a CDK-driven menu (proper roving tabindex,
 * Escape/click-outside dismissal) with the three options; the
 * currently-selected one gets a check mark.
 *
 * State lives in `LayoutStateService` — this component is a thin view
 * over `themeMode()` + `setThemeMode()`.
 */

interface ModeOption {
  readonly mode: ThemeMode;
  readonly label: string;
  readonly icon: IconName;
}

const MODE_OPTIONS: readonly ModeOption[] = [
  { mode: 'light', label: $localize`:@@theme.mode.light:Light`, icon: 'sun' },
  { mode: 'dark', label: $localize`:@@theme.mode.dark:Dark`, icon: 'moon' },
  { mode: 'auto', label: $localize`:@@theme.mode.system:System`, icon: 'monitor' },
];

@Component({
  selector: 'app-theme-switcher',
  imports: [CdkMenu, CdkMenuItem, CdkMenuTrigger, Icon],
  templateUrl: './theme-switcher.html',
  styleUrl: './theme-switcher.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  // The CDK menu opens in an overlay portal appended to <body>, so it
  // is NOT a descendant of this component's host. With the default
  // emulated encapsulation, the menu DOM would lose the scoping
  // attribute and our `.theme-switcher__*` rules would not apply.
  // Disabling encapsulation emits the styles into the global sheet —
  // the BEM-style class names below are specific enough to avoid
  // collisions, and `.dark` ancestor matching just works.
  encapsulation: ViewEncapsulation.None,
})
export class ThemeSwitcher {
  private readonly layout = inject(LayoutStateService);

  protected readonly options = MODE_OPTIONS;
  protected readonly mode = this.layout.themeMode;
  protected readonly currentIcon = computed<IconName>(
    () => MODE_OPTIONS.find((o) => o.mode === this.mode())?.icon ?? 'monitor',
  );
  protected readonly currentLabel = computed(
    () =>
      MODE_OPTIONS.find((o) => o.mode === this.mode())?.label ??
      $localize`:@@theme.mode.system:System`,
  );
  protected readonly triggerAriaLabel = computed(
    () => $localize`:@@theme.trigger.aria:Theme: ${this.currentLabel()}:mode: (open menu)`,
  );

  protected select(mode: ThemeMode): void {
    this.layout.setThemeMode(mode);
  }
}
