/**
 * LLM provider factory.
 *
 * Creates an LLMProvider based on LLM_PROVIDER env var.
 * Auto-detects Azure vs OpenAI from endpoint URLs if not explicitly set.
 */

import { AzureOpenAIProvider } from './providers/azure-openai.js';
import { MockLLMProvider } from './providers/mock.js';
import { OpenAIProvider } from './providers/openai.js';
import type { LLMProvider, LLMProviderType } from './types.js';

let _provider: LLMProvider | null = null;

/**
 * Resolve provider type from env vars.
 * Priority: LLM_PROVIDER > OPENAI_PROVIDER > auto-detect from endpoint URLs.
 */
function resolveProviderType(): LLMProviderType {
  const explicit = (process.env.LLM_PROVIDER || process.env.OPENAI_PROVIDER || '').toLowerCase();
  if (explicit === 'azure') return 'azure';
  if (explicit === 'openai') return 'openai';
  if (explicit === 'mock') return 'mock';

  const azureEndpoint = process.env.AZURE_OPENAI_ENDPOINT;
  const baseUrl = process.env.OPENAI_BASE_URL || '';
  if (azureEndpoint && azureEndpoint.trim().length > 0) return 'azure';
  if (baseUrl.includes('.cognitive.microsoft.com') || baseUrl.includes('.openai.azure.com'))
    return 'azure';

  return 'openai';
}

/**
 * Get the singleton LLM provider.
 */
export function getLLM(): LLMProvider {
  if (!_provider) {
    const type = resolveProviderType();
    _provider = createLLMProvider(type);
  }
  return _provider;
}

/**
 * Create an LLM provider by type.
 */
export function createLLMProvider(type: LLMProviderType): LLMProvider {
  switch (type) {
    case 'azure':
      return new AzureOpenAIProvider();
    case 'openai':
      return new OpenAIProvider();
    case 'mock':
      return new MockLLMProvider();
    default:
      throw new Error(`Unknown LLM_PROVIDER: '${type}'. Valid: azure, openai, mock`);
  }
}

/**
 * Set the singleton LLM provider (for testing).
 */
export function setLLM(provider: LLMProvider): void {
  _provider = provider;
}

/**
 * @internal
 */
export function _resetLLM(): void {
  _provider = null;
}
