'use client';

/**
 * Block registry — maps a `MessageBlock['kind']` to a renderer.
 *
 * Mirrors `AttachmentRendererMap`, but keyed by a discriminant instead of
 * a predicate: cheaper, exhaustively typed, host-extensible. The built-in
 * registry (`BUILTIN_BLOCK_REGISTRY`) lives in `./builtin` so this module
 * stays free of any tool import.
 */

import type { ReactNode } from 'react';

import type { MessageBlock, MessageBlockKind, BlockAppearance } from '../../types/block';
import { BUILTIN_BLOCK_REGISTRY } from './builtin';

/** Context passed to every renderer alongside the block. */
export interface BlockRenderContext {
  appearance: BlockAppearance;
  isUser: boolean;
}

/** A renderer for one `kind`. The union is narrowed by the registry key. */
export type BlockRenderer<K extends MessageBlockKind = MessageBlockKind> = (
  block: Extract<MessageBlock, { kind: K }>,
  ctx: BlockRenderContext,
) => ReactNode;

/** Partial map of `kind` → renderer. Missing kinds fall back to unknown. */
export type BlockRegistry = {
  [K in MessageBlockKind]?: BlockRenderer<K>;
};

/**
 * Merge host overrides over the built-in registry. Overrides win by key —
 * `{ map: myMapRenderer }` swaps only the map renderer.
 */
export function createBlockRegistry(overrides?: BlockRegistry): BlockRegistry {
  return { ...BUILTIN_BLOCK_REGISTRY, ...overrides };
}

export { BUILTIN_BLOCK_REGISTRY };
