import { DOCUMENT } from '@angular/common';
import { CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu';
import { ChangeDetectionStrategy, Component, ViewEncapsulation, inject } from '@angular/core';
import { Icon } from 'shared-ui';

/**
 * Locale switcher rendered in the footer.
 *
 * The trigger is a small chip showing the active locale's native
 * name (e.g. "Français" or "English"). Clicking it opens a CDK menu
 * with one entry per supported locale; the currently-active one
 * carries a check mark. Selecting a locale rewrites the current URL
 * to the matching per-locale prefix (`/fr/...`, `/en/...`) and
 * triggers a hard refresh so the right bundle boots.
 *
 * Locale names are NOT i18n-marked — each language's name is always
 * shown in its own language ("Français" / "English"), which is the
 * universal pattern for locale switchers.
 *
 * v1 is SPA-only: the URL prefix carries the locale, and the next
 * visit naturally lands on the same locale's bundle. The
 * `__Host-portal_locale` cookie + smart redirect at `/` envisaged in
 * ADR-0019 land once a small BFF route is in place; until then the
 * `/` URL falls back to `Accept-Language` then `fr`.
 */

type LocaleCode = 'fr' | 'en';

interface Locale {
  readonly code: LocaleCode;
  readonly displayName: string;
}

const LOCALES: readonly Locale[] = [
  { code: 'fr', displayName: 'Français' },
  { code: 'en', displayName: 'English' },
];

const LOCALE_PREFIX_RE = /^\/(en|fr)(?=\/|$)/;

@Component({
  selector: 'app-locale-switcher',
  imports: [CdkMenu, CdkMenuItem, CdkMenuTrigger, Icon],
  templateUrl: './locale-switcher.html',
  styleUrl: './locale-switcher.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  // Same reasoning as ThemeSwitcher: the CDK menu opens in an
  // overlay portal outside this component's host, so encapsulated
  // styles would not reach it. The BEM-style class names below are
  // specific enough to stay contained.
  encapsulation: ViewEncapsulation.None,
})
export class LocaleSwitcher {
  private readonly document = inject(DOCUMENT);

  protected readonly locales = LOCALES;
  protected readonly currentCode: LocaleCode;
  protected readonly currentDisplayName: string;
  protected readonly triggerAriaLabel: string;

  constructor() {
    this.currentCode = this.detectCurrentLocale();
    this.currentDisplayName =
      LOCALES.find((l) => l.code === this.currentCode)?.displayName ?? 'English';
    this.triggerAriaLabel = $localize`:@@locale.trigger.aria:Language: ${this.currentDisplayName}:locale: (change language)`;
  }

  protected select(code: LocaleCode): void {
    if (code === this.currentCode) {
      return;
    }
    const target = this.buildTargetUrl(code);
    this.document.defaultView?.location.assign(target);
  }

  private detectCurrentLocale(): LocaleCode {
    const lang = this.document.documentElement.lang;
    return lang === 'fr' ? 'fr' : 'en';
  }

  private buildTargetUrl(targetCode: LocaleCode): string {
    const win = this.document.defaultView;
    const pathname = win?.location.pathname ?? '/';
    const search = win?.location.search ?? '';
    const hash = win?.location.hash ?? '';
    const stripped = pathname.replace(LOCALE_PREFIX_RE, '') || '/';
    const normalised = stripped.startsWith('/') ? stripped : `/${stripped}`;
    return `/${targetCode}${normalised}${search}${hash}`;
  }
}
