export interface ToolDefinition {
  name: string;
  description: string;
  parameters: Record<string, unknown>;
}

export interface ToolCall {
  id: string;
  name: string;
  arguments: Record<string, unknown>;
}

export interface ProviderOptions {
  model?: string;
  maxTokens?: number;
  temperature?: number;
  systemPrompt?: string;
  tools?: ToolDefinition[];
  stopSequences?: string[];
}

export interface ProviderResult {
  content: string;
  toolCalls?: ToolCall[];
  usage?: {
    inputTokens: number;
    outputTokens: number;
  };
  stopReason?: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use';
}

export interface StreamChunk {
  type: 'text' | 'tool_use' | 'usage';
  delta?: string;
  toolCall?: ToolCall;
  usage?: { inputTokens: number; outputTokens: number };
}

export type ProviderType = 'claude' | 'openai' | 'gemini';
export type ExecutionMode = 'container' | 'tui' | 'direct';

export interface AIProvider {
  readonly name: string;
  readonly type: ProviderType;
  
  execute(prompt: string, options?: ProviderOptions): Promise<ProviderResult>;
  stream(prompt: string, options?: ProviderOptions): AsyncIterable<StreamChunk>;
  isAvailable(): boolean;
  getModels(): Promise<string[]>;
  getDefaultModel(): string;
}

export interface ProviderConfig {
  apiKey?: string;
  model?: string;
  baseUrl?: string;
  organizationId?: string;
  timeout?: number;
  maxRetries?: number;
}

export class ProviderError extends Error {
  constructor(
    message: string,
    public readonly provider: string,
    public readonly code?: string,
    public readonly statusCode?: number
  ) {
    super(message);
    this.name = 'ProviderError';
  }
}

export class ProviderUnavailableError extends ProviderError {
  constructor(provider: string, reason: string) {
    super(`Provider ${provider} unavailable: ${reason}`, provider, 'UNAVAILABLE');
    this.name = 'ProviderUnavailableError';
  }
}

export class ProviderRateLimitError extends ProviderError {
  constructor(provider: string, retryAfter?: number) {
    super(
      `Provider ${provider} rate limited${retryAfter ? `, retry after ${retryAfter}s` : ''}`,
      provider,
      'RATE_LIMIT',
      429
    );
    this.name = 'ProviderRateLimitError';
  }
}
