package com.wecloud.im.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.wecloud.dispatch.annotation.ActionMapping;
import com.wecloud.dispatch.common.BaseRequest;
import com.wecloud.dispatch.extend.ActionRequest;
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.executor.SendMsgThreadPool;
import com.wecloud.im.friend.entity.ImFriend;
import com.wecloud.im.friend.service.ImFriendService;
import com.wecloud.im.mq.MqSender;
import com.wecloud.im.param.ChatContentVo;
import com.wecloud.im.param.ImClientSimpleDto;
import com.wecloud.im.param.ImConversationQueryVo;
import com.wecloud.im.param.MsgVo;
import com.wecloud.im.sdk.enums.ChatTypeEnum;
import com.wecloud.im.sdk.enums.FriendStateEnum;
import com.wecloud.im.sdk.enums.GroupRoleEnum;
import com.wecloud.im.sdk.enums.MutedEnum;
import com.wecloud.im.service.EhcacheService;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientBlacklistService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.ws.enums.MsgTypeEnum;
import com.wecloud.im.ws.enums.WsResponseCmdEnum;
import com.wecloud.im.ws.model.WsResponse;
import com.wecloud.im.ws.model.request.PushVO;
import com.wecloud.im.ws.sender.ChannelSender;
import com.wecloud.pushserver.client.model.constant.MqConstant;
import com.wecloud.pushserver.client.model.dto.PushDTO;
import com.wecloud.utils.JsonUtils;
import com.wecloud.utils.SnowflakeUtil;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.netty.channel.Channel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description 普通聊天
 * @Author lixiaozhong
 * @Date 2022-01-27
 */
@Slf4j
@Component
@ActionMapping(value = "/chat")
@Api(value = "ws-普通聊天", tags = {"ws-普通聊天"})
public class NormalChatAction {

    @Autowired
    private ImApplicationService imApplicationService;
    @Autowired
    private ImConversationMembersService imConversationMembersService;
    @Autowired
    private ImMessageService imMessageService;
    @Autowired
    private ChannelSender channelSender;
    @Autowired
    private ImClientBlacklistService imClientBlacklistService;
    @Autowired
    private ImInboxService imInboxService;
    @Autowired
    private MqSender mqSender;
    @Autowired
    private ImFriendService friendService;
    @Resource
    private EhcacheService ehcacheService;

    @ActionMapping("/normal/send")
    @ApiOperation("普通消息发送")
    public void sendMsg(ActionRequest request, ChatContentVo data, String reqId) {
        ImConversationQueryVo conversation = ehcacheService.getEhCacheConversation(data.getToConversation());
        if (conversation == null) {
            log.warn("会reqId: {} ,会话id: {}db中不存在", reqId, data.getToConversation());
            return;
        }
        // 查询发送者client
        ImClient imClientSender = ehcacheService.getEhCacheClient(request.getSenderClientId());
        if (imClientSender == null) {
            log.warn("根据senderClientId: {} 查找不到 imClientSender！", request.getSenderClientId());
            return;
        }
        // 查询imApplication
        ImApplication imApplication = imApplicationService.getCacheById(imClientSender.getFkAppid());


        // 给所有人（在线+离线）遍历发送
        // 先查询该会话所有成员
        List<ImConversationMembers> membersList = ehcacheService.getEhCacheMember("member"+conversation.getId(), conversation.getId());
        if (membersList.isEmpty()) {
            log.info("查询会话所有成员返回空，会话ID: {}", data.getToConversation());
            WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
            ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_BE_DISBAND);
            responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
            responseModel.setCode(result.getCode());
            responseModel.setMsg(result.getMessage());
            responseModel.setReqId(reqId);
            channelSender.sendMsgLocal((NioSocketChannel) request.getSenderChannel(), responseModel);
            return;
        }
        Map<Long, ImConversationMembers> memberMap = membersList.stream().collect(Collectors.toMap(ImConversationMembers::getFkClientId, member -> member));

        // 判断为单聊 只能用成员数量来判断，不可用枚举，还需考虑系统消息，临时消息等
        if (membersList.size() == 2) {
            // 判断是否被拉黑逻辑
            if (black(reqId, imClientSender, membersList, request.getSenderChannel())) {
                return;
            }

            if (!friend(reqId, imClientSender, data.getToConversation(), membersList, request.getSenderChannel())) {
                return;
            }
        }
        if (ChatTypeEnum.NORMAL_GROUP.getCode().equals(conversation.getChatType())) {
            if (beKickOut(reqId, imClientSender, membersList, request.getSenderChannel())) {
                return;
            }
            if (muted(conversation, reqId, imClientSender, memberMap, request.getSenderChannel())) {
                return;
            }
            if (baned(conversation, reqId, request.getSenderChannel())) {
                return;
            }
        }
        // 消息内容校验
        if (!checkMsg(imClientSender, conversation, reqId, data, request.getSenderChannel(), memberMap)) {
            return;
        }
        ImMessageOnlineSend imMessageOnlineSend = assembleImMessageOnlineSend(data, imClientSender, imApplication.getId());

