// src/controllers/chat.controller.js
// 채팅 컨트롤러 (OpenAI 호환 API)

const llmService = require('../services/llm.service');
const logger = require('../config/logger.config');

/**
 * 채팅 완성 API (OpenAI 호환)
 * POST /api/v1/chat/completions
 */
exports.completions = async (req, res, next) => {
  try {
    const {
      model = 'gemini-2.0-flash',
      messages,
      temperature = 0.7,
      max_tokens = 4096,
      stream = false,
    } = req.body;

    const startTime = Date.now();

    // 스트리밍 응답 처리
    if (stream) {
      return handleStreamingResponse(req, res, {
        model,
        messages,
        temperature,
        maxTokens: max_tokens,
      });
    }

    // 일반 응답 처리
    const result = await llmService.chat({
      model,
      messages,
      temperature,
      maxTokens: max_tokens,
      userId: req.user.id,
      apiKeyId: req.apiKey?.id,
    });

    const responseTime = Date.now() - startTime;

    // 사용량 정보 저장 (미들웨어에서 처리)
    req.usageData = {
      providerId: result.providerId,
      providerName: result.provider,
      modelName: result.model,
      promptTokens: result.usage.promptTokens,
      completionTokens: result.usage.completionTokens,
      totalTokens: result.usage.totalTokens,
      costUsd: result.cost,
      responseTimeMs: responseTime,
      success: true,
    };

    // OpenAI 호환 응답 형식
    return res.json({
      id: `chatcmpl-${Date.now()}`,
      object: 'chat.completion',
      created: Math.floor(Date.now() / 1000),
      model: result.model,
      choices: [
        {
          index: 0,
          message: {
            role: 'assistant',
            content: result.text,
          },
          finish_reason: 'stop',
        },
      ],
      usage: {
        prompt_tokens: result.usage.promptTokens,
        completion_tokens: result.usage.completionTokens,
        total_tokens: result.usage.totalTokens,
      },
    });
  } catch (error) {
    logger.error('채팅 완성 오류:', error);

    // 사용량 정보 저장 (실패)
    req.usageData = {
      success: false,
      errorMessage: error.message,
    };

    return next(error);
  }
};

/**
 * 스트리밍 응답 처리
 */
async function handleStreamingResponse(req, res, params) {
  const { model, messages, temperature, maxTokens } = params;

  // SSE 헤더 설정
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  try {
    // 스트리밍 응답 생성
    const stream = await llmService.chatStream({
      model,
      messages,
      temperature,
      maxTokens,
      userId: req.user.id,
      apiKeyId: req.apiKey?.id,
    });

    // 스트림 이벤트 처리
    for await (const chunk of stream) {
      const data = {
        id: `chatcmpl-${Date.now()}`,
        object: 'chat.completion.chunk',
        created: Math.floor(Date.now() / 1000),
        model,
        choices: [
          {
            index: 0,
            delta: {
              content: chunk.text,
            },
            finish_reason: chunk.done ? 'stop' : null,
          },
        ],
      };

      res.write(`data: ${JSON.stringify(data)}\n\n`);
    }

    // 스트림 종료
    res.write('data: [DONE]\n\n');
    res.end();
  } catch (error) {
    logger.error('스트리밍 오류:', error);

    const errorData = {
      error: {
        message: error.message,
        type: 'server_error',
      },
    };

    res.write(`data: ${JSON.stringify(errorData)}\n\n`);
    res.end();
  }
}
