// Type declarations for cast-avatar.
// The source is dependency-free ES module JavaScript (src/avatar.js); these
// declarations describe its public API for TypeScript consumers.

/** Avatar style. `'face'` is a legacy alias for `'cartoon'`. */
export type AvatarStyle =
  | 'portrait'
  | 'studio'
  | 'cartoon'
  | 'minimal'
  | 'line'
  | 'pixel'
  | 'initials'
  | 'bot'
  | 'shapes'
  | 'mesh'
  | 'face';

/** Built-in background keywords (any CSS color is also accepted). */
export type BackgroundKeyword = 'auto' | 'transparent' | 'gradient' | 'dots' | 'rings' | 'grid';

/**
 * Override any of the default color sets to theme avatars (e.g. to a brand
 * palette). Tone maps (`skinTones`/`hairColors`) merge over the defaults;
 * color lists replace the defaults when provided.
 */
export interface AvatarPalette {
  skinTones?: Record<string, string>;
  hairColors?: Record<string, string>;
  backgrounds?: string[];
  shapeColors?: string[];
  clothingColors?: string[];
  inks?: string[];
}

/** Names of the built-in palette presets resolvable by string. */
export type PalettePreset = 'accessible' | 'colorblind-safe';

/** Presence state shown by the status badge. */
export type Status = 'online' | 'busy' | 'away' | 'offline';

/**
 * A shorthand that presets the expressive traits (eyes, mouth, eyebrows) while
 * leaving identity traits seed-derived. Explicit `traits` still take precedence.
 * Applies to the face styles. Great for reflecting agent/user state.
 */
export type Expression = 'neutral' | 'happy' | 'sad' | 'surprised' | 'thinking' | 'wink';

/**
 * A subtle, deterministic CSS animation. Respects `prefers-reduced-motion`.
 * `breathe` gently scales; `bounce` bobs; `blink` briefly closes the eyes
 * (face styles only).
 */
export type Animate = 'breathe' | 'bounce' | 'blink';

/** Corner placement for a `dot` status badge. */
export type StatusPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';

/** Full status badge configuration. */
export interface StatusBadge {
  state: Status;
  /** `dot` = corner badge (default); `ring` = colored border around the avatar. */
  shape?: 'dot' | 'ring';
  /** Corner for the `dot` shape; ignored for `ring`. Defaults to `bottom-right`. */
  position?: StatusPosition;
  /** Animate the badge with a pulse. */
  pulse?: boolean;
  /**
   * Draw a colorblind-safe shape glyph on the `dot` so the state is
   * distinguishable without relying on color alone. Defaults to `false`.
   */
  icon?: boolean;
}
export type Gender = 'neutral' | 'feminine' | 'masculine';
export type SkinTone = 'light' | 'mediumLight' | 'medium' | 'mediumDark' | 'dark';
export type FaceShape = 'round' | 'oval' | 'soft';
export type HairStyle =
  | 'none'
  | 'stubble'
  | 'short'
  | 'long'
  | 'curly'
  | 'coily'
  | 'bun'
  | 'afro'
  | 'mohawk'
  | 'spiky'
  | 'hijab';
export type HairColor = 'black' | 'brown' | 'blonde' | 'red' | 'gray' | 'white';
export type Eyes = 'round' | 'smile' | 'sleepy' | 'wink';
export type Mouth = 'smile' | 'neutral' | 'open';
export type FacialHair =
  | 'none'
  | 'stubble'
  | 'mustache'
  | 'goatee'
  | 'beard'
  | 'fullBeard'
  | 'sideburns';
export type Headwear = 'none' | 'beanie' | 'cap' | 'turban' | 'bucket' | 'hijab';
export type Accessories = 'none' | 'glasses' | 'sunglasses';
export type Eyebrows = 'flat' | 'raised' | 'angled';
export type Nose = 'soft' | 'button' | 'wide';
export type Freckles = 'none' | 'light' | 'heavy';
export type Blush = 'none' | 'soft';
export type Earrings = 'none' | 'studs' | 'hoops';

/** Any trait may be set to `'auto'` to let the seed decide. */
export type Auto<T> = T | 'auto';

