package com.erp.ai.client;

import com.erp.ai.exception.LlmClientException;
import com.erp.ai.mapper.AiLlmProviderMapper;
import com.erp.ai.model.AiLlmProvider;
import com.erp.ai.util.AesGcmCipher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientResponseException;

import java.util.Map;

/**
 * OpenAI LLM 클라이언트 (DeepSeek 등 OpenAI 호환 프로바이더 포함).
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OpenAiLlmClient implements LlmClient {

    private static final String DEFAULT_BASE_URL = "https://api.openai.com";

    @Qualifier("llmRestClient")
    private final RestClient httpClient;
    private final AiLlmProviderMapper providerMapper;
    private final AesGcmCipher cipher;

    @Override
    public boolean supports(String model) {
        return model != null && (model.startsWith("gpt-") || model.startsWith("o1-") || model.startsWith("o3-"));
    }

    @Override
    public String providerName() {
        return "openai";
    }

    @Override
    @SuppressWarnings("unchecked")
    public Map<String, Object> chat(Map<String, Object> request) {
        AiLlmProvider provider = providerMapper.getByName("openai");
        if (provider == null || !Boolean.TRUE.equals(provider.getIs_active())) {
            throw new LlmClientException("OpenAI 프로바이더가 활성화되지 않았습니다.");
        }
        String apiKey = cipher.decrypt(provider.getApi_key_encrypted());
        String baseUrl = provider.getEndpoint() != null ? provider.getEndpoint() : DEFAULT_BASE_URL;

        try {
            return httpClient.post()
                    .uri(baseUrl + "/v1/chat/completions")
                    .contentType(MediaType.APPLICATION_JSON)
                    .header("Authorization", "Bearer " + apiKey)
                    .body(request)
                    .retrieve()
                    .body(Map.class);
        } catch (RestClientResponseException e) {
            log.error("OpenAI API 오류 {}: {}", e.getStatusCode().value(), e.getResponseBodyAsString());
            throw new LlmClientException("OpenAI API 오류: " + e.getMessage(), e.getStatusCode().value());
        } catch (Exception e) {
            throw new LlmClientException("OpenAI 호출 실패: " + e.getMessage(), e);
        }
    }
}
