/** Image source for multimodal content blocks. */
export interface ImageSource {
  type: 'base64' | 'url';
  /** MIME type (e.g. "image/jpeg", "image/png", "image/webp", "image/gif"). */
  media_type: string;
  /** Base64-encoded image data (when type === 'base64'). */
  data?: string;
  /** Image URL (when type === 'url'). */
  url?: string;
}

/** Audio source for multimodal content blocks. */
export interface AudioSource {
  /** MIME type (e.g. "audio/ogg", "audio/mpeg", "audio/wav", "audio/webm"). */
  media_type: string;
  /** Base64-encoded audio data. */
  data: string;
  /** Optional transcript (from Whisper) — used when the model doesn't support native audio. */
  transcript?: string;
}

/** Individual content part within a multimodal message. */
export type MessageContentPart =
  | { type: 'text'; text: string }
  | { type: 'image'; source: ImageSource }
  | { type: 'audio'; source: AudioSource };

export interface Message {
  role: 'user' | 'assistant';
  /** String for text-only messages, or array for multimodal content. */
  content: string | MessageContentPart[];
  timestamp?: number;
}

// Tool definition passed to model API
export interface ToolDefinition {
  name: string;
  description: string;
  input_schema: {
    type: 'object';
    properties: Record<string, unknown>;
    required?: string[];
  };
}

// Individual tool call returned by model
export interface ModelToolCall {
  id: string;
  name: string;
  args: unknown;
}

// Content blocks for multi-content responses
export type ContentBlock =
  | { type: 'text'; text: string }
  | { type: 'image'; source: ImageSource }
  | { type: 'audio'; source: AudioSource }
  | { type: 'tool_use'; id: string; name: string; input: unknown };

// Tool result fed back into conversation
export interface ToolResultEntry {
  tool_use_id: string;
  content: string;
  is_error?: boolean;
}

// Message type for tool results (distinct from user/assistant)
export interface ToolMessage {
  role: 'tool_result';
  toolResults: ToolResultEntry[];
}

// Union type for all messages in a conversation
export type ConversationMessage = Message | ToolMessage;

export interface ChatRequest {
  messages: Message[];
  system?: string;
  maxTokens?: number;
  tools?: ToolDefinition[];
  /** Enable extended thinking/reasoning mode for this request. */
  thinking?: boolean;
}

export interface ChatResponse {
  content: string;
  stopReason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | string;
  usage: TokenUsage;
  toolCalls?: ModelToolCall[];
  /** Set when the response came from a fallback model, not the primary. */
  fallback?: boolean;
  /** Human-readable reason for the fallback. */
  fallbackReason?: string;
  /** Raw thinking/reasoning output from extended thinking mode. */
  thinkingContent?: string;
}

export interface TokenUsage {
  inputTokens: number;
  outputTokens: number;
}

export interface ChatStreamEvent {
  type: 'content' | 'done' | 'error' | 'tool_use' | 'fallback_warning';
  content?: string;
  usage?: TokenUsage;
  error?: Error;
  toolCall?: ModelToolCall;
  /** Human-readable message when primary model failed and fallback is being used. */
  fallbackReason?: string;
}

export interface StreamingModelClient {
  chatStream(request: ChatRequest): AsyncIterable<ChatStreamEvent>;
}

export interface ModelClient {
  chat(request: ChatRequest): Promise<ChatResponse>;
  chatStream?(request: ChatRequest): AsyncIterable<ChatStreamEvent>;
}
