import OpenAI from 'openai';
import { ProviderOptions, BaseAIProvider, Context, ModelResponse, StreamingResponseChunk, UniversalMessage } from '@robota-sdk/core';
import { FunctionSchema } from '@robota-sdk/tools';

/**
 * OpenAI provider options
 */
interface OpenAIProviderOptions extends ProviderOptions {
    /**
     * Model name to use (default: gpt-3.5-turbo)
     */
    model: string;
    /**
     * Temperature (0~1)
     */
    temperature?: number;
    /**
     * Maximum number of tokens
     */
    maxTokens?: number;
    /**
     * OpenAI API key (optional: not required when using client)
     */
    apiKey?: string;
    /**
     * OpenAI organization ID (optional)
     */
    organization?: string;
    /**
     * API request timeout (milliseconds)
     */
    timeout?: number;
    /**
     * API base URL (default: 'https://api.openai.com/v1')
     */
    baseURL?: string;
    /**
     * Response format (default: 'text')
     * - 'text': Plain text response
     * - 'json_object': Legacy JSON mode (requires system message)
     * - 'json_schema': Structured Outputs with schema validation
     */
    responseFormat?: 'text' | 'json_object' | 'json_schema';
    /**
     * JSON schema for structured outputs (required when responseFormat is 'json_schema')
     */
    jsonSchema?: {
        name: string;
        description?: string;
        schema?: Record<string, unknown>;
        strict?: boolean;
    };
    /**
     * OpenAI client instance (required)
     */
    client: OpenAI;
    /**
     * Enable API payload logging to files
     * When enabled, saves API request payloads to log files
     *
     * @defaultValue false
     */
    enablePayloadLogging?: boolean;
    /**
     * Directory path for storing API payload log files
     *
     * @defaultValue './logs/api-payloads'
     */
    payloadLogDir?: string;
    /**
     * Include timestamp in payload log filenames
     *
     * @defaultValue true
     */
    includeTimestampInLogFiles?: boolean;
}

/**
 * OpenAI AI provider implementation for Robota
 *
 * Provides integration with OpenAI's GPT models and other services.
 * Extends BaseAIProvider for common functionality and tool calling support.
 *
 * @see {@link ../../../apps/examples/03-integrations | Provider Integration Examples}
 *
 * @public
 */
