import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
import { RouterLink } from '@angular/router';
import { AuthService, type CurrentUser } from 'feature-auth';
import { Icon, UserMenu, type UserMenuItem } from 'shared-ui';
import { LayoutStateService } from 'shared-state';
import { environment } from '../../../environments/environment';
import { CapabilitiesService } from '../../services/capabilities.service';
import { ThemeSwitcher } from '../theme-switcher/theme-switcher';

/**
 * Top-of-page banner.
 *
 * v1 layout (left → right):
 *   - Logo zone — sized to the sidebar rail so the brand sits flush
 *     above the navigation column. When the sidebar collapses, the
 *     logo zone shrinks too and the wordmark hides, leaving just the
 *     glyph centered above the icon-only rail. Driven by
 *     `LayoutStateService`.
 *   - Global search input (placeholder; wired to a real search service
 *     once we have content to query).
 *   - Action cluster: notifications, help, settings, and a user
 *     widget. The widget renders one of three states — loading,
 *     anonymous (a "Sign in" button), authenticated (avatar with
 *     initials + display name + "Sign out" button) — driven by
 *     `AuthService` (ADR-0009).
 *
 * Lives at app level (not in libs/shared/ui/) on purpose: one consumer
 * for now. Promotion when a second app needs it.
 */
@Component({
  selector: 'app-header',
  imports: [RouterLink, Icon, ThemeSwitcher, UserMenu],
  templateUrl: './header.html',
  styleUrl: './header.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class Header {
  private readonly layout = inject(LayoutStateService);
  private readonly auth = inject(AuthService);
  private readonly capabilities = inject(CapabilitiesService);

  protected readonly collapsed = this.layout.sidebarCollapsed;

  protected readonly authState = this.auth.state;

  protected readonly initials = computed(() => {
    const user = this.auth.currentUser();
    return user ? initialsFor(user) : '';
  });

  // Menu rows are recomputed when capabilities flip so the "Open
  // Portal Admin" entry appears as soon as the BFF confirms admin
  // access for the current session. Sign out is NOT in this list —
  // it's the dedicated row at the bottom of the panel, emitted via
  // the menu's `signOut` output.
  protected readonly userMenuItems = computed<readonly UserMenuItem[]>(() => {
    const items: UserMenuItem[] = [
      {
        label: $localize`:@@header.userMenu.profile:Profile`,
        icon: 'user',
        routerLink: '/profile',
      },
      {
        label: $localize`:@@header.userMenu.settings:Settings`,
        icon: 'settings',
        disabled: true,
        badge: $localize`:@@common.badge.soon:Soon`,
      },
    ];
    if (this.capabilities.canAccessAdmin()) {
      items.push({
        label: $localize`:@@header.userMenu.openAdmin:Open Portal Admin`,
        icon: 'wrench',
        href: environment.adminAppUrl,
      });
    }
    return items;
  });

  protected readonly signedInAsLabel = $localize`:@@header.userMenu.signedInAs:Signed in as`;
  protected readonly signOutLabel = $localize`:@@header.userMenu.signOut:Sign out`;

  protected triggerAriaLabel(displayName: string): string {
    return $localize`:@@header.userMenu.trigger.aria:User menu — signed in as ${displayName}:displayName:`;
  }

  protected signIn(): void {
    this.auth.login();
  }

  protected signOut(): void {
    this.auth.logout();
  }
}

function initialsFor(user: CurrentUser): string {
  const name = (user.displayName || user.username).trim();
  if (!name) {
    return '?';
  }
  const parts = name.split(/\s+/).filter(Boolean).slice(0, 2);
  const letters = parts.map((p) => p.charAt(0).toUpperCase()).join('');
  // Fallback to first two chars of the trimmed string when the
  // split produced an empty array (single-word names with no
  // whitespace already covered by parts[0]).
  return letters || name.slice(0, 2).toUpperCase();
}
