package de.assecutor.votianlt.ai.service;

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * LLM client backed by the Anthropic Claude API (official Java SDK). Keeps the
 * same public interface as the previous LM-Studio-based implementation so
 * callers (AiStatisticsService, TranslationService) stay unchanged.
 */
@Component
@Slf4j
public class LlmRestClient {

    private static final Pattern THINK_BLOCK_PATTERN = Pattern.compile("(?is)<think>.*?</think>");
    private static final Pattern THINK_TAG_PATTERN = Pattern.compile("(?is)</?think>");

    private final AnthropicClient client;
    private final String model;

    public LlmRestClient(@Value("${app.ai.anthropic.api-key}") String apiKey,
            @Value("${app.ai.anthropic.model:claude-opus-4-8}") String model) {
        this.model = model;
        this.client = AnthropicOkHttpClient.builder().apiKey(apiKey).build();
        log.info("LlmRestClient initialized - Provider: Anthropic Claude, Model: {}", model);
    }

    /**
     * Send a chat completion request.
     *
     * @param systemPrompt
     *            System prompt for context
     * @param userMessage
     *            User message/question
     * @return LLM response text, or null on error
     */
    public String chat(String systemPrompt, String userMessage) {
        return chat(systemPrompt, userMessage, 0.7, 2000);
    }

    /**
     * Send a chat completion request with custom parameters.
     *
     * @param systemPrompt
     *            System prompt for context
     * @param userMessage
     *            User message/question
     * @param temperature
     *            Ignored - current Claude models do not accept sampling
     *            parameters (kept for signature compatibility)
     * @param maxTokens
     *            Maximum tokens in response
     * @return LLM response text, or null on error
     */
    public String chat(String systemPrompt, String userMessage, double temperature, int maxTokens) {
        try {
            MessageCreateParams.Builder builder = MessageCreateParams.builder().model(model).maxTokens(maxTokens);
            if (systemPrompt != null && !systemPrompt.isBlank()) {
                builder.system(systemPrompt);
            }
            builder.addUserMessage(userMessage);

            log.info("Sending request to Claude (model: {}, prompt length: {} chars)...", model, userMessage.length());
            long startTime = System.currentTimeMillis();

            Message response = client.messages().create(builder.build());

            long duration = System.currentTimeMillis() - startTime;
            log.info("Claude response received in {}ms (stop_reason: {})", duration, response.stopReason());

            String content = response.content().stream().flatMap(block -> block.text().stream())
                    .map(textBlock -> textBlock.text()).collect(Collectors.joining("\n"));

            if (content.isBlank()) {
                log.warn("Claude response content is empty");
                return null;
            }

            String sanitizedContent = sanitizeAssistantContent(content);
            if (sanitizedContent.isBlank()) {
                log.warn("Claude response content is empty after sanitization");
                return null;
            }
            return sanitizedContent;

        } catch (Exception e) {
            log.error("Error calling Claude API: {} - {}", e.getClass().getSimpleName(), e.getMessage());
            if (log.isDebugEnabled()) {
                log.debug("Full stack trace:", e);
            }
            return null;
        }
    }

    /**
     * Simple chat without system prompt.
     */
    public String chat(String userMessage) {
        return chat(null, userMessage);
    }

    public String getModel() {
        return model;
    }

    private String sanitizeAssistantContent(String content) {
        String sanitized = THINK_BLOCK_PATTERN.matcher(content).replaceAll(" ");
        sanitized = THINK_TAG_PATTERN.matcher(sanitized).replaceAll(" ");
        sanitized = sanitized.replace("\r", "");
        sanitized = sanitized.replaceAll("[ \\t]+", " ");
        sanitized = sanitized.replaceAll("\\n{3,}", "\n\n");
        return sanitized.trim();
    }
}
