package com.ym.im.service.impl;

import com.ym.im.entity.MsgBody;
import com.ym.im.entity.StaffSocketInfo;
import com.ym.im.entity.UserSocketInfo;
import com.ym.im.entity.enums.ResultStatus;
import com.ym.im.entity.model.IdModel;
import com.ym.im.handler.ChannelGroupHandler;
import com.ym.im.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static java.util.Map.Entry.comparingByValue;
import static java.util.stream.Collectors.toMap;

/**
 * @author: JJww
 * @Date:2019-05-22
 */
@Service
public class StaffServiceImpl implements StaffService {

    @Autowired
    private ChannelGroupHandler channelGroup;

    @Override
    public StaffSocketInfo getIdleStaff(Long merchantId, Long userId) {

        final Map<Long, StaffSocketInfo> socketInfoMap = channelGroup.STAFF_GROUP.get(merchantId);
        if (socketInfoMap == null) {
            return null;
        }
        final LinkedHashMap<Long, StaffSocketInfo> collect = socketInfoMap
                .entrySet()
                .stream()
                .sorted(comparingByValue(new Comparator<StaffSocketInfo>() {
                    @Override
                    public int compare(StaffSocketInfo o1, StaffSocketInfo o2) {
                        return Integer.valueOf(o1.getUserIds().size()).compareTo(Integer.valueOf(o2.getUserIds().size()));
                    }
                })).collect(toMap(e -> e.getKey(), e -> e.getValue(), (e1, e2) -> e2, LinkedHashMap::new));

        if (collect.size() == 0) {
            return null;
        }
        //客服和用户绑定
        StaffSocketInfo staffSocketInfo = collect.entrySet().iterator().next().getValue();
        staffSocketInfo.getUserIds().add(userId);
        //用户和客服绑定
        final UserSocketInfo userSocketInfo = channelGroup.USER_GROUP.get(userId);
        if (userSocketInfo != null) {
            final Long staffId = staffSocketInfo.getStaffId();
            userSocketInfo.setStaff(merchantId, staffId);
            //通知用户 新的客服
            userSocketInfo.writeAndFlush(new MsgBody<>().setCode(MsgBody.DISTRIBUTION_STAFF).setData(new IdModel().setStaffId(staffId).setUserId(userId)));
        }
        return staffSocketInfo;
    }


    @Override
    public MsgBody forward(IdModel idModel) {

        final Long userId = idModel.getUserId();
        final Long staffId = idModel.getStaffId();
        final Long merchantId = idModel.getMerchantId();
        final UserSocketInfo userSocketInfo = channelGroup.USER_GROUP.get(userId);
        final StaffSocketInfo staffSocketInfo = channelGroup.getMerchantStaff(staffId);
        if (staffSocketInfo == null || userSocketInfo == null) {
            return new MsgBody<>().setCode(MsgBody.BINDINGFAILURE).setMessage(ResultStatus.FORWARD_FAILURE.getMessage());
        }
        //移除原客服绑定
        channelGroup.getMerchantStaff(userSocketInfo.getStaffId(merchantId)).getUserIds().remove(userId);
        //设置新的客服
        staffSocketInfo.getUserIds().add(userId);
        userSocketInfo.setStaff(merchantId, staffId);
        final MsgBody<IdModel> msgBody = new MsgBody<IdModel>().setCode(MsgBody.DISTRIBUTION_STAFF).setData(idModel);
        //通知用户 新客服ID
        userSocketInfo.writeAndFlush(msgBody);
        //通知新客服
        staffSocketInfo.writeAndFlush(msgBody);
        return new MsgBody<>().setData(ResultStatus.SUCCESS.getCode());

    }

    @Override
    public MsgBody getMerchantStaffGroup(Long merchantId) {
        final List<StaffSocketInfo> staffs = new ArrayList<StaffSocketInfo>();
        channelGroup.STAFF_GROUP.get(merchantId).forEach((k, v) -> {
            staffs.add(v);
        });
        return new MsgBody<>().setCode(ResultStatus.SUCCESS.getCode()).setData(staffs);
    }


}