/** Trait inputs. Omitted or `'auto'` traits are derived deterministically from the seed. */
export interface AvatarTraits {
  gender?: Auto<Gender>;
  skinTone?: Auto<SkinTone>;
  faceShape?: Auto<FaceShape>;
  hairStyle?: Auto<HairStyle>;
  hairColor?: Auto<HairColor>;
  eyebrows?: Auto<Eyebrows>;
  eyes?: Auto<Eyes>;
  nose?: Auto<Nose>;
  mouth?: Auto<Mouth>;
  facialHair?: Auto<FacialHair>;
  freckles?: Auto<Freckles>;
  blush?: Auto<Blush>;
  headwear?: Auto<Headwear>;
  earrings?: Auto<Earrings>;
  accessories?: Auto<Accessories>;
  /** Clothing color — the one free-color trait. A CSS color or `'auto'`. */
  clothing?: 'auto' | (string & {});
}

/** Fully resolved traits, as produced by {@link resolveAvatarOptions}. */
export interface ResolvedAvatarTraits {
  gender: Gender;
  skinTone: SkinTone;
  faceShape: FaceShape;
  hairStyle: HairStyle;
  hairColor: HairColor;
  eyebrows: Eyebrows;
  eyes: Eyes;
  nose: Nose;
  mouth: Mouth;
  facialHair: FacialHair;
  freckles: Freckles;
  blush: Blush;
  headwear: Headwear;
  earrings: Earrings;
  accessories: Accessories;
  clothing: string;
}

export interface AvatarOptions {
  /** Stable identity input. `name` and `id` are accepted as aliases. */
  seed?: string | number;
  name?: string | number;
  id?: string | number;
  style?: Auto<AvatarStyle>;
  /** Preset the expressive traits (eyes/mouth/eyebrows) to reflect a mood/state. */
  expression?: Expression;
  /** Rendered pixel size, clamped to 24–1024. Defaults to 128. */
  size?: number;
  traits?: AvatarTraits;
  /**
   * Background fill. A CSS color, `'transparent'`, a seeded `'gradient'`, a
   * seeded pattern (`'dots'`, `'rings'`, `'grid'`), or `'auto'` / omitted to
   * pick a color from the palette.
   */
  background?: BackgroundKeyword | (string & {});
  /** @deprecated Use `traits.clothing`. Top-level `clothing` is still accepted. */
  clothing?: 'auto' | (string & {});
  /** Presence badge. A state string (corner dot) or a full config object. Omitted = no badge. */
  status?: Status | StatusBadge;
  /** A subtle looping animation (`breathe` | `bounce`). Respects reduced-motion. */
  animate?: Animate;
  /**
   * Override the default color sets (skin tones, hair, backgrounds, etc.), or
   * name a built-in preset (`'accessible'` / `'colorblind-safe'`).
   */
  palette?: AvatarPalette | PalettePreset;
  /** Monogram font weight for the `initials` style (default `800`). */
  fontWeight?: number | string;
  /** Monogram font family for the `initials` style. */
  fontFamily?: string;
  /** Corner radius for the frame; number (px) or CSS length. Defaults to `'50%'`. */
  radius?: number | string;
  /** Accessible title / aria-label and native `<title>` tooltip. Defaults to `` `${seed} avatar` ``. */
  title?: string;
  /**
   * Hide the avatar from assistive technology (`aria-hidden`, no role/label/title)
   * instead of exposing it as a labelled image. Use when adjacent text already
   * names the person. Defaults to `false`.
   */
  decorative?: boolean;
  /** Explicit initials for the `initials` style. */
  initials?: string;
  /** Legacy alias for `traits.hairStyle`. */
  hair?: Auto<HairStyle>;
}

/** A resolved, serializable avatar configuration. */
export interface ResolvedAvatarConfig {
  version: 1;
  seed: string;
  style: AvatarStyle;
  size: number;
  traits: ResolvedAvatarTraits;
  background: string;
  radius: number | string;
  title: string;
  initials?: string;
  fontWeight?: number | string;
  fontFamily?: string;
  status?: Status | StatusBadge;
  animate?: Animate;
  palette?: AvatarPalette | PalettePreset;
  decorative?: boolean;
}

/** The full set of allowed values for each option, keyed by trait name. */
export interface AvatarOptionSets {
  style: AvatarStyle[];
  gender: Gender[];
  skinTone: SkinTone[];
  faceShape: FaceShape[];
  hairStyle: HairStyle[];
  hairColor: HairColor[];
  eyebrows: Eyebrows[];
  eyes: Eyes[];
  nose: Nose[];
  mouth: Mouth[];
  facialHair: FacialHair[];
  freckles: Freckles[];
  blush: Blush[];
  headwear: Headwear[];
  earrings: Earrings[];
  accessories: Accessories[];
}