        // 入库 保存收件箱
        batchSaveInbox(imApplication, imClientSender, conversation, imMessageOnlineSend.getMsgId(), membersList);
        // 入库成功后 判断是否是临时会话 如果是，双方会话display状态是否是1(显示)，如果不是，需要修改为是
        if (ChatTypeEnum.TEMP.getCode().equals(conversation.getChatType())) {
            // 木有只有私聊一种临时会话类型
            List<ImConversationMembers> tempMemberToUpdate = Lists.newArrayList();
            for (ImConversationMembers members : membersList) {
                if (members.getDisplayStatus() == 0) {
                    members.setDisplayStatus(1);
                    tempMemberToUpdate.add(members);
                }
            }
            if (CollectionUtils.isNotEmpty(tempMemberToUpdate)) {
                imConversationMembersService.updateBatchById(tempMemberToUpdate);
            }
        }
//        final Boolean isPush = ehcacheService.getIsPush("push" + conversation.getId());
        final Boolean isPush = Boolean.TRUE;
        // 多线程处理消息下发
        for (ImConversationMembers member : membersList) {
            if (member.getFkClientId().equals(imClientSender.getId())) {
                // 不给自己发
                continue;
            }
            SendMsgThreadPool.SEND_MSG_THREAD_POOL_EXECUTOR.execute(() -> {
                this.sendMsgToMember(imApplication, member, imMessageOnlineSend, data.getPush(), isPush);
            });
        }

