package com.sonic.pigeon.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.netease.nim.server.sdk.core.Result;
import com.netease.nim.server.sdk.core.exception.YunxinSdkException;
import com.netease.nim.server.sdk.im.v2.YunxinV2ApiServices;
import com.netease.nim.server.sdk.im.v2.message.request.ModifyMessageRequestV2;
import com.netease.nim.server.sdk.im.v2.message.request.QueryMessageRequestV2;
import com.netease.nim.server.sdk.im.v2.message.request.QueryMessagesByPageRequestV2;
import com.netease.nim.server.sdk.im.v2.message.request.SendMessageRequestV2;
import com.netease.nim.server.sdk.im.v2.message.response.ModifyMessageResponseV2;
import com.netease.nim.server.sdk.im.v2.message.response.QueryMessageResponseV2;
import com.netease.nim.server.sdk.im.v2.message.response.QueryMessagesByPageResponseV2;
import com.netease.nim.server.sdk.im.v2.message.response.SendMessageResponseV2;
import com.sonic.pigeon.domain.bo.PushPayloadBo;
import com.sonic.pigeon.lib.bo.AttachBo;
import com.sonic.pigeon.lib.enums.ImUserTypeEnum;
import com.sonic.pigeon.lib.enums.MessageTypeEnum;
import com.sonic.pigeon.lib.input.HistoryMessageInput;
import com.sonic.pigeon.lib.input.SendAiCustomerMessageInput;
import com.sonic.pigeon.lib.input.SendAiTextMessageInput;
import com.sonic.pigeon.lib.output.HistoryMessageOutput;
import com.sonic.pigeon.service.ImMessageService;
import com.sonic.pigeon.utils.ImGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class ImMessageServiceImpl implements ImMessageService {

    @Autowired
    private YunxinV2ApiServices yunxinV2ApiServices;
    @Autowired
    private ImGenerator imGenerator;

    @Override
    public void sendAiToUserTextMessage(SendAiTextMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.r);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.u);
        sendTextMessage(fromAccountId, toAccountId, input);
    }

    @Override
    public void sendUserToAiTextMessage(SendAiTextMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.u);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.r);
        sendTextMessage(fromAccountId, toAccountId, input);
    }

    @Override
    public void sendAiToUserCustomerMessage(SendAiCustomerMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.r);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.u);
        sendCustomerMessage(fromAccountId, toAccountId, input);
    }

    @Override
    public void sendUserToAiCustomerMessage(SendAiCustomerMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.u);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.r);
        sendCustomerMessage(fromAccountId, toAccountId, input);
    }

    /**
     * 发送普通文本消息
     * @param fromAccountId
     * @param toAccountId
     * @param input
     */
    private void sendTextMessage(String fromAccountId, String toAccountId, SendAiTextMessageInput input) {
        SendMessageRequestV2 request = new SendMessageRequestV2();
        request.setConversationId(fromAccountId + "|1|" + toAccountId);
        SendMessageRequestV2.MessageBody messageBody = new SendMessageRequestV2.MessageBody();
        messageBody.setMessageType(MessageTypeEnum.TEXT.getCode());
        messageBody.setText(input.getContent());
        request.setMessage(messageBody);
        request.setExtension(input.getExtension());
        //设置消息推送
        SendMessageRequestV2.PushConfig pushConfig = new SendMessageRequestV2.PushConfig();
        pushConfig.setPushEnabled(true);
        pushConfig.setPushContent(input.getContent());
        pushConfig.setPushPayload(JSONObject.toJSONString(PushPayloadBo.builder().fromAccountId(fromAccountId).toAccountId(toAccountId).build()));
        request.setPushConfig(pushConfig);
        try {
            Result<SendMessageResponseV2> result  = yunxinV2ApiServices.getMessageService().sendMessage(request);
            if (result.isSuccess()) {
                // 获取成功
                log.info("===> sendAiTextMessage success, response : {}, traceId : {}", JSONObject.toJSONString(result.getResponse()), result.getTraceId());
            } else {
                // 获取失败
                log.info("===> sendAiTextMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> sendAiTextMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
    }

    /**
     * 发送自定义消息
     * @param input
     */
    private void sendCustomerMessage(String fromAccountId, String toAccountId, SendAiCustomerMessageInput input) {
        SendMessageRequestV2 request = new SendMessageRequestV2();
        request.setConversationId(fromAccountId + "|1|" + toAccountId);
        SendMessageRequestV2.MessageBody messageBody = new SendMessageRequestV2.MessageBody();
        messageBody.setMessageType(MessageTypeEnum.CUSTOM.getCode());
        messageBody.setText(input.getContent());
        //设置消息扩展字段
        messageBody.setAttachment(input.getAttachment() == null ? null : JSONObject.parseObject(input.getAttachment(), Map.class));
        //服务端扩展字段
        request.setExtension(input.getExtension());
        request.setMessage(messageBody);
        //设置消息推送
        SendMessageRequestV2.PushConfig pushConfig = new SendMessageRequestV2.PushConfig();
        pushConfig.setPushEnabled(true);
        pushConfig.setPushPayload(JSONObject.toJSONString(PushPayloadBo.builder().fromAccountId(fromAccountId).toAccountId(toAccountId).build()));
        request.setPushConfig(pushConfig);
        try {
            log.info("===> sendAiCustomerMessage request : {}", JSONObject.toJSONString(request));
            Result<SendMessageResponseV2> result  = yunxinV2ApiServices.getMessageService().sendMessage(request);
            if (result.isSuccess()) {
                // 获取成功
                log.info("===> sendAiCustomerMessage success, response : {}, traceId : {}", JSONObject.toJSONString(result.getResponse()), result.getTraceId());
            } else {
                // 获取失败
                log.info("===> sendAiCustomerMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> sendAiCustomerMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
    }

    @Override
    public void sendUserTextMessage(SendAiTextMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.u);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.r);

        SendMessageRequestV2 request = new SendMessageRequestV2();
        request.setConversationId(fromAccountId.toLowerCase() + "|1|" + toAccountId.toLowerCase());
        SendMessageRequestV2.MessageBody messageBody = new SendMessageRequestV2.MessageBody();
        messageBody.setMessageType(MessageTypeEnum.TEXT.getCode());
        messageBody.setText(input.getContent());
        request.setMessage(messageBody);
        //设置消息推送
        SendMessageRequestV2.PushConfig pushConfig = new SendMessageRequestV2.PushConfig();
        pushConfig.setPushEnabled(true);
        pushConfig.setPushContent(input.getContent());
        pushConfig.setPushPayload(JSONObject.toJSONString(PushPayloadBo.builder().fromAccountId(fromAccountId).toAccountId(toAccountId).build()));
        request.setPushConfig(pushConfig);
        try {
            log.info("===> sendAiTextMessage param : {}", JSONObject.toJSONString(request));
            Result<SendMessageResponseV2> result  = yunxinV2ApiServices.getMessageService().sendMessage(request);
            if (result.isSuccess()) {
                // 获取成功
                log.info("===> sendAiTextMessage success, response : {}, traceId : {}", JSONObject.toJSONString(result.getResponse()), result.getTraceId());
            } else {
                // 获取失败
                log.info("===> sendAiTextMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> sendAiTextMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
    }

    @Override
    public List<HistoryMessageOutput> getUserToAiHistoryMessage(HistoryMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.u);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.r);
        return getHistoryMessage(fromAccountId, toAccountId, input);
    }

    @Override
    public List<HistoryMessageOutput> getAiToUserHistoryMessage(HistoryMessageInput input) {
        String fromAccountId = imGenerator.genImAccountId(input.getFromUserId(), ImUserTypeEnum.r);
        String toAccountId = imGenerator.genImAccountId(input.getToUserId(), ImUserTypeEnum.u);
        return getHistoryMessage(fromAccountId, toAccountId, input);
    }

    /**
     * 获取历史消息
     * @param fromAccountId
     * @param toAccountId
     * @param input
     * @return
     */
    private List<HistoryMessageOutput> getHistoryMessage(String fromAccountId, String toAccountId, HistoryMessageInput input) {
        QueryMessagesByPageRequestV2 request = new QueryMessagesByPageRequestV2();
        request.setConversationId(fromAccountId + "|1|" + toAccountId);
        StringBuilder sb = new StringBuilder();
        sb.append(MessageTypeEnum.TEXT.getCode());
        sb.append(",");
        sb.append(MessageTypeEnum.CUSTOM.getCode());
        request.setMessageType(sb.toString());
        //最近一年的消息
        request.setBeginTime(input.getBeginTime() == null ? System.currentTimeMillis() - 31557600000L : input.getBeginTime());
        request.setEndTime(input.getEndTime() == null ? System.currentTimeMillis() : input.getEndTime());
        request.setLimit(input.getLimit() == null ? 100 : input.getLimit());
        request.setDescending(input.getDescending() == null ? true : input.getDescending());
        try {
            Result<QueryMessagesByPageResponseV2> result = yunxinV2ApiServices.getMessageService().queryMessagesByPage(request);
            if (result.isSuccess()) {
                QueryMessagesByPageResponseV2 response = result.getResponse();
                // 获取成功
                log.info("===> getHistoryMessage success, response : {}, traceId : {}", JSONObject.toJSONString(response), result.getTraceId());
                List<HistoryMessageOutput> historyMessageOutputs = new ArrayList<>();
                response.getItems().forEach(item -> {
                    HistoryMessageOutput output = new HistoryMessageOutput();
                    output.setFromUserId(imGenerator.decodeImAccountId(item.getSenderId()));
                    output.setToUserId(imGenerator.decodeImAccountId(item.getReceiverId()));
                    output.setContent(item.getText());
                    output.setMessageType(MessageTypeEnum.getByCode(item.getMessageType()));
                    output.setAttachment(item.getAttachment());
                    output.setExtension(item.getExtension());
                    output.setCreateTime(item.getCreateTime());
                    historyMessageOutputs.add(output);
                });
                if(input.getDescending() != null && !input.getDescending()) {
                    //顺序翻转，末尾的排到第一
                    Collections.reverse(historyMessageOutputs);
                }
                return historyMessageOutputs;
            } else {
                // 获取失败
                log.info("===> getHistoryMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> getHistoryMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
        return Collections.emptyList();
    }

    @Override
    public QueryMessageResponseV2 getAiSendMessage(Long aiId, Long userId, Long messageServerId) {
        String fromAccountId = imGenerator.genImAccountId(aiId, ImUserTypeEnum.r);
        String toAccountId = imGenerator.genImAccountId(userId, ImUserTypeEnum.u);

        QueryMessageRequestV2 request = new QueryMessageRequestV2();
        request.setConversationId(fromAccountId + "|1|" + toAccountId);
        request.setMessageServerId(messageServerId);
        try {
            Result<QueryMessageResponseV2> result = yunxinV2ApiServices.getMessageService().queryMessage(request);
            if (result.isSuccess()) {
                // 获取成功
                log.info("===> getAiSendMessage success, response : {}, traceId : {}", JSONObject.toJSONString(result.getResponse()), result.getTraceId());
            } else {
                // 获取失败
                log.info("===> getAiSendMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
            return result.getResponse();
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> getAiSendMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
        return null;
    }

    @Override
    public void updateAiSendCustomImageMessage(Long aiId, Long userId, Long messageServerId, AttachBo attachment) {
        // 查询消息
        QueryMessageResponseV2 queryMessageResponseV2 = getAiSendMessage(aiId, userId, messageServerId);
        if(queryMessageResponseV2 == null) {
            return;
        }
        // 更新消息
        try {
            String fromAccountId = imGenerator.genImAccountId(aiId, ImUserTypeEnum.r);
            ModifyMessageRequestV2 request = new ModifyMessageRequestV2();
            request.setOperator(fromAccountId);
            request.setType(1);
            ModifyMessageRequestV2.Message message = new ModifyMessageRequestV2.Message();
            message.setMessageServerId(queryMessageResponseV2.getMessageServerId());
            message.setReceiverId(queryMessageResponseV2.getReceiverId());
            message.setTime(queryMessageResponseV2.getCreateTime());
            message.setSenderId(queryMessageResponseV2.getSenderId());
            message.setMessageType(queryMessageResponseV2.getMessageType());
            message.setText(queryMessageResponseV2.getText());
            request.setMessage(message);
            //处理自定义字段
            Map<?, ?> attachmentMap = JSONObject.parseObject(JSONObject.toJSONString(attachment), Map.class);
            message.setAttachment(attachmentMap);
            Result<ModifyMessageResponseV2> result = yunxinV2ApiServices.getMessageService().modifyMessage(request);
            if (result.isSuccess()) {
                // 获取成功
                log.info("===> updateAiSendCustomImageMessage success, response : {}, traceId : {}", JSONObject.toJSONString(result.getResponse()), result.getTraceId());
            } else {
                // 获取失败
                log.info("===> updateAiSendCustomImageMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> updateAiSendCustomImageMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
    }

    @Override
    public void updateAiSendMessage(Long aiId, Long userId, Long messageServerId, Map<String, Object> extension) {
        // 查询消息
        QueryMessageResponseV2 queryMessageResponseV2 = getAiSendMessage(aiId, userId, messageServerId);
        if(queryMessageResponseV2 == null) {
            return;
        }
        // 更新消息
        try {
            String fromAccountId = imGenerator.genImAccountId(aiId, ImUserTypeEnum.r);
            ModifyMessageRequestV2 request = new ModifyMessageRequestV2();
            request.setOperator(fromAccountId);
            request.setType(1);
            ModifyMessageRequestV2.Message message = new ModifyMessageRequestV2.Message();
            message.setMessageServerId(queryMessageResponseV2.getMessageServerId());
            message.setReceiverId(queryMessageResponseV2.getReceiverId());
            message.setTime(queryMessageResponseV2.getCreateTime());
            message.setSenderId(queryMessageResponseV2.getSenderId());
            message.setMessageType(queryMessageResponseV2.getMessageType());
            message.setText(queryMessageResponseV2.getText());
            request.setMessage(message);
            //处理扩展字段
            String queryExtension = queryMessageResponseV2.getExtension();
            if(StringUtils.isNotEmpty(queryExtension)) {
                Map<String, Object> queryExtensionMap = JSONObject.parseObject(queryExtension, Map.class);
                queryExtensionMap.putAll(extension);
                request.setExtension(JSONObject.toJSONString(queryExtensionMap));
            } else {
                request.setExtension(JSONObject.toJSONString(extension));
            }
            Result<ModifyMessageResponseV2> result = yunxinV2ApiServices.getMessageService().modifyMessage(request);
            if (result.isSuccess()) {
                // 获取成功
                log.info("===> updateAiSendMessage success, response : {}, traceId : {}", JSONObject.toJSONString(result.getResponse()), result.getTraceId());
            } else {
                // 获取失败
                log.info("===> updateAiSendMessage fail, code : {}, msg : {}, traceId : {}", result.getCode(), result.getMsg(), result.getTraceId());
            }
        } catch (YunxinSdkException e) {
            // 超时等异常
            log.error("===> updateAiSendMessage error, endpoint : {}, traceId : {}", e.getContext().getEndpoint(), e.getTraceId());
        }
    }

}
