/**
 * Message blocks — typed, serializable rich-content slots.
 *
 * A `ChatMessage` may carry `blocks: MessageBlock[]`. Each block is a
 * discriminated union member keyed by `kind`. Payloads are plain JSON
 * (no Date, no Float32Array, no React nodes) so blocks survive history
 * persistence and SSE transport. See `@docs/message-blocks.md`.
 */

/** Spaciousness hint forwarded from the bubble to renderers. */
export type BlockAppearance = 'compact' | 'full';

interface BlockBase {
  /** Stable id — used as React key and for memo diffing. */
  id: string;
  /** Optional caption rendered above the block. */
  caption?: string;
}

export interface TextBlock extends BlockBase {
  kind: 'text';
  text: string;
}

export interface MarkdownBlock extends BlockBase {
  kind: 'markdown';
  markdown: string;
}

export interface AudioBlock extends BlockBase {
  kind: 'audio';
  src: string;
  title?: string;
  artist?: string;
  cover?: string;
  /** `compact` → AudioPlayer variant. */
  variant?: 'default' | 'compact';
}

export interface VideoBlock extends BlockBase {
  kind: 'video';
  /** Raw URL string — VideoPlayer auto-classifies YouTube/Vimeo/HLS/MP4. */
  src: string;
  poster?: string;
  title?: string;
  aspectRatio?: number | 'auto' | 'fill';
}

export interface ImageBlock extends BlockBase {
  kind: 'image';
  src: string;
  alt?: string;
  /** When true → zoom/pan ImageViewer; else a plain `<img>`. */
  interactive?: boolean;
}

export interface GalleryBlock extends BlockBase {
  kind: 'gallery';
  items: Array<{ id: string; src: string; thumbnail?: string; alt?: string }>;
}

export interface MapBlock extends BlockBase {
  kind: 'map';
  center: { lat: number; lng: number };
  zoom?: number;
  markers?: Array<{ id: string; lat: number; lng: number; label?: string }>;
}

export interface JsonBlock extends BlockBase {
  kind: 'json';
  data: unknown;
  /** JsonTree display mode. */
  mode?: 'full' | 'compact' | 'inline';
}

export interface MermaidBlock extends BlockBase {
  kind: 'mermaid';
  chart: string;
}

export interface CodeBlock extends BlockBase {
  kind: 'code';
  code: string;
  language: string;
}

export interface LottieBlock extends BlockBase {
  kind: 'lottie';
  /** Animation JSON URL or inline animationData object. */
  src: string;
}

/**
 * Escape hatch for host-defined block types. The built-in registry
 * renders it as the unknown-kind fallback unless the host registers a
 * `custom` renderer that switches on `name`.
 */
export interface CustomBlock extends BlockBase {
  kind: 'custom';
  /** Host-defined sub-type, dispatched by the host's own renderer. */
  name: string;
  payload: unknown;
}

export type MessageBlock =
  | TextBlock
  | MarkdownBlock
  | AudioBlock
  | VideoBlock
  | ImageBlock
  | GalleryBlock
  | MapBlock
  | JsonBlock
  | MermaidBlock
  | CodeBlock
  | LottieBlock
  | CustomBlock;

/** The discriminant literal — `'audio' | 'video' | …`. */
export type MessageBlockKind = MessageBlock['kind'];
