package io.github.lynbean.lynbot.cogs.openai.chat;

import java.util.List;

import com.google.common.base.Optional;
import com.theokanning.openai.completion.chat.ChatCompletionChunk;
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
import com.theokanning.openai.completion.chat.ChatCompletionResult;
import com.theokanning.openai.completion.chat.ChatMessage;
import com.theokanning.openai.completion.chat.ChatMessageRole;

import io.github.lynbean.lynbot.Bot;
import io.github.lynbean.lynbot.cogs.openai.core.OpenAiCore;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Accessors(chain = true)
public class Chat extends OpenAiCore {
    private @Getter @Setter Double frequencyPenalty;
    private @Getter @Setter Double presencePenalty;
    private @Getter @Setter Double temperature;
    private @Getter @Setter Double topP;
    private @Getter @Setter Integer maxTokens;
    private @Getter List<ChatMessage> messages;
    private @Getter @Setter String model;
    private @Getter @Setter String user;

    public static Chat fromString(String content) {
        ChatMessage message = new ChatMessage();
        message.setContent(content);
        message.setRole(ChatMessageRole.USER.value());
        return new Chat(message);
    }

    public Chat(ChatMessage message) {
        super();
        this.messages = List.of(message);
    }

    public Chat(List<ChatMessage> messages) {
        super();
        this.messages = messages;
    }

    private ChatCompletionRequest createCompletionRequest() {
        return ChatCompletionRequest.builder()
            .frequencyPenalty(
                Optional.fromNullable(frequencyPenalty)
                    .or(Bot.getConfig().getDouble("openai.chat.frequency_penalty"))
            )
            .maxTokens(
                Optional.fromNullable(maxTokens)
                    .or(Bot.getConfig().getInt("openai.chat.max_tokens"))
            )
            .messages(messages)
            .model(
                Optional.fromNullable(model)
                    .or(Bot.getConfig().getString("openai.chat.default_model"))
            )
            .presencePenalty(
                Optional.fromNullable(presencePenalty)
                    .or(Bot.getConfig().getDouble("openai.chat.presence_penalty"))
            )
            .topP(
                Optional.fromNullable(topP)
                    .or(Bot.getConfig().getDouble("openai.chat.top_p"))
            )
            .user(user)
            .build();
    }

    public ChatCompletionResult complete() {
        return OPEN_AI_SERVICE.createChatCompletion(createCompletionRequest());
    }

    public void complete(Consumer<ChatCompletionChunk> onNext, Consumer<Throwable> onError, Action onComplete) {
        OPEN_AI_SERVICE.streamChatCompletion(createCompletionRequest())
            .subscribe(
                chunk -> onNext.accept(chunk),
                error -> onError.accept(error),
                onComplete
            );
    }
}

com.theokanning.openai.completion.chat.ChatMessageRole.USER.value com.theokanning.openai.completion.chat.ChatCompletionRequest.builder
[((1301, 1329), 'com.theokanning.openai.completion.chat.ChatMessageRole.USER.value'), ((1659, 2603), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 2582), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 2558), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 2409), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 2227), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 2068), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 2036), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1659, 1875), 'com.theokanning.openai.completion.chat.ChatCompletionRequest.builder'), ((1738, 1861), 'com.google.common.base.Optional.fromNullable'), ((1802, 1860), 'io.github.lynbean.lynbot.Bot.getConfig'), ((1916, 2022), 'com.google.common.base.Optional.fromNullable'), ((1973, 2021), 'io.github.lynbean.lynbot.Bot.getConfig'), ((2105, 2213), 'com.google.common.base.Optional.fromNullable'), ((2158, 2212), 'io.github.lynbean.lynbot.Bot.getConfig'), ((2274, 2395), 'com.google.common.base.Optional.fromNullable'), ((2337, 2394), 'io.github.lynbean.lynbot.Bot.getConfig'), ((2445, 2544), 'com.google.common.base.Optional.fromNullable'), ((2497, 2543), 'io.github.lynbean.lynbot.Bot.getConfig')]