package org.jim.server.command.handler.processor.chat;

import com.alibaba.fastjson.JSONObject;
import org.jim.common.ImAio;
import org.jim.common.ImConfig;
import org.jim.common.ImConst;
import org.jim.common.ImPacket;
import org.jim.common.message.MessageHelper;
import org.jim.common.packets.CancelMessageReqBody;
import org.jim.common.packets.ChatType;
import org.jim.common.packets.User;
import org.jim.common.utils.ChatKit;
import org.jim.server.command.CommandManager;
import org.jim.server.command.handler.processor.CmdProcessor;
import org.jim.server.enums.CancelMessageTypeEnum;
import org.jim.server.enums.VisitTypeEnum;
import org.jim.server.model.ConversationRecord;
import org.jim.server.util.CancelMessageKit;
import org.tio.core.ChannelContext;

import java.util.List;

/**
 * @author Darren
 * @date 2020/2/12 10:35
 */
public class IMCancelMessageProcessor implements CmdProcessor {

    protected ImConfig imConfig;

    /**
     * 修改redis中 和 mysql 中的 撤回消息状态
     * @param cancelMessageReqBody
     * @param channelContext
     * @return
     */
    public ImPacket handler(CancelMessageReqBody cancelMessageReqBody, ChannelContext channelContext){
        if(imConfig == null) {
            imConfig = CommandManager.getImConfig();
        }
        //判断 fromId 与 数据库中的fromId 是否一致
        String chatBodyId = cancelMessageReqBody.getId();
        ConversationRecord conversationRecord = ConversationRecord.dao
                .findFirst("select * from sw_conversation_record where chat_body_id = ? ", chatBodyId);
        if( null != conversationRecord ){
            String oldFromId;
            User user = ImAio.getUser(cancelMessageReqBody.getFrom());
            if(user != null){
                String visitType = user.getVisitType();
                if(VisitTypeEnum.CUSTOMER.getKey().equals(visitType)){
                    oldFromId = user.getExtras().getString("customerId");
                }else if(VisitTypeEnum.VISITOR.getKey().equals(visitType)){
                    // VISITOR 游客  发送的消息
                    oldFromId = user.getExtras().getString("visitorId");
                }else {
                    //SERVICEACCOUNT 客服  发送的消息
                    oldFromId = user.getExtras().getString("serviceAccountId");
                }
                if( oldFromId.equals(conversationRecord.getStr("from_id")) ){
                    //表示当前撤销的信息 是 当前人 发的消息 可以撤销
                    //1.修改 sw_conversation_record 数据中相关对应字段 is_recall 消息是否撤回 1:是 0:否
                    conversationRecord.set("is_recall", CancelMessageTypeEnum.CANCEL.getKey()).update();
                    //2. 对redis 对应数据 进行更改
                    if(ImConst.ON.equals(imConfig.getIsStore())){
                        //更改reids中 已经 持久化的 消息
                        if(ChatType.CHAT_TYPE_PUBLIC.getNumber() == cancelMessageReqBody.getChatType()){
                            removeGroupMessage(cancelMessageReqBody);
                        }
                    }
                    return CancelMessageKit.sendSuccessRespPacket(channelContext);
                }
                return CancelMessageKit.fromIdInCorrectRespPacket(channelContext);
            }
        }
        return null;
    }

    /**
     * 撤回消息 需要删除已经在redis中持久化的消息(撤回的消息)
     * @param cancelMessageReqBody
     */
    private void removeGroupMessage(CancelMessageReqBody cancelMessageReqBody) {
        MessageHelper messageHelper = imConfig.getMessageHelper();
        String group_id = cancelMessageReqBody.getGroup_id();
        messageHelper.removeCancelMessage(cancelMessageReqBody);
        List<String> userIds = messageHelper.getGroupUsers(group_id);
        //将群需要消息同步到所有的群成员
        for(String userId : userIds){
            boolean isOnline = false;
            if(ImConst.ON.equals(imConfig.getIsStore()) && ImConst.ON.equals(imConfig.getIsCluster())){
                isOnline = messageHelper.isOnline(userId);
            }else{
                isOnline = ChatKit.isOnline(userId,imConfig);
            }
            if(!isOnline){
                messageHelper.removeCancelMessageByOffOnlineUserId(userId, cancelMessageReqBody);
            }
        }
    }

    @Override
    public boolean isProtocol(ChannelContext channelContext) {
        return true;
    }

    @Override
    public String name() {
        return ImConst.IM_CANCEL_MESSAGE_PROCESSOR;
    }

}
