package com.mortals.xhx.base.system.message.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.service.ICacheService;
import com.mortals.xhx.base.system.message.MessageService;
import com.mortals.xhx.webflux.req.RobotTransReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.util.Collections;

/**
 * DeviceService
 * 设备 service实现
 *
 * @author zxfei
 * @date 2022-03-09
 */
@Service("messageService")
@Slf4j
public class MessageServiceImpl implements MessageService {

    @Value("${chat.streamChatUrl:''}")
    private String streamChatUrl;

    @Value("${chat.auth-head:''}")
    private String authHead;

    @Value("${chat.auth-value:''}")
    private String authValue;


    @Autowired
    private ICacheService cacheService;


    @Override
    public Flux<String> sendMessageToFastApi(SseEmitter sseEmitter, RobotTransReq robotTransReq) {
        // 创建 WebClient 客户端
        WebClient webClient = WebClient.builder().baseUrl(streamChatUrl).build();
        // 封装参数
        JSONObject params = new JSONObject();
        params.put("chatId", "my_chatId");
        params.put("stream", true);
        params.put("detail", true);
        params.put("responseChatItemId", "my_responseChatItemId");
        JSONObject variables = new JSONObject();
        variables.put("uid", "asdfadsfasfd2323");
        variables.put("name", "张三");
        params.put("variables", variables);

        JSONArray jsonArray = new JSONArray();
        JSONObject obj = new JSONObject();
        obj.put("role", "user");
        obj.put("content", "如何办理身份证");
        jsonArray.add(obj);
        params.put("messages", jsonArray);

        // 封装请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set(authHead, authValue);

        // headers.setBasicAuth("Authorization","fastgpt-jZqZqjWQOic82RbTFdzAu94ddX0YL0ZWfBUtYAcVtewIkXe0yUfH");
        // accept 一定要设置为 TEXT_EVENT_STREAM
        headers.setAccept(Collections.singletonList(MediaType.TEXT_EVENT_STREAM));

        Flux<String> eventStream = webClient
                .post()
                .uri("/api/v1/chat/completions")
                .accept(MediaType.valueOf("text/event-stream;charset=UTF-8")) // 一定要设置
                .headers(httpHeaders -> httpHeaders.addAll(headers))
                .bodyValue(params.toJSONString())
                .retrieve()
                .bodyToFlux(String.class);

        eventStream.subscribe(
                data -> { // data 有什么key，value。具体看你对接agent的文档
                    log.info("data:{}", data);
                    try {
                        JSONObject bodyJson = JSONObject.parseObject(data);

                        JSONArray choices = bodyJson.getJSONArray("choices");
                        if (choices != null && choices.size() > 0) {
                            JSONObject jsonObject = choices.getJSONObject(0);
                            JSONObject delta = jsonObject.getJSONObject("delta");
                            String role = delta.getString("role");
                            String content = delta.getString("content");

                            String finish_reason = jsonObject.getString("finish_reason");

                        }
                        sseEmitter.send(bodyJson.toJSONString());

                        // 事件类型
                   /*     String event = bodyJson.getString("event");
                        // agent回答
                        String answer = bodyJson.getJSONObject("data").getString("answer");

                        if ("message".equals(event)) {
                            // 中间一段一段的消息
                            sseEmitter.send(answer);
                        } else if ("end".equals(event)) {
                            // 最后会全部返回
                            sseEmitter.send(answer);
                        }
*/
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                },
                error -> {
                    sseEmitter.completeWithError(error);
                    log.error("报错了:{}", error.getMessage(), error);
                },
                sseEmitter::complete
        );

        return eventStream;

        // 封装参数
/*        JSONObject params = new JSONObject();
        params.put("question", question);*/


        //todo
       /* Flux<String> response = webClient.post()
                .uri("/chat/completions")//请求uri
                .header("Authorization", "Bearer fastgpt-bfjg4AUxE2ocCUXXeT91proKcnc0t86y9mmPBraOp8waDnPZpQMrw")//设置成自己的key，获得key的方式可以在下文查看
                .header(HttpHeaders.ACCEPT, MediaType.TEXT_EVENT_STREAM_VALUE)//设置流式响应
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(paramJson))
                .retrieve()
                .bodyToFlux(String.class)
                .flatMap(res->{
                    if (StrUtil.equals("[DONE]",res)){//[DONE]是消息结束标识
                        return Flux.empty();
                    }
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        //System.out.println(res);
                        JsonNode jsonNode = objectMapper.readTree(res);
                        Answer aiAnswer = objectMapper.treeToValue(jsonNode, Answer.class);
                        List<Choices> choicesList = aiAnswer.getChoices();
                        Choices choices = choicesList.get(0);
                        Delta delta = choices.getDelta();
                        String json = objectMapper.writeValueAsString(delta);
                        System.out.println(json);
                        return Flux.just(json);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }

                    return Flux.empty();
                });
*/
        //转换请求包

        //return null;
    }
}