/** First argument of the public helpers: a bare seed or an options object. */
export type SeedOrOptions = string | number | AvatarOptions;

/** Resolve a seed/options pair into a complete, deterministic configuration. */
export function resolveAvatarOptions(
  seedOrOptions?: SeedOrOptions,
  maybeOptions?: AvatarOptions
): ResolvedAvatarConfig;

/** Short, stable hash of the resolved configuration (base-36). */
export function avatarHash(seedOrOptions?: SeedOrOptions, maybeOptions?: AvatarOptions): string;

/** Encode an avatar to a portable, hash-checked string (`ca1.<hash>.<payload>`). */
export function encodeAvatar(seedOrOptions?: SeedOrOptions, maybeOptions?: AvatarOptions): string;

/**
 * Decode a string produced by {@link encodeAvatar}.
 * @throws if the string is malformed or the embedded hash does not match.
 */
export function decodeAvatar(encoded: string): ResolvedAvatarConfig;

/** Render an avatar to an SVG string. Accepts a seed, options, or a resolved config. */
export function createAvatar(
  seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
  maybeOptions?: AvatarOptions
): string;

/** Render many avatars at once. Each item is a seed or options object; `sharedOptions` is merged under each. */
export function createAvatars(
  items: Array<SeedOrOptions>,
  sharedOptions?: AvatarOptions
): string[];

/** Options for {@link createAvatarSprite}: grid layout plus shared avatar options. */
export interface SpriteOptions extends AvatarOptions {
  /** Avatars per row (default 8). */
  columns?: number;
  /** Pixel size of each avatar cell (default 64). */
  cell?: number;
  /** Gap in px between cells (default 8). */
  gap?: number;
}

/** Render a roster of avatars into a single SVG sprite-sheet grid. */
export function createAvatarSprite(
  items: Array<SeedOrOptions>,
  options?: SpriteOptions
): string;

/**
 * Combine seeds into a single deterministic, order-independent seed — for a
 * stable "pair"/relationship avatar. `mergeSeeds('a','b') === mergeSeeds('b','a')`.
 */
export function mergeSeeds(
  ...seeds: Array<string | number | ReadonlyArray<string | number>>
): string;

/** Options for {@link createAvatarGroup}: shared avatar options plus the tile cap. */
export interface GroupOptions extends AvatarOptions {
  /** Max member tiles (2–4, default 4); extra members collapse into a "+N" chip. */
  max?: number;
}

/** A group member: a plain seed, or an object with per-member option overrides. */
export type GroupMember = string | number | (AvatarOptions & { seed: string | number });

/** Render several members into one cohesive group mark (a clipped mosaic). */
export function createAvatarGroup(
  seeds: Array<GroupMember>,
  options?: GroupOptions
): string;

/** Wrap an SVG string in a `data:image/svg+xml` URI. */
export function toDataUri(svg: string): string;

/** Render an avatar directly to a `data:image/svg+xml` URI. */
export function createAvatarDataUri(
  seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
  maybeOptions?: AvatarOptions
): string;

/**
 * Render an avatar to a detached `SVGElement`.
 * Requires a DOM environment; throws otherwise.
 */
export function createAvatarElement(
  seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
  maybeOptions?: AvatarOptions
): SVGElement | null;

/**
 * Render an avatar and mount it into `target` (a selector or element).
 * Requires a DOM environment; throws otherwise. Returns the SVG string.
 */
export function mountAvatar(
  target: string | Element,
  seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
  maybeOptions?: AvatarOptions
): string;

/** The allowed values for every trait (re-export of the internal option table). */
export const avatarOptions: AvatarOptionSets;

/** Resolve a palette override (object or preset name) into a full color set. */
export function resolvePalette(override?: AvatarPalette | PalettePreset): Required<AvatarPalette>;

/** A colorblind-safe palette preset (Okabe–Ito based). */
export const COLORBLIND_SAFE_PALETTE: AvatarPalette;

/** Built-in palette presets, keyed by preset name. */
export const PALETTE_PRESETS: Record<PalettePreset, AvatarPalette>;
