/**
 * LLM Provider API client
 *
 * Provides centralized methods for LLM provider management:
 * - Provider configuration
 * - Model selection
 * - API key management
 * - Usage statistics
 */

import { apiClient } from './client';

// Type definitions for LLM API

export interface LLMProvider {
  name: string;
  label: string;
  models: string[];
  is_configured: boolean;
  requires_api_key: boolean;
  description?: string;
  cost_per_1k_input_tokens?: number;
  cost_per_1k_output_tokens?: number;
  context_window?: number;
  supports_streaming?: boolean;
  supports_vision?: boolean;
  available?: boolean;
  auth_methods?: string[];
}

export interface LLMModel {
  id: string;
  name: string;
  context: number;
}

export interface LLMConfig {
  default_provider: string;
  default_model: string;
  temperature: number;
  max_tokens: number;
}

export interface UsageStats {
  total_requests: number;
  total_tokens: {
    input: number;
    output: number;
  };
  by_provider: Record<
    string,
    {
      requests: number;
      tokens: number;
      cost: number;
    }
  >;
  by_model: Record<string, any>;
  cost_summary: {
    estimated: number;
    period: string;
  };
}

export interface ListProvidersResponse {
  providers: LLMProvider[];
  total: number;
}

export interface ListModelsResponse {
  provider: string;
  models: LLMModel[];
  total: number;
}

/**
 * LLM Provider API client
 */
export const llmAPI = {
  /**
   * List all available LLM providers
   */
  async listProviders(): Promise<ListProvidersResponse> {
    const response = await apiClient.get<{ providers: LLMProvider[]; total: number }>(
      '/llm/providers'
    );
    return response;
  },

  /**
   * Get current LLM configuration
   */
  async getConfig(): Promise<LLMConfig> {
    const response = await apiClient.get<LLMConfig>('/llm/config');
    return response;
  },

  /**
   * Set default LLM provider
   */
  async setDefaultProvider(provider: string): Promise<{ provider: string }> {
    return apiClient.put<{ provider: string }>(
      `/llm/default-provider`,
      { provider }
    );
  },

  /**
   * Set LLM model for a provider
   */
  async setProviderModel(
    provider: string,
    model: string
  ): Promise<{ provider: string; model: string }> {
    return apiClient.put<{ provider: string; model: string }>(
      `/llm/model`,
      { provider, model }
    );
  },

  /**
   * Add or update API key for provider
   *
   * SECURITY: API key is sent in request body (not URL) to prevent logging in server logs/proxies
   */
  async addAPIKey(provider: string, apiKey: string): Promise<{ provider: string; key_last_4: string }> {
    return apiClient.post<{ provider: string; key_last_4: string }>(
      `/llm/api-key`,
      {
        provider: provider,
        api_key: apiKey,
      }
    );
  },

  /**
   * Remove API key for provider
   */
  async removeAPIKey(provider: string): Promise<{ provider: string }> {
    return apiClient.delete<{ provider: string }>(`/llm/api-key/${provider}`);
  },

  /**
   * List models for a provider
   */
  async listProviderModels(provider: string): Promise<ListModelsResponse> {
    const response = await apiClient.get<ListModelsResponse>(`/llm/models/${provider}`);
    return response;
  },

  /**
   * Set authentication method for a provider
   */
  async setAuthMethod(provider: string, authMethod: string): Promise<{ provider: string; auth_method: string }> {
    return apiClient.put<{ provider: string; auth_method: string }>(
      `/llm/auth-method`,
      { provider, auth_method: authMethod }
    );
  },

  /**
   * Get API key configuration status
   *
   * Returns information about which providers have API keys configured
   * and which ones need attention (missing keys or fallback to environment variable)
   */
  async getApiKeyStatus(): Promise<{
    configured_providers: string[];
    missing_api_keys: string[];
    warnings: string[];
    environment_fallback_available: boolean;
    action_required: boolean;
  }> {
    return apiClient.get(
      `/llm-config/status`
    );
  },

  /**
   * Get usage statistics
   */
  async getUsageStats(timePeriod: string = 'month'): Promise<UsageStats> {
    return apiClient.get<UsageStats>(
      `/llm/usage-stats`,
      { params: { time_period: timePeriod } }
    );
  },
};
