/**
 * Anthropic Messages API adapter.
 *
 * 차이점 (OpenAI 와):
 *   1. base URL: https://api.anthropic.com/v1
 *   2. 인증: x-api-key: <key>  + anthropic-version: 2023-06-01
 *   3. system prompt 는 messages 가 아니라 *top-level `system`* 필드
 *   4. response stream 은 OpenAI 와 다른 event 형식 — streamHelpers.transformAnthropicStream 로 변환
 *
 * 향후 확장 여지 (이번 세션은 단순 streaming 만):
 *   - prompt caching (`cache_control: {type: "ephemeral"}`) — 시스템 prompt 비용 90% 절감
 *   - tool use — action tag 와 함께 쓰면 더 깔끔
 */

import * as vscode from 'vscode';
import { StreamParams } from './types';
import { readProviderConfig } from './providerConfig';
import { transformAnthropicStream } from './streamHelpers';

const BASE_URL = 'https://api.anthropic.com/v1';
const API_VERSION = '2023-06-01';

export async function streamAnthropic(
    context: vscode.ExtensionContext,
    params: StreamParams,
): Promise<Response> {
    const cfg = await readProviderConfig(context, 'anthropic');
    if (!cfg.apiKey) {
        return _errorResponse(401, 'Anthropic API key 가 설정되지 않았습니다. Settings 패널에서 등록해주세요.');
    }

    // system 메시지 분리 — Anthropic 은 system 을 top-level 로.
    let systemPrompt = '';
    const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [];
    for (const m of params.messages) {
        if (m.role === 'system') {
            // 여러 system 메시지가 있으면 합침 (Anthropic 은 한 개의 system 문자열만 받음).
            systemPrompt += (systemPrompt ? '\n\n' : '') + m.content;
        } else if (m.role === 'user' || m.role === 'assistant') {
            // 연속된 같은 role 은 합쳐야 함 — Anthropic 은 role 교대 강제.
            const last = messages[messages.length - 1];
            if (last && last.role === m.role) {
                last.content += '\n\n' + m.content;
            } else {
                messages.push({ role: m.role, content: m.content });
            }
        }
    }

    // Anthropic 은 첫 메시지가 user 여야 함 — assistant 로 시작하면 dummy user 추가.
    if (messages.length === 0 || messages[0].role !== 'user') {
        messages.unshift({ role: 'user', content: '(continue)' });
    }

    const body: any = {
        model: params.model,
        messages,
        max_tokens: Math.max(1, params.maxTokens),
        temperature: params.temperature,
        stream: true,
    };
    if (systemPrompt) body.system = systemPrompt;

    const upstream = await fetch(`${BASE_URL}/messages`, {
        method: 'POST',
        headers: {
            'x-api-key': cfg.apiKey,
            'anthropic-version': API_VERSION,
            'Content-Type': 'application/json',
            'Accept': 'text/event-stream',
        },
        body: JSON.stringify(body),
        signal: params.signal,
    });

    if (!upstream.ok || !upstream.body) {
        // 에러 응답은 그대로 반환 — caller 가 .text() 로 에러 메시지 추출.
        return upstream;
    }

    // OpenAI-format SSE 로 transform 후 새 Response 로 wrap.
    const transformed = transformAnthropicStream(upstream.body);
    return new Response(transformed, {
        status: 200,
        headers: { 'Content-Type': 'text/event-stream' },
    });
}

/**
 * Anthropic 은 모델 list API 가 *없음* (공개) — 대신 *알려진 stable 모델* 의 하드코딩 목록을 반환.
 * 사용자가 직접 정확한 model id 를 입력해도 동작 (validate 안 함).
 */
export function listAnthropicModels(): string[] {
    return [
        'claude-3-5-sonnet-20241022',
        'claude-3-5-sonnet-20240620',
        'claude-3-5-haiku-20241022',
        'claude-3-opus-20240229',
        'claude-3-sonnet-20240229',
        'claude-3-haiku-20240307',
    ];
}

function _errorResponse(status: number, msg: string): Response {
    return new Response(JSON.stringify({ error: { message: msg } }), {
        status, headers: { 'Content-Type': 'application/json' },
    });
}
