package app.mealsmadeeasy.api.ai;

import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.Nullable;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.ollama.api.OllamaChatOptions;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class InferenceService {

    private static final String OLLAMA_MODEL = "gemma3:latest";

    private final ChatModel chatModel;

    public <T> @Nullable T extract(
            Message systemMessage,
            Message userMessage,
            BeanOutputConverter<T> converter
    ) {
        final ChatOptions extractChatOptions = OllamaChatOptions.builder()
                .model(OLLAMA_MODEL)
                .format(converter.getJsonSchemaMap())
                .build();
        final Prompt extractPrompt = Prompt.builder()
                .messages(systemMessage, userMessage)
                .chatOptions(extractChatOptions)
                .build();
        final ChatResponse extractResponse = this.chatModel.call(extractPrompt);
        final String extractContent = extractResponse.getResult().getOutput().getText();
        if (extractContent == null) {
            return null;
        }
        return converter.convert(extractContent);
    }

    public @Nullable String infer(List<Message> messages) {
        final ChatOptions chatOptions = OllamaChatOptions.builder()
                .model(OLLAMA_MODEL)
                .build();
        final Prompt prompt = Prompt.builder()
                .messages(messages)
                .chatOptions(chatOptions)
                .build();
        final ChatResponse chatResponse = this.chatModel.call(prompt);
        return chatResponse.getResult().getOutput().getText();
    }

}
