/**
 * Resolving `DemoMeta.icon` — a lucide export NAME — to a component.
 *
 * The obvious implementations are both wrong, and both were tried:
 *
 *   `import * as lucide from 'lucide-react'`  — kills tree-shaking. Every icon
 *   in the library (~1,500) lands in a chunk to render twelve of them.
 *
 *   `import('lucide-react/dynamicIconImports')` — correct at runtime, but the
 *   map holds a dynamic import per icon, so Rollup emits ~1,500 chunk files
 *   into `dist/` for a static site that serves twelve.
 *
 * So the shell keeps an explicit registry. Adding a demo means adding its icon
 * here; that is one line, and in exchange the entry chunk stays honest. An
 * unknown name renders the neutral fallback rather than throwing, because a
 * typo in a demo's metadata must not take the gallery down.
 */
import type { LucideIcon } from 'lucide-react';
import {
  Blocks,
  Boxes,
  Braces,
  Building2,
  ClipboardCheck,
  Code,
  Cpu,
  Database,
  FileSearch,
  Gauge,
  Grid3x3,
  HeartPulse,
  Landmark,
  LifeBuoy,
  MessagesSquare,
  Package,
  PhoneCall,
  Plug,
  Radio,
  Receipt,
  Scale,
  ShieldCheck,
  ShoppingCart,
  Stethoscope,
  Truck,
  Wallet,
  Workflow,
  Zap,
} from 'lucide-react';

const REGISTRY: Record<string, LucideIcon> = {
  Blocks,
  Boxes,
  Braces,
  Building2,
  ClipboardCheck,
  Code,
  Cpu,
  Database,
  FileSearch,
  Gauge,
  Grid3x3,
  HeartPulse,
  Landmark,
  LifeBuoy,
  MessagesSquare,
  Package,
  PhoneCall,
  Plug,
  Radio,
  Receipt,
  Scale,
  ShieldCheck,
  ShoppingCart,
  Stethoscope,
  Truck,
  Wallet,
  Workflow,
  Zap,
};

export const FallbackDemoIcon: LucideIcon = Boxes;

/** Every icon name the shell can render, for `check-demos` to assert against. */
export const KNOWN_ICON_NAMES: readonly string[] = Object.keys(REGISTRY);

export function resolveDemoIcon(name: string | undefined): LucideIcon {
  if (!name) return FallbackDemoIcon;
  return REGISTRY[name] ?? FallbackDemoIcon;
}

export interface DemoIconProps {
  /** A lucide export name from `DemoMeta.icon`, e.g. `Grid3x3`. */
  name: string | undefined;
  className?: string;
  /** Icons here are always decorative — the label beside them carries the name. */
  strokeWidth?: number;
}

export function DemoIcon({ name, className, strokeWidth = 1.75 }: DemoIconProps) {
  const Icon = resolveDemoIcon(name);
  return <Icon className={className} strokeWidth={strokeWidth} aria-hidden="true" />;
}