declare class OpenAIProvider extends BaseAIProvider {
    /**
     * Provider identifier name
     * @readonly
     */
    readonly name: string;
    /**
     * OpenAI client instance
     * @internal
     */
    private readonly client;
    /**
     * Client type identifier
     * @readonly
     */
    readonly type: string;
    /**
     * OpenAI client instance (alias for backwards compatibility)
     * @readonly
     * @deprecated Use the private client property instead
     */
    readonly instance: OpenAI;
    /**
     * Provider configuration options
     * @readonly
     */
    readonly options: OpenAIProviderOptions;
    /**
     * Payload logger for API request logging
     * @internal
     */
    private readonly payloadLogger;
    /**
     * Create a new OpenAI provider instance
     *
     * @param options - Configuration options for the OpenAI provider
     *
     * @throws {Error} When client is not provided in options
     */
    constructor(options: OpenAIProviderOptions);
    /**
     * Convert function definitions to OpenAI tool format
     *
     * Transforms universal function definitions into OpenAI's specific tool format
     * required by the Chat Completions API.
     *
     * @param functions - Array of universal function definitions
     * @returns Array of OpenAI-formatted tools
     */
    formatFunctions(functions: FunctionSchema[]): OpenAI.Chat.ChatCompletionTool[];
    /**
     * Filter conversation history for OpenAI API compatibility
     *
     * Converts messages to OpenAI format and filters out invalid tool messages.
     *
     * @param messages - Array of messages to filter
     * @returns OpenAI-formatted messages array
     */
    private filterHistory;
    /**
     * Configure tools for OpenAI API request
     *
     * Transforms function schemas into OpenAI tool format and sets tool_choice.
     *
     * @param tools - Array of function schemas
     * @returns OpenAI tool configuration object
     */
    protected configureTools(tools?: FunctionSchema[]): {
        tools: OpenAI.Chat.ChatCompletionTool[];
        tool_choice: 'auto';
    } | undefined;
    /**
     * Send a chat request to OpenAI and receive a complete response
     *
     * Processes the provided context and sends it to OpenAI's Chat Completions API.
     * Handles message format conversion, error handling, and response parsing.
     *
     * @param model - Model name to use (e.g., 'gpt-4', 'gpt-3.5-turbo')
     * @param context - Context object containing messages and system prompt
     * @param options - Optional generation parameters and tools
     * @returns Promise resolving to the model's response
     *
     * @throws {Error} When context is invalid
     * @throws {Error} When messages array is invalid
     * @throws {Error} When message format conversion fails
     * @throws {Error} When OpenAI API call fails
     */
    chat(model: string, context: Context, options?: any): Promise<ModelResponse>;
    /**
     * Convert OpenAI API response to universal ModelResponse format
     *
     * Transforms the OpenAI-specific response format into the standard format
     * used across all providers in Robota.
     *
     * @param response - Raw response from OpenAI Chat Completions API
     * @returns Parsed model response in universal format
     *
     * @internal
     */
    parseResponse(response: OpenAI.Chat.ChatCompletion): ModelResponse;
    /**
     * Convert OpenAI streaming response chunk to universal format
     *
     * Transforms individual chunks from OpenAI's streaming response into the
     * standard StreamingResponseChunk format used across all providers.
     *
     * @param chunk - Raw chunk from OpenAI streaming API
     * @returns Parsed streaming response chunk
     *
     * @internal
     */
    parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): StreamingResponseChunk;
    /**
     * Send a streaming chat request to OpenAI and receive response chunks
     *
     * Similar to chat() but returns an async iterator that yields response chunks
     * as they arrive from OpenAI's streaming API. Useful for real-time display
     * of responses or handling large responses incrementally.
     *
     * @param model - Model name to use
     * @param context - Context object containing messages and system prompt
     * @param options - Optional generation parameters and tools
     * @returns Async generator yielding response chunks
     *
     * @throws {Error} When context is invalid
     * @throws {Error} When messages array is invalid
     * @throws {Error} When message format conversion fails
     * @throws {Error} When OpenAI streaming API call fails
     *
     * @see {@link ../../../apps/examples/01-basic | Basic Usage Examples}
     */
    chatStream(model: string, context: Context, options?: any): AsyncGenerator<StreamingResponseChunk, void, unknown>;
    /**
     * Release resources and close connections
     *
     * Performs cleanup operations when the provider is no longer needed.
     * OpenAI client doesn't require explicit cleanup, so this is a no-op.
     *
     * @returns Promise that resolves when cleanup is complete
     */
    close(): Promise<void>;
}

/**
 * OpenAI ConversationHistory adapter
 *
 * Converts UniversalMessage to OpenAI Chat Completions API format
 */
declare class OpenAIConversationAdapter {
    /**
     * Filter messages for OpenAI compatibility
     *
     * OpenAI has specific requirements:
     * - Tool messages must have valid toolCallId
     * - Messages must be in proper sequence
     * - Tool messages without toolCallId should be excluded
     */
    static filterMessagesForOpenAI(messages: UniversalMessage[]): UniversalMessage[];
    /**
     * Convert UniversalMessage array to OpenAI message format
     * Now properly handles tool messages for OpenAI's tool calling feature
     */
    static toOpenAIFormat(messages: UniversalMessage[]): OpenAI.Chat.ChatCompletionMessageParam[];
    /**
     * Convert a single UniversalMessage to OpenAI format
     * Handles all message types including tool messages
     */
    static convertMessage(msg: UniversalMessage): OpenAI.Chat.ChatCompletionMessageParam;
    /**
     * Add system prompt to message array if needed
     */
    static addSystemPromptIfNeeded(messages: OpenAI.Chat.ChatCompletionMessageParam[], systemPrompt?: string): OpenAI.Chat.ChatCompletionMessageParam[];
}

/**
 * Utility class for logging OpenAI API payloads to files
 */
declare class PayloadLogger {
    private readonly enabled;
    private readonly logDir;
    private readonly includeTimestamp;
    constructor(enabled?: boolean, logDir?: string, includeTimestamp?: boolean);
    /**
     * Log API payload to file
     * @param payload - The API request payload
     * @param type - Type of request ('chat' or 'stream')
     */
    logPayload(payload: any, type?: 'chat' | 'stream'): Promise<void>;
    /**
     * Ensure log directory exists
     */
    private ensureLogDirectoryExists;
    /**
     * Sanitize payload to remove sensitive information
     * @param payload - Raw payload object
     * @returns Sanitized payload
     */
    private sanitizePayload;
    /**
     * Check if logging is enabled
     */
    isEnabled(): boolean;
}

export { OpenAIConversationAdapter, OpenAIProvider, type OpenAIProviderOptions, PayloadLogger };