        // 响应发送方消息id等信息
        response(reqId, imMessageOnlineSend.getMsgId(), request.getSenderChannel());
    }

    private void sendMsgToMember(ImApplication imApplication, ImConversationMembers member, ImMessageOnlineSend imMessageOnlineSend, PushVO push, Boolean isPush) {
        // 在线用户直接发消息

        Boolean sendSuccess = sendMsgForOnline(member.getFkClientId(), imMessageOnlineSend);
        if (isPush && !sendSuccess && !member.getDoNotDisturb()) {
            // 异步推送系统通知消息 5分钟内推一次消息
            PushDTO pushDTO = mqSender.buildPushDto(push, member.getFkClientId(), member.getClientId(), imApplication);
            if (pushDTO != null) {
                mqSender.orderSend(MqConstant.Topic.IM_ORDER_MSG_TOPIC, MqConstant.Tag.IM_ORDER_MSG_TAG, pushDTO);
            }
        }
    }

    /**
     * 发送消息给在线客户
     *
     * @param receiverClientId
     * @param imMessageOnlineSend
     */
    private Boolean sendMsgForOnline(Long receiverClientId, ImMessageOnlineSend imMessageOnlineSend) {
        //  封装要推给接收方的消息
        WsResponse<ImMessageOnlineSend> responseModel = new WsResponse<>();
        responseModel.setCmd(WsResponseCmdEnum.ONLINE_MSG.getCmdCode());
        ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
        responseModel.setCode(result.getCode());
        responseModel.setMsg(result.getMessage());
        responseModel.setData(imMessageOnlineSend);
        responseModel.setReqId(null);
        return channelSender.sendMsg(responseModel, receiverClientId);
    }

    /**
     * 拼装发送消息体
     *
     * @param data
     * @param imClientSender
     * @param appId
     * @return
     */
    private ImMessageOnlineSend assembleImMessageOnlineSend(ChatContentVo data, ImClient imClientSender, Long appId) {
        // 入库  保存消息至消息表
        ImClientSimpleDto client = new ImClientSimpleDto().setId(imClientSender.getId()).setFkAppid(appId);
        ImMessage imMessage = imMessageService.saveImMessage(client, data);

        // 封装响应的实体
        ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
        imMessageOnlineSend.setMsgId(imMessage.getId());
        imMessageOnlineSend.setSender(imClientSender.getClientId());
        Map<String, Object> content = JsonUtils.beanCopyDeep(data, Map.class);
        //action的属性无需要返回
        content.remove(BaseRequest.ACTION);
        imMessageOnlineSend.setContent(content);
        imMessageOnlineSend.setConversationId(data.getToConversation());
        imMessageOnlineSend.setCreateTime(imMessage.getCreateTime());
        imMessageOnlineSend.setWithdrawTime(imMessage.getWithdrawTime());
        imMessageOnlineSend.setWithdraw(imMessage.getWithdraw());
        imMessageOnlineSend.setEvent(imMessage.getEvent());
        imMessageOnlineSend.setSystemFlag(imMessage.getSystemFlag());
        imMessageOnlineSend.setType(data.getType());
        imMessageOnlineSend.setAt(imMessage.getAt());
        return imMessageOnlineSend;
    }

    /**
     * 响应发送方消息id等信息
     *
     * @param reqId
     * @param messageId
     * @param channel
     */
    private void response(String reqId, long messageId, Channel channel) {
        WsResponse<MsgVo> responseModel = new WsResponse<>();
        ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
        responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
        responseModel.setCode(result.getCode());
        responseModel.setMsg(result.getMessage());
        responseModel.setData(new MsgVo(messageId));
        responseModel.setReqId(reqId);
        // 响应发送方
        channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
    }

    /**
     * 入库 保存收件箱
     *
     * @param imApplication
     * @param conversation
     * @param messageId
     * @param membersList
     */
    private void batchSaveInbox(ImApplication imApplication, ImClient clientSender, ImConversationQueryVo conversation, long messageId,
                                List<ImConversationMembers> membersList) {
        List<ImInbox> inboxes = Lists.newArrayList();
        for (ImConversationMembers member : membersList) {
            if (clientSender.getClientId().equals(member.getClientId())) {
                continue;
            }
            ImInbox imInbox = new ImInbox();
            imInbox.setId(SnowflakeUtil.getId());
            imInbox.setCreateTime(new Date());
            imInbox.setFkAppid(imApplication.getId());
            imInbox.setReceiver(member.getFkClientId());
            imInbox.setFkMsgId(messageId);
            imInbox.setReadMsgStatus(0);
            imInbox.setReceiverMsgStatus(0);
            imInbox.setFkConversationId(conversation.getId());
            inboxes.add(imInbox);
        }
        if (CollectionUtils.isNotEmpty(inboxes)) {
            imInboxService.saveBatch(inboxes);
        }
    }

    /**
     * 判断是否被拉黑
     *
     * @param reqId
     * @param imClientSender
     * @param membersList
     * @param channel
     * @return
     */
    private boolean black(String reqId, ImClient imClientSender, List<ImConversationMembers> membersList, Channel channel) {
        String meClientId = imClientSender.getClientId();
        String heClientId;
        if (membersList.get(0).getClientId() != null && membersList.get(0).getClientId().equals(meClientId)) {
            heClientId = membersList.get(1).getClientId();
        } else {
            heClientId = membersList.get(0).getClientId();
        }
        // 判断是否被拉黑
        boolean beBlack = imClientBlacklistService.isBeBlack(heClientId, meClientId);
        if (beBlack) {
            log.info("被对方拉黑了, meId={},heClientId={}", meClientId, heClientId);
            // 响应发送方
            WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
            ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_BE_BLACK);
            responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
            responseModel.setCode(result.getCode());
            responseModel.setMsg(result.getMessage());
            responseModel.setReqId(reqId);
            channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
            return true;
        }

        // 是否把对方拉黑
        boolean black = imClientBlacklistService.isBeBlack(meClientId, heClientId);
        if (black) {
            log.info("你把对方拉黑了, meId={},heClientId={}", meClientId, heClientId);
            // 响应发送方
            WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
            ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_TO_BLACK);
            responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
            responseModel.setCode(result.getCode());
            responseModel.setMsg(result.getMessage());
            responseModel.setReqId(reqId);
            channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
            return true;
        }
        return false;
    }

    /**
     * 好友判断
     *
     * @param
     * @Author luozh
     * @Date 2022年05月18日 07:28:34
     * @Return
     */
    private boolean friend(String reqId, ImClient imClientSender, Long conversationId,
                           List<ImConversationMembers> membersList, Channel channel) {
        String meClientId = imClientSender.getClientId();

        String heClientId;
        Long heFkClientId;
        if (membersList.get(0).getClientId() != null && membersList.get(0).getClientId().equals(meClientId)) {
            heClientId = membersList.get(1).getClientId();
            heFkClientId = membersList.get(1).getFkClientId();
        } else {
            heClientId = membersList.get(0).getClientId();
            heFkClientId = membersList.get(0).getFkClientId();
        }

        ImClient imClientReceiver = ehcacheService.getEhCacheClient(heFkClientId);
        ImFriend my = friendService.getByKey(meClientId, heClientId);
        ImFriend friend = friendService.getByKey(heClientId, meClientId);

        // 获取拓展参数
        String senderAttributesStr = imClientSender.getAttributes();
        String receiverAttributesStr = imClientReceiver.getAttributes();

        JSONObject senderAttributes = new JSONObject();
        JSONObject receiverAttributes = new JSONObject();

        if (StringUtils.isNotBlank(senderAttributesStr)) {
            try {
                senderAttributes = JSONObject.parseObject(senderAttributesStr);
            } catch (Exception e) {
                // do nothing is ok
            }
        }
        if (StringUtils.isNotBlank(receiverAttributesStr)) {
            try {
                receiverAttributes = JSONObject.parseObject(receiverAttributesStr);
            } catch (Exception e) {
                // do nothing is ok
            }
        }
        // 判断是否其中一方是客服
        boolean senderIsServiceMan =
                Optional.ofNullable(senderAttributes.getBoolean("isServiceMan")).orElse(Boolean.FALSE);

        boolean receiverIsServiceMan =
                Optional.ofNullable(receiverAttributes.getBoolean("isServiceMan")).orElse(Boolean.FALSE);

        if (senderIsServiceMan || receiverIsServiceMan) {
            // 无需继续判断
            return true;
        }

        // 判定是陌生人的几种情况，没有好友申请 or 好友申请未通过 or 我/朋友拒绝了请求 or  我/朋友删除了好友关系
        Boolean isStranger =
                (my == null || friend == null)
                        || FriendStateEnum.UNSURE.getCode().equals(my.getState())
                        || FriendStateEnum.REJECT.getCode().equals(my.getState())
                        || FriendStateEnum.REJECT.getCode().equals(friend.getState())
                        || FriendStateEnum.DEL.getCode().equals(my.getState())
                        || FriendStateEnum.DEL.getCode().equals(friend.getState());

        if (isStranger) {
            // 陌生人限制
            boolean isVip = Optional.ofNullable(senderAttributes.getBoolean("isVip")).orElse(Boolean.FALSE);
            int sendCount =
                    imMessageService.count(Wrappers.<ImMessage>lambdaQuery().eq(ImMessage::getFkConversationId,
                            conversationId).eq(ImMessage::getSender, imClientSender.getId()).between(ImMessage::getCreateTime, getStartTime(), getEndTime()));
            if (!isVip) {
                // 非vip发送消息
                // 判断消息发送数量
                if (sendCount >= 3) {
                    WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
                    responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
                    responseModel.setCode(ApiCode.MSG_EXCEED_QUANTITY_LIMIT.getCode());
                    responseModel.setMsg("和对方还不是好友，只能发送三条消息");
                    responseModel.setReqId(reqId);
                    channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
                    return false;
                }
            } else {
                // vip发送
                // 判断消息发送数量
                if (sendCount >= 10) {
                    WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
                    responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
                    responseModel.setCode(ApiCode.EXCEED_VIP_QUANTITY_LIMIT.getCode());
                    responseModel.setMsg("和对方还不是好友，只能发送十条消息");
                    responseModel.setReqId(reqId);
                    channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
                    return false;
                }
            }
            return true;
        }
        // 非陌生人

        return true;
    }

    /**
     * 判断被踢出逻辑
     *
     * @param reqId
     * @param imClientSender
     * @param membersList
     * @param channel
     * @return
     */
    private boolean beKickOut(String reqId, ImClient imClientSender, List<ImConversationMembers> membersList, Channel channel) {
        Long senderId = imClientSender.getId();
        // 判断是否被踢出
        boolean beKickOut = membersList.stream().anyMatch(c -> c.getFkClientId().equals(imClientSender.getId()));
        if (!beKickOut) {
            log.info("发送方: {}, 已被踢出会话", senderId);
            // 响应发送方
            WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
            ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_BE_KICK_OUT);
            responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
            responseModel.setCode(result.getCode());
            responseModel.setMsg(result.getMessage());
            responseModel.setReqId(reqId);
            channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
            return true;
        }
        return false;
    }

    /**
     * 是否禁言判断
     *
     * @param conversation
     * @param reqId
     * @param imClientSender
     * @param channel
     * @return 是-ture 否-false
     */
    private boolean muted(ImConversationQueryVo conversation, String reqId, ImClient imClientSender, Map<Long, ImConversationMembers> memberMap, Channel channel) {
        Long senderId = imClientSender.getId();
        if (Lists.newArrayList(GroupRoleEnum.OWNER.getCode(), GroupRoleEnum.ADMIN.getCode())
                .contains(memberMap.get(senderId).getRole())) {
            // 当前操作人属于群主或管理人员 - 不做禁言处理
            return false;
        }
        boolean result = false;
        if (MutedEnum.YES.getCode().equals(conversation.getMuted())) {
            // 设置了群禁言 - 普通成员全部禁言
            result = true;
        }
        if (MutedEnum.NO.getCode().equals(conversation.getMuted())) {
            // 未设置群禁言 判断自己是否被禁言
            ImConversationMembers self = memberMap.get(senderId);
            if (self == null || MutedEnum.YES.getCode().equals(self.getMuted())) {
                result = true;
            }
        }
        if (result) {
            log.info("发送方: {}, 已被禁言", senderId);
            // 响应发送方
            WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
            ApiResult<Boolean> apiResult = ApiResult.result(ApiCode.IS_BE_MUTED);
            responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
            responseModel.setCode(apiResult.getCode());
            responseModel.setMsg(apiResult.getMessage());
            responseModel.setReqId(reqId);
            channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
        }
        return result;
    }

    /**
     * 是否封禁
     *
     * @param
     * @Author Shadow
     * @Date 2022年06月06日 01:42:33
     * @Return
     */
    private boolean baned(ImConversationQueryVo conversation, String reqId, Channel channel) {
        // 会话是否被封禁
        String attributes = conversation.getAttributes();
        if (StringUtils.isNotBlank(attributes)) {
            JSONObject jsonObject = JSONObject.parseObject(attributes);
            if (jsonObject == null || jsonObject.isEmpty() || !jsonObject.containsKey("baned")) {
                return false;
            }

            boolean baned = jsonObject.getBoolean("baned");
            if (baned) {
                // 响应发送方
                WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
                ApiResult<Boolean> apiResult = ApiResult.result(ApiCode.IS_BE_BANED);
                responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
                responseModel.setCode(apiResult.getCode());
                responseModel.setMsg(apiResult.getMessage());
                responseModel.setReqId(reqId);
                channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
                return true;
            }
            return false;
        } else {
            return false;
        }
    }

    /**
     * 是否禁止发送链接
     *
     * @Author luozh
     * @Date 2022年04月27日 04:39:04
     * @Return
     */
    private boolean checkMsg(ImClient sender, ImConversationQueryVo conversation, String reqId,
                             ChatContentVo data, Channel channel, Map<Long, ImConversationMembers> memberMap) {
        if (Lists.newArrayList(GroupRoleEnum.OWNER.getCode(), GroupRoleEnum.ADMIN.getCode())
                .contains(memberMap.get(sender.getId()).getRole())) {
            // 当前操作人属于群主或管理人员 - 不做处理
            return true;
        }

        String msgContent = data.getText();
        // 是否图片
        if (MsgTypeEnum.MEDIA_TYPE_IMAGE.getUriCode() == data.getType()) {

            if (conversation.getForbidSendPic()) {
                // 响应发送方
                WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
                ApiResult<Boolean> apiResult = ApiResult.result(ApiCode.IS_BE_FORBID_SEND_PIC);
                responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
                responseModel.setCode(apiResult.getCode());
                responseModel.setMsg(apiResult.getMessage());
                responseModel.setReqId(reqId);
                channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
                return false;
            }
        }

        if (MsgTypeEnum.MEDIA_TYPE_TEXT.getUriCode() == data.getType()) {
            // 判断是否开启禁止发送链接
            if (conversation.getForbidSendLink()) {
                String regex = "((ht|f)tp(s?)\\:\\/\\/)?[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*." +
                        "(html|htm|shtml|jsp|asp|php|com|cn|net|com.cn|org|vip)+(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\," +
                        "\\'\\/\\\\&%\\+\\$#_=]*)?";

                Pattern pat = Pattern.compile(regex);
                Matcher mat = pat.matcher(msgContent.trim());
                boolean result = mat.find();

                if (result) {
                    log.info("群: {}, 已被禁止发送链接", conversation.getName());
                    // 响应发送方
                    WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
                    ApiResult<Boolean> apiResult = ApiResult.result(ApiCode.IS_BE_FORBID_SEND_LINK);
                    responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
                    responseModel.setCode(apiResult.getCode());
                    responseModel.setMsg(apiResult.getMessage());
                    responseModel.setReqId(reqId);
                    channelSender.sendMsgLocal((NioSocketChannel) channel, responseModel);
                    return false;
                }
            }
        }


        return true;


    }

    private Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    private Date getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }


}
