/**
 * Google Gemini Generative Language API adapter.
 *
 * 차이점 (OpenAI 와):
 *   1. base URL: https://generativelanguage.googleapis.com/v1beta
 *   2. 인증: ?key=<api key>  (query parameter)
 *   3. 메시지 형식: `contents: [{role: 'user'|'model', parts: [{text: '...'}]}]`
 *      - 'system' role 없음. systemInstruction 으로 top-level 분리.
 *      - 'assistant' → 'model' 로 rename.
 *   4. response stream (alt=sse) 은 OpenAI 와 다른 JSON 구조 — streamHelpers.transformGeminiStream 으로 변환.
 *
 * 모델: gemini-2.0-flash-exp / gemini-1.5-pro / gemini-1.5-flash 등.
 *   1M context window (gemini-1.5-pro), vision, 무료 tier 등 native 기능들.
 */

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

const BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';

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

    // system 분리.
    let systemPrompt = '';
    const contents: Array<{ role: 'user' | 'model'; parts: Array<{ text: string }> }> = [];
    for (const m of params.messages) {
        if (m.role === 'system') {
            systemPrompt += (systemPrompt ? '\n\n' : '') + m.content;
        } else {
            const role: 'user' | 'model' = m.role === 'assistant' ? 'model' : 'user';
            const last = contents[contents.length - 1];
            if (last && last.role === role) {
                // 같은 role 연속이면 parts 에 합침 — Gemini 도 role 교대 강제.
                last.parts.push({ text: m.content });
            } else {
                contents.push({ role, parts: [{ text: m.content }] });
            }
        }
    }
    if (contents.length === 0 || contents[0].role !== 'user') {
        contents.unshift({ role: 'user', parts: [{ text: '(continue)' }] });
    }

    const body: any = {
        contents,
        generationConfig: {
            temperature: params.temperature,
            maxOutputTokens: params.maxTokens,
        },
    };
    if (systemPrompt) body.systemInstruction = { parts: [{ text: systemPrompt }] };

    const url = `${BASE_URL}/models/${encodeURIComponent(params.model)}:streamGenerateContent?alt=sse&key=${encodeURIComponent(cfg.apiKey)}`;
    const upstream = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'text/event-stream',
        },
        body: JSON.stringify(body),
        signal: params.signal,
    });

    if (!upstream.ok || !upstream.body) {
        return upstream;
    }

    const transformed = transformGeminiStream(upstream.body);
    return new Response(transformed, {
        status: 200,
        headers: { 'Content-Type': 'text/event-stream' },
    });
}

/** Gemini 의 사용 가능 모델 list 조회. listModels endpoint 사용. */
export async function listGeminiModels(context: vscode.ExtensionContext): Promise<string[]> {
    const cfg = await readProviderConfig(context, 'gemini');
    if (!cfg.apiKey) return [];
    try {
        const url = `${BASE_URL}/models?key=${encodeURIComponent(cfg.apiKey)}`;
        const res = await fetch(url, { signal: AbortSignal.timeout(10000) });
        if (!res.ok) return [];
        const json: any = await res.json();
        const arr = Array.isArray(json?.models) ? json.models : [];
        // 'models/gemini-2.0-flash-exp' 형식 → 'gemini-2.0-flash-exp' 로 잘라서.
        return arr
            .filter((m: any) => Array.isArray(m?.supportedGenerationMethods) && m.supportedGenerationMethods.includes('generateContent'))
            .map((m: any) => String(m?.name ?? '').replace(/^models\//, ''))
            .filter(Boolean);
    } catch {
        return [];
    }
}

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