package com.skr.mdm.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.skr.mdm.bean.vo.WebSocketResultMessageVO;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dao.LogUserOnlineDao;
import com.skr.mdm.dao.SysSendMsgUserDao;
import com.skr.mdm.dto.LoginUserDTO;
import com.skr.mdm.entity.DeviceEquipmentDO;
import com.skr.mdm.entity.LogUserOnlineDO;
import com.skr.mdm.entity.SysSendMsgDO;
import com.skr.mdm.enums.EquipmentStateEnum;
import com.skr.mdm.result.ResponseResult;
import com.skr.mdm.service.ApplicationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * @author nfq
 * @date 2020/9/14 10:19
 */
@Slf4j
@Service
public class ApplicationServiceImpl implements ApplicationService {

    @Autowired
    private SysSendMsgUserDao sendMsgUserDao;
    @Autowired
    private DeviceEquipmentDao equipmentDao;
    @Autowired
    private LogUserOnlineDao logUserOnlineDao;

    @Override
    public ResponseResult heartbeat(LoginUserDTO loginUserDTO) {
        ReentrantLock lock = new ReentrantLock();
        lock.lock();
        try {
            // 更新心跳时间
            new LambdaUpdateChainWrapper<>(equipmentDao)
                    .set(DeviceEquipmentDO::getHeartbeatTime, new Date())
                    .eq(DeviceEquipmentDO::getId, loginUserDTO.getId())
                    .update();
            Integer equipmentState = equipmentDao.getEquipmentStateById(loginUserDTO.getId());
            if (EquipmentStateEnum.INACTIVATED.getState().equals(equipmentState) || EquipmentStateEnum.OFFLINE.getState().equals(equipmentState)) {
                // 添加上线日志
                LogUserOnlineDO logUserOnlineDO = LogUserOnlineDO.builder()
                        .equipmentId(loginUserDTO.getId())
                        .equipmentName(loginUserDTO.getEquipmentName())
                        .userName(loginUserDTO.getUserName())
                        .departmentName(loginUserDTO.getDepartmentName())
                        .logType(1)
                        .content("上线(http)")
                        .departmentId(loginUserDTO.getDepartmentId())
                        .companyId(loginUserDTO.getCompanyId())
                        .operateTime(new Date())
                        .build();
                logUserOnlineDao.insert(logUserOnlineDO);
                // 更新在线状态
                new LambdaUpdateChainWrapper<>(equipmentDao)
                        .set(DeviceEquipmentDO::getEquipmentState, EquipmentStateEnum.HTTP_ONLINE.getState())
                        .eq(DeviceEquipmentDO::getId, loginUserDTO.getId())
                        .update();
            }
        } finally {
            lock.unlock();
        }
        // 获取未下发成功的数据
        List<SysSendMsgDO> sendMsgDOList = sendMsgUserDao.listIssuedSendMsg(loginUserDTO.getId(), 1);
        List<WebSocketResultMessageVO> resultMessageVOList = new ArrayList<>(sendMsgDOList.size());
        if (CollectionUtils.isNotEmpty(sendMsgDOList)) {
            List<Long> idList = sendMsgDOList.stream().map(SysSendMsgDO::getId).collect(Collectors.toList());
            log.info("用户：{} 设备ID：{} 请求HeartBeat接口获取数据 消息ID：{}", loginUserDTO.getUsername(), loginUserDTO.getId(), JSONUtil.toJsonStr(idList));
            resultMessageVOList = sendMsgDOList.stream().map(sendMsgDO -> WebSocketResultMessageVO.builder()
                    .msgId(sendMsgDO.getId())
                    .type(sendMsgDO.getCmdType())
                    .data(sendMsgDO.getData())
                    .sendTime(sendMsgDO.getCreateTime().getTime())
                    .secretKey(sendMsgDO.getSecretKey())
                    .build()).collect(Collectors.toList());
        }
        return ResponseResult.success(resultMessageVOList);
    }
}
