package com.wecloud.im.ws.strategy.concrete;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.entity.ImInbox;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.entity.ImMessageOnlineSend;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientBlacklistService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.ws.annotation.ReceiveTypeAnnotation;
import com.wecloud.im.ws.enums.WsRequestCmdEnum;
import com.wecloud.im.ws.model.ResponseModel;
import com.wecloud.im.ws.model.request.ReceiveModel;
import com.wecloud.im.ws.sender.PushTask;
import com.wecloud.im.ws.service.MangerChannelService;
import com.wecloud.im.ws.service.WriteDataService;
import com.wecloud.im.ws.strategy.AbstractReceiveStrategy;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.shiro.util.SnowflakeUtil;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Description 处理app单聊消息
 */
@ReceiveTypeAnnotation(type = WsRequestCmdEnum.DATA)
@Service
@Slf4j
public class ImConcreteReceiveStrategy extends AbstractReceiveStrategy {

    @Autowired
    private ImClientBlacklistService imClientBlacklistService;

    @Autowired
    private WriteDataService writeDataService;

    @Autowired
    private ImMessageService imMessageService;

    @Autowired
    private ImInboxService imInboxService;

    @Autowired
    private ImApplicationService imApplicationService;

    @Autowired
    private ImConversationMembersService imConversationMembersService;

    @Autowired
    private ImClientService imClientService;

    @Autowired
    private PushTask pushTask;

    @Override
    public void process(ReceiveModel receiveModel, String language, ChannelHandlerContext ctx, String data) {

        String appKey = ctx.channel().attr(MangerChannelService.APP_KEY).get();
        String clientUniId = ctx.channel().attr(MangerChannelService.CLIENT_ID).get();

        // 查询imApplication
        ImApplication imApplication = imApplicationService.getOne(new QueryWrapper<ImApplication>().lambda()
                .eq(ImApplication::getAppKey, appKey));
        if (imApplication == null) {
            log.error("imApplication为空");
            return;
        }

        // 查询发送者client
        ImClient imClientSender = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
                .eq(ImClient::getFkAppid, imApplication.getId())
                .eq(ImClient::getClientId, clientUniId));
        if (imClientSender == null) {
            log.error("imClientSender为空");
            return;
        }

        JsonMapper jsonMapper = new JsonMapper();

        // 获取会话id
        Long toConversationId = Long.valueOf(receiveModel.getData().get("toConversation").toString());
        receiveModel.getData().remove("toConversation");

        // 生成消息id
        long messageId = SnowflakeUtil.getId();
        String content = null;

        try {
            content = jsonMapper.writeValueAsString(receiveModel.getData());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // 查询该会话所有成员
        List<ImConversationMembers> membersList = imConversationMembersService.list(
                new QueryWrapper<ImConversationMembers>().lambda()
                        .eq(ImConversationMembers::getFkConversationId, toConversationId)
                        .notIn(ImConversationMembers::getFkClientId, imClientSender.getId())
        );

        if (membersList.isEmpty()) {
            log.error("membersList为空,toConversationId:" + toConversationId);
            return;
        }

        // 判断为单聊
        if (membersList.size() == 1) {
            // 判断是否被拉黑
            boolean beBlack = imClientBlacklistService.isBeBlack(membersList.get(0).getFkClientId(), imClientSender.getId());
            if (beBlack) {
                log.debug("被对方拉黑了");

                // 响应发送方
                ResponseModel<HashMap<String, Long>> responseModel = new ResponseModel<>();
                ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_BE_BLACK);
                responseModel.setCmd(ResponseModel.RES);
                responseModel.setCode(result.getCode());
                responseModel.setMsg(result.getMessage());
                responseModel.setReqId(receiveModel.getReqId());
                writeDataService.write(responseModel, appKey, clientUniId);
                return;
            }

            // 是否把对方拉黑
            boolean black = imClientBlacklistService.isBeBlack(imClientSender.getId(), membersList.get(0).getFkClientId());
            if (black) {
                log.debug("你把对方拉黑了");
                // 响应发送方
                ResponseModel<HashMap<String, Long>> responseModel = new ResponseModel<>();
                ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_TO_BLACK);
                responseModel.setCmd(ResponseModel.RES);
                responseModel.setCode(result.getCode());
                responseModel.setMsg(result.getMessage());
                responseModel.setReqId(receiveModel.getReqId());
                writeDataService.write(responseModel, appKey, clientUniId);
                return;
            }
        }


        //  保存消息
        ImMessage imMessage = new ImMessage();
        imMessage.setId(messageId);
        imMessage.setCreateTime(new Date());
        imMessage.setFkAppid(imApplication.getId());
        imMessage.setSender(imClientSender.getId());
        imMessage.setContent(content);
        imMessage.setWithdraw(false);
        imMessage.setEvent(false);
        imMessage.setSystem(false);
        imMessage.setSendStatus(2);
        imMessage.setFkConversationId(toConversationId);
        imMessageService.save(imMessage);

        // 封装响应的实体
        ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
        BeanUtils.copyProperties(imMessage, imMessageOnlineSend);
        imMessageOnlineSend.setMsgId(imMessage.getId());
        imMessageOnlineSend.setSender(clientUniId);
        imMessageOnlineSend.setContent(receiveModel.getData());
        imMessageOnlineSend.setConversationId(toConversationId);

        // 遍历发送
        for (ImConversationMembers conversationMembers : membersList) {
            // 保存收件箱
            long imInboxId = SnowflakeUtil.getId();
            ImInbox imInbox = new ImInbox();
            imInbox.setId(imInboxId);
            imInbox.setCreateTime(new Date());
            imInbox.setFkAppid(imApplication.getId());
            imInbox.setReceiver(conversationMembers.getFkClientId());
            imInbox.setFkMsgId(messageId);
            imInbox.setReadMsgStatus(0);
            imInbox.setReceiverMsgStatus(0);
            imInbox.setFkConversationId(toConversationId);
            imInboxService.save(imInbox);

            // 查询接收方
            ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
                    .eq(ImClient::getFkAppid, imApplication.getId())
                    .eq(ImClient::getId, conversationMembers.getFkClientId()));
            if (imClientReceiver == null) {
                return;
            }

            //  向接收方推送
            ResponseModel<ImMessageOnlineSend> responseModel = new ResponseModel<>();
            responseModel.setCmd(ResponseModel.ONLINE_MSG);
            ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
            responseModel.setCode(result.getCode());
            responseModel.setMsg(result.getMessage());
            responseModel.setData(imMessageOnlineSend);
            responseModel.setReqId(null);
            writeDataService.write(responseModel, appKey, imClientReceiver.getClientId());

            // 异步推送系统通知消息
            pushTask.push(imClientReceiver, imClientSender, imMessage, imApplication);
        }

        // 响应发送方消息id等信息
        ResponseModel<HashMap<String, Long>> responseModel = new ResponseModel<>();
        ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
        responseModel.setCmd(ResponseModel.RES);
        responseModel.setCode(result.getCode());
        responseModel.setMsg(result.getMessage());

        HashMap<String, Long> stringHashMap = new HashMap<>();
        stringHashMap.put("msgId", messageId);

        responseModel.setData(stringHashMap);
        responseModel.setReqId(receiveModel.getReqId());
        writeDataService.write(responseModel, appKey, clientUniId);

    }


}
