/**
 * Icon registry — pluggable lookup map for `<icon-ui>` SVG resolution.
 *
 * Three consumer paths, picked by bundle-size budget:
 *
 *   1. **Zero-config** — import the main barrel; phosphor side-effect-loads
 *      via `core/icons-phosphor.js`. Largest bundle (~9 000 chunks under
 *      `vite build`). Best for prototypes.
 *
 *   2. **Opt-in phosphor with piecemeal component imports** — when you
 *      `import '@adia-ai/web-components/components/button'` etc. you skip
 *      the barrel's phosphor side-effect. Add it explicitly:
 *        import '@adia-ai/web-components/core/icons-phosphor';
 *
 *   3. **Scoped registration (smallest bundle)** — install only the icons
 *      you use via `installIconLoaders()` with a brace-list glob, OR
 *      `installIconLoadersForRegistered()` to auto-discover from defined
 *      primitives' `static requiredIcons`.
 *
 * Runtime exports mirror `core/icons.js`. `installIconLoadersForRegistered`
 * shipped in v0.5.3 §154 (FEEDBACK-06 §4 + FEEDBACK-07 §4). `.d.ts`
 * authored in v0.5.4 to close the missing-type-surface gap that blocked
 * TypeScript consumers from importing the helper.
 *
 * @see ../USAGE.md (consumer guide)
 * @see ./icons-phosphor.js (the zero-config side-effect path)
 */

/**
 * Phosphor weight identifiers. `regular` is the default; the other five
 * weights resolve to the corresponding `@phosphor-icons/core/assets/<weight>/`
 * subtree when consumers install loaders for them.
 */
export const ICON_WEIGHTS: ReadonlyArray<'regular' | 'thin' | 'light' | 'bold' | 'fill' | 'duotone'>;

/** A single phosphor weight identifier. */
export type IconWeight = 'regular' | 'thin' | 'light' | 'bold' | 'fill' | 'duotone';

/**
 * Loader value in an icon-loader map. Either the SVG string itself (eager
 * `import.meta.glob({ eager: true })` output) or a thunk that resolves to
 * the SVG string (lazy / dynamic import).
 */
export type IconLoader = string | (() => string | Promise<string>);

/**
 * Per-path loader map for a single weight. Keys are typically the
 * `/node_modules/@phosphor-icons/core/assets/<weight>/<filename>.svg` paths
 * `import.meta.glob` produces — but any keys work (§140's filename-suffix
 * fallback handles pnpm / yarn-berry / custom-Vite-root prefixes).
 */
export type IconLoaderMap = Record<string, IconLoader>;

/**
 * Per-weight loader maps. Pass to `installIconLoaders()` /
 * `installIconLoadersForRegistered()`. Most consumers pass only `regular`;
 * weight-overloaded usage (e.g. `<icon-ui name="star" weight="fill">`)
 * needs the corresponding weight populated.
 */
export interface WeightModules {
  regular?: IconLoaderMap;
  thin?: IconLoaderMap;
  light?: IconLoaderMap;
  bold?: IconLoaderMap;
  fill?: IconLoaderMap;
  duotone?: IconLoaderMap;
}

/** Register a single icon by name. Bypasses loader-map lookup entirely. */
export function registerIcon(name: string, svg: string, weight?: IconWeight): void;

/** Register multiple icons at a single weight. Bypasses loader-map lookup. */
export function registerIcons(icons: Record<string, string>, weight?: IconWeight): void;

/**
 * Get icon SVG by name + weight. Returns the cached SVG if present;
 * otherwise triggers an async load (returning `''` immediately) + the
 * registered `<icon-ui>` elements re-render once the load resolves.
 */
export function getIcon(name: string, weight?: IconWeight): string;

/** Sync check — is `name` cached in the registry at this weight? */
export function hasIcon(name: string, weight?: IconWeight): boolean;

/** List all cached `weight:name` keys in the registry. */
export function listIcons(): string[];

/**
 * Sync check — is `name` (or its `ICON_ALIASES` alias) a known icon at
 * the given weight? Doesn't trigger loading. Used by primitives that
 * accept either an icon name or a text label (`<input-ui prefix>`,
 * `<input-ui suffix>`) to disambiguate.
 */
export function isIconName(name: string, weight?: IconWeight): boolean;

/**
 * Resolves once the icon registry is sync-checkable — i.e., after the
 * first `installIconLoaders()` call. Primitives that branch on
 * `isIconName` at connect time should await this to avoid the static-
 * deploy race (the registry starts empty, fills async via manifest fetch).
 */
export const whenIconRegistryReady: Promise<void>;

/**
 * Install a per-weight loader map. Idempotent — subsequent calls replace
 * the previous map. After install, re-stamps any existing
 * `<icon-ui[name]>` elements so they re-render with the newly-loadable
 * SVGs.
 *
 * @param modules per-weight maps; missing weights stay empty.
 */
export function installIconLoaders(modules: WeightModules): void;

/**
 * Auto-discover the icon set from defined primitives' `static
 * requiredIcons` declarations, then install loaders.
 *
 * Each AdiaUI primitive that auto-stamps icons declares them via:
 *
 *     export class UISelect extends UIFormElement {
 *       static requiredIcons = ['caret-up-down'];
 *       // ...
 *     }
 *
 * This helper aggregates the union across all currently-defined
 * primitives (post-side-effect imports) and installs `modules` as the
 * loader source. The returned list is the discovered set — useful for
 * trimming a wide glob to only what's needed.
 *
 * Shipped v0.5.3 §154 (FEEDBACK-06 §4 + FEEDBACK-07 §4).
 *
 * @param modules - per-weight loader maps (typically `import.meta.glob`
 *                  output for `@phosphor-icons/core/assets/<weight>/*.svg`)
 * @returns the union of `static requiredIcons` across all defined primitives
 */
export function installIconLoadersForRegistered(
  modules: IconLoaderMap | WeightModules
): string[];

export namespace installIconLoadersForRegistered {
  /**
   * Same-shape companion to `installIconLoadersForRegistered` but
   * doesn't install. Returns the union of `static requiredIcons` across
   * all currently-defined primitives — useful when you want to build a
   * narrower glob from the discovered list.
   */
  function discover(): string[];
}
