package com.lanyuanxiaoyao.service.ai.chat.controller;

import cn.hutool.core.util.StrUtil;
import com.lanyuanxiaoyao.service.ai.chat.entity.MessageVO;
import com.lanyuanxiaoyao.service.ai.chat.tools.DatetimeTools;
import java.io.IOException;
import org.eclipse.collections.api.list.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

/**
 * 聊天
 *
 * @author lanyuanxiaoyao
 * @version 20250514
 */
@Controller
@RequestMapping("chat")
public class ChatController {
  private static final Logger logger = LoggerFactory.getLogger(ChatController.class);

  private final ChatClient chatClient;

  public ChatController(ChatClient.Builder builder) {
    this.chatClient = builder.build();
  }

  private ChatClient.ChatClientRequestSpec buildRequest(ImmutableList<MessageVO> messages) {
    return chatClient.prompt()
        .system("""
            你是一名专业的AI运维助手，负责“Hudi数据同步服务平台”的运维工作；
            你将会友好地帮助用户解答关于该平台运维工作的问题，你会尽可能通过各种方式获取知识和数据来解答；
            对于无法通过已有知识回答的问题，你会提示用户你无法解答该问题，而不是虚构不存在的数据或答案；
            对于与该平台无关的问题，你会委婉地拒绝用户，并提示无法回答；
            你将始终在中文语境下进行对话。
            """)
        .tools(new DatetimeTools())
        .messages(
            messages
                .collect(message -> StrUtil.equals(message.getRole(), "assistant")
                    ? new AssistantMessage(message.getContent())
                    : new UserMessage(message.getContent()))
                .collect(message -> (Message) message)
                .toList()
        );
  }

  @PostMapping("sync")
  @ResponseBody
  public String chatSync(@RequestBody ImmutableList<MessageVO> messages) {
    String content = buildRequest(messages)
        .call()
        .content();
    return StrUtil.trimToEmpty(content);
  }

  @PostMapping("async")
  public SseEmitter chatAsync(@RequestBody ImmutableList<MessageVO> messages) {
    SseEmitter emitter = new SseEmitter();
    buildRequest(messages)
        .stream()
        .content()
        .subscribe(
            content -> {
              try {
                emitter.send(content);
              } catch (IOException e) {
                emitter.completeWithError(e);
                throw new RuntimeException(e);
              }
            },
            emitter::completeWithError,
            emitter::complete
        );
    return emitter;
  }
}
