package com.ym.im.mq;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.ym.im.entity.*;
import com.ym.im.entity.base.NettyConstant;
import com.ym.im.entity.model.IdModel;
import com.ym.im.handler.ChannelGroupHandler;
import com.ym.im.service.ChatRecordService;
import com.ym.im.service.ChatService;
import com.ym.im.service.SessionListService;
import com.ym.im.service.StaffService;
import com.ym.im.util.JsonUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Set;

import static com.ym.im.entity.ChatRecord.RECEIVE;

/**
 * @author: JJww
 * @Date:2019-05-30
 */
@Slf4j
@Component
public class Receiver {

    @Resource(name = "myRedisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private StaffService staffService;

    @Autowired
    private ChannelGroupHandler channelGroup;

    @Autowired
    private ChatService staffSingleChatServiceImpl;

    @Autowired
    private SessionListService sessiontListService;

    @Autowired
    private ChatRecordService chatRecordService;

    /**
     * 卓美亚商户ID 默认商户
     */
    private static final Long JUMEIRAH_ID = 1L;


    @RabbitListener(queues = "#{staffOfflineQueue.name}")
    public void offlineHandler(StaffSocketInfo staffSocketInfo) {

        final Long staffId = staffSocketInfo.getStaffId();
        //移除用户列表
        redisTemplate.delete(NettyConstant.STAFF_USERIDS_KEY + staffId);
        //客服真离线后 才转发
        if (channelGroup.getMerchantStaff(staffId) == null) {
            final Set userIds = staffSocketInfo.getUserIds();
            log.info("客服离线队列: " + "ID: " + "UserIds:" + userIds);
            userIds.forEach(uid -> {
                Long userId = Long.valueOf(uid.toString());
                //用户在线才重新分配和转发
                if (channelGroup.USER_GROUP.get(userId) != null) {
                    final StaffSocketInfo idleStaff = staffService.getIdleStaff(staffSocketInfo.getMerchantId(), userId);
                    if (idleStaff != null) {
                        idleStaff.writeAndFlush(new MsgBody<>().setCode(MsgBody.DISTRIBUTION_STAFF).setData(new IdModel().setStaffId(staffId).setUserId(userId)));
                    }
                }
            });
        }
    }


    /**
     * 订单相关处理
     *
     * @param json
     */
    @SneakyThrows
    @RabbitListener(queues = "#{orderQueue.name}")
    public void orderHandler(String json) {
        final Stroke stroke = JsonUtils.json2Obj(json, Stroke.class);
        log.info("订单信息: " + json);
        final Long mcId = stroke.getMcId();
        final Long userId = stroke.getUserId();
        final UserSocketInfo userSocketInfo = channelGroup.USER_GROUP.get(userId);
        if (userSocketInfo == null) {
            return;
        }
        final StaffSocketInfo staffSocketInfo = channelGroup.getMerchantStaff(userSocketInfo.getStaffId(stroke.getMcId())) == null ? staffService.getIdleStaff(mcId, userId) : channelGroup.getMerchantStaff(userSocketInfo.getStaffId(stroke.getMcId()));
        final MsgBody<ChatRecord> orderInfo = new MsgBody<ChatRecord>().setCode(MsgBody.ORDER).setData(new ChatRecord().setMsgInfo(json).setUserId(userId).setSendTime(new Date()).setMsgType(MsgBody.ORDER));
        if (staffSocketInfo == null) {//没有商户在线  逻辑待优化....完善
            log.info("当前客服不在线，请稍后等待!");
            final ChatRecord chatRecord = orderInfo.getData();
            chatRecord.setId(IdWorker.getId())
                    .setMerchantId(JUMEIRAH_ID)
                    .setSendReceive(RECEIVE)
                    .setCreateTime(new Date());
            chatRecordService.insertSelective(chatRecord);
            this.updateMerchantList(orderInfo);
            userSocketInfo.writeAndFlush(new MsgBody<>().setCode(MsgBody.MERCHANTS_OFFLINE));
            return;
        }
        orderInfo.getData().setMerchantId(staffSocketInfo.getMerchantId());
        staffSingleChatServiceImpl.save(staffSocketInfo.getStaffId(), orderInfo);
        this.updateMerchantList(orderInfo);
        staffSocketInfo.writeAndFlush(orderInfo);
        log.info("客服订单: " + "给客服(" + staffSocketInfo.getStaffId() + ")发送订单:" + json);

    }

    private void updateMerchantList(MsgBody<ChatRecord> msgBody) {
        final Date now = new Date();
        final ChatRecord chatRecord = msgBody.getData();
        final Long userId = chatRecord.getUserId();
        final Long merchantId = chatRecord.getMerchantId();
        final Set<Long> merchantList = channelGroup.USER_GROUP.get(userId).getSessionList();
        if (!merchantList.contains(merchantId)) {
            sessiontListService.save(new Session().setId(IdWorker.getId()).setUserId(userId).setMerchantId(merchantId).setCreateTime(now).setModifyTime(now));
            merchantList.add(merchantId);
        }
    }

}