/**
 * Core object: a mounted Glim companion (Presence).
 * Source of truth: glim.js — class Glim, Glim.mount, STATES, THEMES, freeTypes.
 * Pack version: 0.1.0-brand
 *
 * Invariants:
 * - Exactly one of PresenceState at a time.
 * - setState with an unknown string is a no-op (returns this).
 * - say(text) always enters 'talking' and holds the line.
 * - freeTypes is a license/marketing list; the published glim.js registers
 *   every body in Glim.types with no runtime entitlement check (open decision).
 * - Valid "empty" result: mounted presence in 'idle' with no caption text held.
 */

/** The four-state mind. Names are public API — do not rename in UI copy. */
export type PresenceState = 'idle' | 'thinking' | 'talking' | 'listening';

/** Named theme presets from glim.js THEMES. */
export type ThemeName = 'signal' | 'aurora' | 'ember' | 'mono' | 'bloom' | 'deep';

/** Per-state mood: hex for CSS, rgb 0..1 for shaders, energy for motion. */
export interface MoodSwatch {
  hex: string;
  rgb: [number, number, number];
  /** Motion energy ~0.3..1.0 depending on state/theme. */
  energy: number;
}

/** Full palette: one MoodSwatch per PresenceState. */
export type MoodPalette = Record<PresenceState, MoodSwatch>;

/**
 * Partial theme override accepted by setTheme / mount opts.
 * Missing states fall back to default MOOD (signal).
 */
export type ThemeInput = ThemeName | Partial<Record<PresenceState, { hex?: string; energy?: number }>>;

/** Creature body ids registered in the build (Glim.types). */
export type CreatureId =
  | 'dots' | 'orb' | 'fog' | 'plasma' | 'liquid' | 'metaball' | 'voronoi'
  | 'swarm' | 'cube' | 'ring' | 'aurora' | 'pet' | 'radar' | 'bars'
  | 'orbit' | 'slime' | 'grid' | 'ink' | 'comet' | 'morph' | 'eye'
  | 'petals' | 'glyph' | 'nebula' | 'mercury' | 'flame' | 'bubble' | 'koi'
  | 'fireflies' | 'jelly' | 'rain' | 'embers' | 'pulse' | 'ribbon' | 'wisp'
  | 'zen' | 'lantern' | 'breath' | 'caret' | 'sprout' | 'cradle' | 'stars'
  | 'compass';

/**
 * MIT free tier creatures (Glim.freeTypes).
 * Commercial use allowed per product copy. Not a runtime whitelist in glim.js.
 */
export type FreeCreatureId =
  | 'dots' | 'orb' | 'ring' | 'bars' | 'grid' | 'caret' | 'pulse' | 'wisp';

export interface MountOptions {
  /** CSS pixel size of the square host stage. Site configurator range: 80–240; default often 160. */
  size?: number;
  theme?: ThemeInput;
  state?: PresenceState;
  /** Initial line; triggers talking via say() path when provided by host helpers. */
  say?: string;
}

/** Events emitted by Presence.on */
export type PresenceEvent = 'state' | 'settle';

export type PresenceEventMap = {
  /** Fired when setState changes (or re-asserts) state. */
  state: PresenceState;
  /** Fired once after a held say() line finishes typing. Payload is the full string. */
  settle: string;
};

/**
 * Public instance returned by Glim.mount.
 * Field names match glim.js — use these in UI, analytics, and docs.
 */
export interface Presence {
  host: HTMLElement;
  /** Active palette (merged theme). */
  palette: MoodPalette;
  state: PresenceState;
  /** Own phase clock in seconds (randomised at construct so walls desync). */
  t: number;
  /** Eased public energy 0..~1.5 (mood energy + react spike). */
  energy: number;
  /** Eased attention 0..~1.5 (proximity + react). */
  hover: number;
  mood: MoodSwatch;
  /** Optional caption element; when set, state lines / say() render here. */
  cap: HTMLElement | null;

  setState(state: PresenceState): this;
  cycle(): this;
  say(text: string): this;
  react(power?: number): this;
  setTheme(theme: ThemeInput): this;
  on<E extends PresenceEvent>(event: E, fn: (data: PresenceEventMap[E], self: Presence) => void): this;
  destroy(): void;
  /** Legacy binary attention. */
  setHover(v: boolean | number): void;
  /** Continuous proximity attention 0..1. */
  setAttention(v: number): void;
}

export interface GlimStatic {
  mount(el: HTMLElement, type: CreatureId | string, opts?: MountOptions): Presence;
  /** Every body id registered in this build. */
  types: string[];
  /** Eight MIT creatures. */
  freeTypes: FreeCreatureId[];
}

declare const Glim: GlimStatic;
export default Glim;
