import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { NavigationEnd, Router, RouterLink } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
  lucideBookOpen,
  lucideBot,
  lucideChevronRight,
  lucideLayoutDashboard,
  lucideSettings2,
  lucideSquareTerminal,
} from '@ng-icons/lucide';
import { HlmCollapsibleImports } from '@spartan-ng/helm/collapsible';
import { HlmSidebarImports } from '@spartan-ng/helm/sidebar';
import { filter, map } from 'rxjs';
import { NavSubItems } from './nav-sub-items';
import type { NavItem, NavSubItem } from './types';

@Component({
  selector: 'app-nav-main',
  imports: [HlmSidebarImports, NgIcon, HlmCollapsibleImports, RouterLink, NavSubItems],
  providers: [
    // Framework icons stay inline (sidebar chrome). Per-bounded-context icons are
    // appended automatically by the codegen via `registerBcAggregatorInNavMain`
    // — do NOT add `lucide*` icons here for items declared in a `<bc>.navigation.ts`.
    provideIcons({
      lucideSquareTerminal,
      lucideBot,
      lucideBookOpen,
      lucideSettings2,
      lucideChevronRight,
      lucideLayoutDashboard
    }),
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <hlm-sidebar-group>
      <div hlmSidebarGroupLabel>{{ label() }}</div>
      <ul hlmSidebarMenu>
        @for (item of items(); track item.title) {
          @if (item.items; as subItems) {
            <hlm-collapsible
              class="group/collapsible"
              [expanded]="isExpanded(item)"
            >
              <li hlmSidebarMenuItem>
                <button
                  hlmCollapsibleTrigger
                  hlmSidebarMenuButton
                >
                  <ng-icon [name]="item.icon" />
                  {{ item.title }}
                  <ng-icon
                    name="lucideChevronRight"
                    class="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90"
                  />
                </button>
                <hlm-collapsible-content>
                  <ul hlmSidebarMenuSub>
                    <app-nav-sub-items [items]="subItems" />
                  </ul>
                </hlm-collapsible-content>
              </li>
            </hlm-collapsible>
          } @else {
            <li hlmSidebarMenuItem>
              <a
                [routerLink]="item.url"
                hlmSidebarMenuButton
                closeMobileSidebarOnClick
              >
                <ng-icon [name]="item.icon" />
                {{ item.title }}
              </a>
            </li>
          }
        }
      </ul>
    </hlm-sidebar-group>
  `,
})
export class NavMain {
  // injections
  private readonly router = inject(Router);

  // inputs
  readonly label = input.required<string>();
  readonly items = input.required<NavItem[]>();

  // signals
  private readonly url = toSignal(
    this.router.events.pipe(
      filter((e) => e instanceof NavigationEnd),
      map(() => this.router.url),
    ),
    { initialValue: this.router.url },
  );

  isExpanded(item: NavItem): boolean {
    return this.hasActiveChild(item);
  }

  private hasActiveChild(item: NavItem | NavSubItem): boolean {
    if (this.url().startsWith(item.url)) return true;
    return item.items?.some((child) => this.hasActiveChild(child)) ?? false;
  }
}
