/**
 * Anthropic Adapter Integration Test
 *
 * Purpose: Verify Anthropic adapter works with real API calls
 * Pattern: External API Integration (Pattern 4)
 * Runs in CI: NO (requires ANTHROPIC_API_KEY)
 *
 * Prerequisites:
 * - ANTHROPIC_API_KEY in .env.development
 *
 * Run locally:
 *   cd packages/core
 *   pnpm vitest run anthropic.integration
 *
 * Note: Tests use model aliases defined in AnthropicModel type (model-info.ts)
 */

import { describe, it, expect, beforeAll } from 'vitest'
import { createLLMAdapter } from '../server/adapter-factory'
import type { ModelConfig } from '../../model-info'
import type { LLMGenerateRequest } from '../../types'

// Skip by default - set to false to run manually
const SKIP_TESTS = true

describe.skipIf(SKIP_TESTS)('Anthropic Adapter Integration', () => {
  let apiKey: string

  beforeAll(() => {
    apiKey = process.env.ANTHROPIC_API_KEY!
  })

  const createRequest = (prompt: string): LLMGenerateRequest => ({
    messages: [
      { role: 'system', content: 'You are a helpful assistant. Always respond using the structured_output tool.' },
      { role: 'user', content: prompt }
    ],
    responseSchema: {
      type: 'object',
      properties: {
        answer: { type: 'string' },
        confidence: { type: 'number' }
      },
      required: ['answer', 'confidence']
    },
    maxOutputTokens: 500
  })

  describe('Claude Haiku 4.5 (fastest)', () => {
    it('generates structured output with tool_use', async () => {
      const config: ModelConfig = {
        provider: 'anthropic',
        model: 'claude-haiku-4-5',
        apiKey,
        temperature: 0.7,
        maxOutputTokens: 500
      }

      const adapter = createLLMAdapter(config)
      const request = createRequest('What is the capital of France? Be concise.')

      const response = await adapter.generate<{ answer: string; confidence: number }>(request)

      expect(response.output).toBeDefined()
      expect(response.output.answer).toBeDefined()
      expect(typeof response.output.answer).toBe('string')
      expect(response.output.answer.toLowerCase()).toContain('paris')
      expect(typeof response.output.confidence).toBe('number')
    }, 30000)

    it('tracks token usage correctly', async () => {
      const config: ModelConfig = {
        provider: 'anthropic',
        model: 'claude-haiku-4-5',
        apiKey,
        maxOutputTokens: 500
      }

      const adapter = createLLMAdapter(config)
      const request = createRequest('Say hello.')

      const response = await adapter.generate<{ answer: string; confidence: number }>(request)

      expect(response.usage).toBeDefined()
      expect(response.usage?.inputTokens).toBeGreaterThan(0)
      expect(response.usage?.outputTokens).toBeGreaterThan(0)
      expect(response.usage?.totalTokens).toBe((response.usage?.inputTokens || 0) + (response.usage?.outputTokens || 0))
    }, 30000)
  })

  describe('Claude Sonnet 4.5 (balanced)', () => {
    it('generates structured output', async () => {
      const config: ModelConfig = {
        provider: 'anthropic',
        model: 'claude-sonnet-4-5',
        apiKey,
        temperature: 0.7,
        maxOutputTokens: 500
      }

      const adapter = createLLMAdapter(config)
      const request = createRequest('What is 2 + 2? Answer with just the number.')

      const response = await adapter.generate<{ answer: string; confidence: number }>(request)

      expect(response.output).toBeDefined()
      expect(response.output.answer).toBeDefined()
      expect(response.output.answer).toContain('4')
    }, 30000)
  })

  describe('Message Handling', () => {
    it('handles multi-turn conversations', async () => {
      const config: ModelConfig = {
        provider: 'anthropic',
        model: 'claude-haiku-4-5',
        apiKey,
        maxOutputTokens: 500
      }

      const adapter = createLLMAdapter(config)
      const request: LLMGenerateRequest = {
        messages: [
          { role: 'system', content: 'You are a helpful math tutor.' },
          { role: 'user', content: 'What is 5 + 3?' },
          { role: 'assistant', content: 'The answer is 8.' },
          { role: 'user', content: 'Now multiply that by 2.' }
        ],
        responseSchema: {
          type: 'object',
          properties: {
            answer: { type: 'string' },
            calculation: { type: 'string' }
          },
          required: ['answer', 'calculation']
        },
        maxOutputTokens: 500
      }

      const response = await adapter.generate<{ answer: string; calculation: string }>(request)

      expect(response.output).toBeDefined()
      expect(response.output.answer).toContain('16')
    }, 30000)

    it('handles multiple system messages', async () => {
      const config: ModelConfig = {
        provider: 'anthropic',
        model: 'claude-haiku-4-5',
        apiKey,
        maxOutputTokens: 500
      }

      const adapter = createLLMAdapter(config)
      const request: LLMGenerateRequest = {
        messages: [
          { role: 'system', content: 'You are a helpful assistant.' },
          { role: 'system', content: 'Always be concise.' },
          { role: 'user', content: 'Say hi.' }
        ],
        responseSchema: {
          type: 'object',
          properties: {
            greeting: { type: 'string' }
          },
          required: ['greeting']
        },
        maxOutputTokens: 500
      }

      const response = await adapter.generate<{ greeting: string }>(request)

      expect(response.output).toBeDefined()
      expect(response.output.greeting).toBeDefined()
    }, 30000)
  })
})
