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

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.jim.common.ImAio;
import org.jim.common.ImConst;
import org.jim.common.ImPacket;
import org.jim.common.packets.*;
import org.jim.server.command.CommandManager;
import org.jim.server.command.handler.ChatReqHandler;
import org.jim.server.command.handler.processor.CmdProcessor;
import org.jim.server.model.AutoReplyMessage;
import org.jim.server.model.ServiceAccountRoleDepartmentMiddle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.utils.lock.SetWithLock;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 自动消息处理器
 * @author Darren
 * @date 2020/2/11 10:07
 */
public class IMAutoMessageProcessor implements CmdProcessor, ImConst {

    private static Logger log = LoggerFactory.getLogger(IMAutoMessageProcessor.class);

    /**
     * 自动消息处理方法
     */
    public void handler(Group group) {
        log.info("AutoMessageProcessor : 执行自动消息处理方法...");
        String group_id = group.getGroup_id();
        String accountRoleDepartmentId = group.getServiceAccountRoleDepartmentId();
        ServiceAccountRoleDepartmentMiddle accountRoleDepartment
                = ServiceAccountRoleDepartmentMiddle.dao.findById(accountRoleDepartmentId);
        if( null != accountRoleDepartment ){
            String serviceAccountId = accountRoleDepartment.getStr("service_account_id");
            //获取 sw_auto_reply_message 中的数据
            List<AutoReplyMessage> list
                    = AutoReplyMessage.dao.find(
                    this.createSql(group.getCompanyId(), group.getDepartmentId(), serviceAccountId)
            );
            if(CollectionUtils.isNotEmpty(list)){
                //已经睡眠的时间
                int alreadySleepTime = 0;
                for(AutoReplyMessage message : list) {

                    //需要睡眠几秒 单位 s
                    Integer needSleepTime = message.getInt("sendtime");
                    needSleepTime -= alreadySleepTime;
                    alreadySleepTime += needSleepTime;
                    try {
                        TimeUnit.SECONDS.sleep(needSleepTime);
                    } catch (InterruptedException e) {
                        log.error("执行自动消息处理方法时,发生错误...");
                        e.printStackTrace();
                    }
                    //聊天数据包
                    ImPacket chatPacket = new ImPacket(
                            Command.COMMAND_CHAT_REQ
                            , createChatBody(message, accountRoleDepartmentId, group_id).toByte()
                    );
                    //设置同步序列号;
                    chatPacket.setSynSeq(0);
                    SetWithLock<ChannelContext> channelContexts = ImAio.getChannelContextsByUserId(accountRoleDepartmentId);
                    if( null != channelContexts && channelContexts.size() > 0 ){
                        //获取读锁
                        ReentrantReadWriteLock.ReadLock readLock = channelContexts.getLock().readLock();
                        //加锁
                        readLock.lock();
                        try {
                            Set<ChannelContext> channels= channelContexts.getObj();
                            for (ChannelContext channelContext : channels) {
                                ChatReqHandler chatReqHandler = CommandManager.getCommand(Command.COMMAND_CHAT_REQ, ChatReqHandler.class);
                                chatReqHandler.handler(chatPacket,channelContext);
                            }
                        } catch (Exception e) {
                            log.error(e.toString(),e);
                        } finally {
                            //解锁
                            readLock.unlock();
                        }
                    }

                }
            }
        }

    }

    /**
     * 创建聊天体
     * @param message
     * @param accountRoleDepartmentId
     * @param group_id
     * @return {@link {@link ChatBody}}
     * @author Darren
     * @date 2020/2/11 15:01
     */
    private ChatBody createChatBody(AutoReplyMessage message, String accountRoleDepartmentId, String group_id){
        Map<String, Object> map = new HashMap<>();
        //发送的消息类型 0:客户/游客发送的消息 1:客服发送的消息 2:客服自动发送的消息
        map.put("sendType",2);
        ChatBody chatBody = ChatBody.newBuilder().build();
        chatBody.setChatType(ChatType.CHAT_TYPE_PUBLIC.getNumber())
                .setContent(message.getStr("content"))
                .setFrom(accountRoleDepartmentId)
                .setGroup_id(group_id)
                .setMsgType(MsgType.MSG_TYPE_TEXT.getNumber())
                .setId(UUID.randomUUID().toString().replace("-",""));
        chatBody.setCreateTime(System.currentTimeMillis());
        chatBody.setExtras(new JSONObject(map));
        return chatBody;
    }

    /**
     * 创建查询sql
     * @param companyId
     * @param departmentId
     * @param serviceAccountId
     * @return {@link {@link String}}
     * @author Darren
     * @date 2020/2/11 15:01
     */
    private String createSql(String companyId, String departmentId, String serviceAccountId){
        StringBuilder sql = new StringBuilder();
        sql.append(" select * from sw_auto_reply_message where state = 1 and company_id = " + companyId)
                .append(" and department_id = " + departmentId)
                .append(" and service_account_id = " + serviceAccountId)
                .append(" order by sendtime asc ");
        return sql.toString();
    }

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

    @Override
    public String name() {
        return IM_AUTO_MESSAGE_PROCESSOR;
    }
}
