package com.ruoyi.cms.controller.app;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.cms.domain.ai.AiChatHistory;
import com.ruoyi.cms.domain.chat.ChatRequest;
import com.ruoyi.cms.service.AiChatHistoryService;
import com.ruoyi.common.annotation.BussinessLog;
import com.ruoyi.cms.config.ChatClient;
import com.ruoyi.cms.config.ChatConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.SiteSecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.ruoyi.common.enums.BusinessType.QUERY;

@RestController
@RequestMapping(value = "/app/chat")
@Slf4j
@Api(tags = "移动端:ai对话")
public class ChatController extends BaseController {

    @Autowired
    ChatClient chatClient;
    @Autowired
    ChatConfig chatConfig;
    @Autowired
    AiChatHistoryService aiChatHistoryService;

    //private final ExecutorService executor = Executors.newCachedThreadPool();
    // 可优化线程池配置，避免无限创建线程
    private final ExecutorService executor = new ThreadPoolExecutor(
            2,  // 核心线程数
            10, // 最大线程数
            30, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(50), // 任务队列
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略（避免任务丢失）
    );

    @BussinessLog(title = "查询用户的聊天历史记录",businessType = QUERY)
    @ApiOperation("查询用户的聊天历史记录")
    @GetMapping(value = "/getHistory")
    public AjaxResult getChatHistoryList(AiChatHistory chatHistory) {
        return AjaxResult.success(aiChatHistoryService.getList(chatHistory));
    }

    @BussinessLog(title = "查询用户的聊天详情",businessType = QUERY)
    @ApiOperation("查询用户的聊天详情")
    @GetMapping(value = "/detail")
    public AjaxResult getChatDetail(ChatRequest request) {
        return AjaxResult.success(aiChatHistoryService.getDetailList(request.getSessionId()));
    }

    // 处理前端聊天请求，返回 SSE 发射器
    @ApiOperation("用户AI聊天")
    @PostMapping("/chat")
    @ResponseBody
    @BussinessLog(title = "用户AI聊天",businessType = QUERY)
    public SseEmitter chatStream(@RequestBody ChatRequest request) {
        // 设置超时时间（30分钟）
        SseEmitter emitter = new SseEmitter(1800000L);
        long userId = 0;
        if(ObjectUtil.isNotEmpty(request.getUserId())&&request.getUserId()!=0){
            userId = request.getUserId();
        }else{
            try {
                userId = SiteSecurityUtils.getLoginUser().getUserId();
            }catch (Exception e) {

            }
        }

        JSONObject contentObject = new JSONObject();
        contentObject.put("content",request.getData());
        contentObject.put("role","user");
        JSONArray array = aiChatHistoryService.getChatHistoryData(request.getSessionId());
        if(array==null||array.isEmpty()||array.size()==0){
            array = new JSONArray();
        }
        array.add(contentObject);
        request.setMessages(array);

        List<String> answerList = new ArrayList<>();
        long[] timeStart = {0};
        // 异步处理请求并推送数据
        executor.submit(() -> {
            try {
                // 2. 调用ChatClient的流式聊天方法，正确传递参数
                chatClient.sendStreamingChat(
                        request,
                        new ChatClient.StreamCallback() {  // 使用内部类完整路径
                            @Override
                            public void onData(String chunk) {
                                try {
                                    if(timeStart[0] == 0){
                                        timeStart[0] = System.currentTimeMillis();
                                    }
                                    // 1. 处理SSE协议格式
                                    String processedChunk = chunk.trim();
                                    // 解析返回的chunk数据
                                    String content = parseChatChunk(processedChunk);
                                    if (StringUtils.isNotEmpty(content)) {
                                        answerList.add(content);
                                    }
                                    emitter.send(processedChunk, MediaType.TEXT_EVENT_STREAM);
                                } catch (IOException e) {
                                    emitter.completeWithError(e);
                                }
                            }

                            @Override
                            public void onComplete() {
                                emitter.complete();
                            }

                            @Override
                            public void onError(Throwable e) {
                                try {
                                    emitter.send(SseEmitter.event()
                                            .data("{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}")
                                            .name("error"));
                                } catch (IOException ex) {
                                    // 记录日志
                                } finally {
                                    emitter.completeWithError(e);
                                }
                            }
                        }
                );
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        });

        // 处理连接关闭
        long finalUserId = userId;
        emitter.onCompletion(() -> {
            // 此处仅做资源清理，不关闭线程池
            log.info("连接关闭，清理资源");
            long timeEnd = System.currentTimeMillis();
            double duration = (timeEnd - timeStart[0]) / 1000.0;
            AiChatHistory chatHistory = new AiChatHistory();
            chatHistory.setChatId(request.getSessionId());
            chatHistory.setUserId((finalUserId==0)?null:finalUserId);
            chatHistory.setAppId(chatConfig.getAppId());
            chatHistory.setDataId(request.getDataId());
            chatHistory.setTitle(request.getData());
            chatHistory.setAnswerStringList(answerList);
            chatHistory.setDurationSeconds(duration);
            aiChatHistoryService.saveChatHistory(chatHistory);
        });
        return emitter;
    }

    @BussinessLog(title = "提供推测出的问询建议",businessType = QUERY)
    @ApiOperation("提供推测出的问询建议")
    @PostMapping(value = "/guest")
    public AjaxResult getChatGuest(@RequestBody ChatRequest request) throws IOException {
        JSONArray array = aiChatHistoryService.getChatHistoryData(request.getSessionId());
        request.setMessages(array);
        String result = chatClient.sendChatGuest(request);
        try {
            String[] strList = result.split("？");
            List<String> list = new ArrayList<>();
            for(String str:strList){
                if(StringUtils.isNotEmpty(str)){
                    str = str+"？";
                    list.add(str);
                }
            }
            return AjaxResult.success(list);
        }catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    // 解析返回的流式数据
    private String parseChatChunk(String chunk) {
        try {
            String processed = chunk.trim();
            if (processed.startsWith("data:")) {
                processed = processed.substring("data:".length()).trim();
            }
            if (processed.isEmpty() || "[DONE]".equals(processed)) {
                return null;
            }
            JSONObject json = JSONObject.parseObject(processed);
            String choices = json.getString("choices");
            if (choices != null && !choices.trim().isEmpty()) {
                JSONArray jsonArray = JSONArray.parseArray(choices);
                json = JSONObject.parseObject(jsonArray.getString(0));
                json = json.getJSONObject("delta");
                String content = json.getString("content");// 消息内容

                return content;
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    @PreDestroy
    public void destroy() {
        executor.shutdown(); // 应用退出前关闭线程池
        try {
            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                executor.shutdownNow(); // 强制关闭未完成的任务
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            executor.shutdownNow();
            log.error(e.getMessage());
        }
    }

}
