import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
import {
  Accessibility,
  Bell,
  Building2,
  Calendar,
  Check,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  CircleHelp,
  FileText,
  Folder,
  Globe,
  Grid2x2,
  House,
  LayoutDashboard,
  LogOut,
  type LucideIconData,
  LucideAngularModule,
  Mail,
  Monitor,
  Moon,
  Search,
  Settings,
  Store,
  Sun,
  User,
  UsersRound,
  Wrench,
} from 'lucide-angular';

/**
 * Icon façade — single point of truth for the icon set across every
 * app in the workspace (`portal-shell` today, `portal-admin` next).
 *
 * v1 is backed by `lucide-angular`. The migration to an in-house
 * icomoon-generated set (sprite SVG) is a single-file change to
 * THIS component — every consumer just writes `<lib-icon name="…">`,
 * so swapping the implementation never touches them.
 *
 * Convention: `name` is the lowercase, kebab-cased "logical" name we
 * will keep across implementations (`home`, `bar-chart`, etc.). The
 * registry below maps each logical name to its lucide-angular icon
 * data. When the icomoon export lands, each name will instead map to
 * a `<symbol id="icon-…">` in the sprite — the template-side
 * contract stays identical.
 */

// Adding an icon to the registry: import the lucide pascal-case name
// above (Tailwind eslint sorts the import block), then add a single
// `'kebab-name': PascalImport,` line below. Both lists are alphabetical
// so contributors don't have to think about placement.
const ICON_REGISTRY = {
  accessibility: Accessibility,
  bell: Bell,
  'building-2': Building2,
  calendar: Calendar,
  check: Check,
  'chevron-down': ChevronDown,
  'chevron-left': ChevronLeft,
  'chevron-right': ChevronRight,
  'circle-help': CircleHelp,
  'file-text': FileText,
  folder: Folder,
  globe: Globe,
  'grid-2x2': Grid2x2,
  home: House,
  'layout-dashboard': LayoutDashboard,
  'log-out': LogOut,
  mail: Mail,
  monitor: Monitor,
  moon: Moon,
  search: Search,
  settings: Settings,
  store: Store,
  sun: Sun,
  user: User,
  'users-round': UsersRound,
  wrench: Wrench,
} satisfies Record<string, LucideIconData>;

export type IconName = keyof typeof ICON_REGISTRY;

@Component({
  selector: 'lib-icon',
  imports: [LucideAngularModule],
  template: `<lucide-angular
    [img]="icon()"
    [size]="size()"
    [strokeWidth]="strokeWidth()"
    aria-hidden="true"
  />`,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class Icon {
  readonly name = input.required<IconName>();
  readonly size = input<number>(20);
  /** Lucide draws with stroke-width 2 by default; 1.5 reads slightly
   *  lighter and matches the visual weight of most icomoon sets. */
  readonly strokeWidth = input<number>(1.5);

  protected readonly icon = computed(() => ICON_REGISTRY[this.name()]);
}
