/** Per-model capability metadata used by the routing engine */
export interface ModelCapability {
  id: string;
  provider: string;
  displayName: string;
  tier: 'cheap' | 'standard' | 'premium' | 'local';
  contextWindow: number;
  maxOutputTokens: number;
  capabilities: {
    tools: boolean;
    vision: boolean;
    streaming: boolean;
    reasoning: boolean;
    embedding: boolean;
  };
  costPer1kInput?: number;
  costPer1kOutput?: number;
}

/** Known built-in LLM provider identifiers */
export type KnownProvider =
  | 'anthropic'
  | 'openai'
  | 'google'
  | 'ollama'
  | 'xai'
  | 'groq'
  | 'openrouter'
  | 'zai'
  | 'mistral';

/** Provider identifier — known providers or custom string */
export type ProviderId = KnownProvider | string;

/** Describes an available LLM model */
export interface ModelInfo {
  id: string;
  provider: ProviderId;
  name: string;
  reasoning: boolean;
  contextWindow: number;
  maxTokens: number;
  inputTypes: ('text' | 'image')[];
  cost: {
    input: number;
    output: number;
    cacheRead: number;
    cacheWrite: number;
  };
}

/** Describes an available provider */
export interface ProviderInfo {
  id: ProviderId;
  name: string;
  available: boolean;
  models: ModelInfo[];
}

/** Configuration for a custom (non-built-in) provider */
export interface CustomProviderConfig {
  id: string;
  name: string;
  baseUrl: string;
  apiKey?: string;
  models: Array<{
    id: string;
    name: string;
    reasoning?: boolean;
    contextWindow?: number;
    maxTokens?: number;
  }>;
}

// ---------------------------------------------------------------------------
// IProviderAdapter pattern — M3-001
// ---------------------------------------------------------------------------

/** Health status of a provider */
export type ProviderHealthStatus = 'healthy' | 'degraded' | 'down';

/** Result of a provider health check */
export interface ProviderHealth {
  status: ProviderHealthStatus;
  /** Round-trip latency in milliseconds (undefined when provider is down) */
  latencyMs?: number;
  /** ISO-8601 timestamp of the check */
  lastChecked: string;
  /** Human-readable error message (defined when status is not healthy) */
  error?: string;
}

/** A single message in a completion request */
export interface CompletionMessage {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

/** Tool definition for completion requests */
export interface CompletionTool {
  name: string;
  description: string;
  parameters: Record<string, unknown>;
}

/** Parameters for a completion request */
export interface CompletionParams {
  model: string;
  messages: CompletionMessage[];
  tools?: CompletionTool[];
  temperature?: number;
  maxTokens?: number;
  stream?: boolean;
}

/** Usage statistics for a completion event */
export interface CompletionUsage {
  inputTokens: number;
  outputTokens: number;
}

/** A streamed completion event */
export type CompletionEvent =
  | { type: 'text_delta'; content: string }
  | { type: 'tool_call'; name: string; arguments: string }
  | { type: 'done'; usage?: CompletionUsage };

/**
 * Pluggable provider adapter interface.
 *
 * Each LLM provider (Anthropic, OpenAI, Ollama, etc.) implements this interface
 * to integrate with Mosaic's provider layer. The ProviderService aggregates all
 * registered adapters and routes requests accordingly.
 *
 * Note on createCompletion: this method is part of the interface for future
 * direct-completion use cases. The current Pi SDK integration routes completions
 * through the Pi session/ModelRegistry layer rather than calling adapters directly.
 * Adapters MUST still implement register() and healthCheck() correctly — those are
 * used by ProviderService today.
 */
export interface IProviderAdapter {
  /** Unique provider identifier (e.g. 'anthropic', 'openai', 'ollama') */
  readonly name: string;

  /**
   * Initialize the provider — connect, discover models, register with the
   * Pi ModelRegistry. Called once at module startup by ProviderService.registerAll().
   */
  register(): Promise<void>;

  /**
   * Return the list of models this adapter makes available.
   * Returns an empty array when the provider is not configured.
   */
  listModels(): ModelInfo[];

  /**
   * Check whether the provider endpoint is reachable and responsive.
   */
  healthCheck(): Promise<ProviderHealth>;

  /**
   * Stream a completion from the provider.
   *
   * Note: Currently reserved for future use. The Pi SDK integration routes
   * completions through ModelRegistry / AgentSession rather than this method.
   * Implementations may throw NotImplementedError until M3+ tasks wire this up.
   */
  createCompletion(params: CompletionParams): AsyncIterable<CompletionEvent>;
}
