import test from 'node:test';
import assert from 'node:assert/strict';
import { LiteLLMProvider } from '../lib/llm/litellm.mjs';
import { createLLMProvider } from '../lib/llm/index.mjs';

test('factory creates a configured LiteLLM provider', () => {
  const provider = createLLMProvider({
    provider: 'litellm',
    baseUrl: 'https://llm.example.test/v1/',
    apiKey: 'proxy-key',
    model: 'private-model',
  });

  assert.ok(provider instanceof LiteLLMProvider);
  assert.equal(provider.baseUrl, 'https://llm.example.test/v1');
  assert.equal(provider.isConfigured, true);
  assert.deepEqual(provider.status, {
    state: 'configured',
    provider: 'litellm',
    model: 'private-model',
    baseUrl: 'https://llm.example.test/v1',
  });
});

test('LiteLLM requires base URL, API key, and model', () => {
  const missingBaseUrl = new LiteLLMProvider({ apiKey: 'key', model: 'model' });
  assert.equal(missingBaseUrl.isConfigured, false);
  assert.equal(missingBaseUrl.status.reason, 'LLM_BASE_URL is required for LiteLLM');

  const missingKey = new LiteLLMProvider({ baseUrl: 'https://llm.example.test/v1', model: 'model' });
  assert.equal(missingKey.status.reason, 'LLM_API_KEY is required for LiteLLM');

  const missingModel = new LiteLLMProvider({ baseUrl: 'https://llm.example.test/v1', apiKey: 'key' });
  assert.equal(missingModel.status.reason, 'LLM_MODEL is required for LiteLLM');
});

test('LiteLLM sends bearer-authenticated OpenAI-compatible requests', async () => {
  const provider = new LiteLLMProvider({
    baseUrl: 'https://llm.example.test/v1',
    apiKey: 'proxy-key',
    model: 'private-model',
    temperature: 0.15,
    maxTokens: 512,
  });
  const originalFetch = globalThis.fetch;

  globalThis.fetch = async (url, options) => {
    assert.equal(url, 'https://llm.example.test/v1/chat/completions');
    assert.equal(options.headers.Authorization, 'Bearer proxy-key');
    assert.deepEqual(JSON.parse(options.body), {
      model: 'private-model',
      temperature: 0.15,
      messages: [
        { role: 'system', content: 'system' },
        { role: 'user', content: 'user' },
      ],
      max_tokens: 512,
    });
    return {
      ok: true,
      json: async () => ({
        choices: [{ message: { content: 'response' } }],
        usage: { prompt_tokens: 7, completion_tokens: 11 },
        model: 'private-model',
      }),
    };
  };

  try {
    const result = await provider.complete('system', 'user');
    assert.equal(result.text, 'response');
    assert.deepEqual(result.usage, { inputTokens: 7, outputTokens: 11 });
  } finally {
    globalThis.fetch = originalFetch;
  }
});
