package com.skr.mdm.observer.global;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.google.common.collect.Lists;
import com.skr.mdm.bean.so.content.ContentInformSO;
import com.skr.mdm.dao.ContentInformDao;
import com.skr.mdm.dao.ContentInformUserDao;
import com.skr.mdm.entity.ContentInformDO;
import com.skr.mdm.entity.ContentInformUserDO;
import com.skr.mdm.enums.InformCmdEnum;
import com.skr.mdm.enums.IssuedTypeEnum;
import com.skr.mdm.enums.StrategyEquipmentStateEnum;
import com.skr.mdm.event.UserActiveEvent;
import com.skr.mdm.handle.IssuedUserHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户设备激活全局通知下发
 *
 * @author nfq
 * @date 2022/11/18 9:50
 */
@Component
@Slf4j
public class GlobalContentInformObserver implements ApplicationListener<UserActiveEvent> {

    @Autowired
    private ContentInformDao contentInformDao;
    @Autowired
    private ContentInformUserDao contentInformUserDao;
    @Autowired
    private IssuedUserHandler issuedUserHandler;

    @Override
    public void onApplicationEvent(UserActiveEvent event) {
        try {
            // 获取公司下所有的全局通知
            List<ContentInformDO> informDOList = new LambdaQueryChainWrapper<>(contentInformDao)
                    .ne(ContentInformDO::getGlobalType, IssuedTypeEnum.DEVICE.getIssuedType())
                    .eq(ContentInformDO::getCompanyId, event.getCompanyId())
                    .list();
            if (CollectionUtils.isNotEmpty(informDOList)) {
                // 筛选非当前设备所在部门的部门全局策略
                List<ContentInformDO> informDOS = informDOList.stream().filter(informDO ->
                                IssuedTypeEnum.DEPT_GLOBAL.getIssuedType().equals(informDO.getGlobalType()) &&
                                        !JSONUtil.toList(JSONUtil.parseArray(informDO.getDepartmentIds()), Integer.class)
                                                .contains(event.getDepartmentId()))
                        .collect(Collectors.toList());
                // 排除筛选出的部门策略
                if (CollectionUtils.isNotEmpty(informDOS)) {
                    informDOList.removeAll(informDOS);
                }
                if (CollectionUtils.isNotEmpty(informDOList)) {
                    List<ContentInformUserDO> contentInformUserDOList = Lists.newArrayListWithCapacity(informDOList.size());
                    List<ContentInformSO> cmdMessageSOList = Lists.newArrayListWithCapacity(informDOList.size());
                    List<ContentInformSO> cmdForceMessageSOList = Lists.newArrayListWithCapacity(informDOList.size());
                    for (ContentInformDO informDO : informDOList) {
                        // 查重
                        Long counted = new LambdaQueryChainWrapper<>(contentInformUserDao)
                                .eq(ContentInformUserDO::getInformId, informDO.getId())
                                .eq(ContentInformUserDO::getEquipmentId, event.getEquipmentId())
                                .count();
                        if (counted > 0) {
                            continue;
                        }
                        ContentInformUserDO contentInformUserDO = ContentInformUserDO.builder()
                                .equipmentId(event.getEquipmentId())
                                .companyId(event.getCompanyId())
                                .informId(informDO.getId())
                                .issuedTime(new Date())
                                .state(StrategyEquipmentStateEnum.ISSUING.getState())
                                .build();
                        // 未到推送时间只保存不下发
                        if (informDO.getExecuteTime() != null && informDO.getExecuteTime().after(new Date())) {
                            contentInformUserDO.setState(StrategyEquipmentStateEnum.WAIT_ISSUED.getState());
                            contentInformUserDOList.add(contentInformUserDO);
                            continue;
                        }
                        contentInformUserDOList.add(contentInformUserDO);
                        // 下发数据
                        ContentInformSO contentInformSO = new ContentInformSO();
                        contentInformSO.setActionId(informDO.getId());
                        contentInformSO.setMsg(informDO.getInformContent());
                        contentInformSO.setReadDelay(informDO.getReadDelay());
                        contentInformSO.setSendTime(new Date());
                        // 立即下发
                        if (informDO.getInformType() == 1) {
                            // 非强制
                            cmdMessageSOList.add(contentInformSO);
                        } else {
                            // 强制
                            cmdForceMessageSOList.add(contentInformSO);
                        }
                    }
                    contentInformUserDao.insertBatch(contentInformUserDOList);
                    // 下发
                    if (CollectionUtils.isNotEmpty(cmdMessageSOList)) {
                        issuedUserHandler.issuedUser(ListUtil.toList(event.getEquipmentId()), event.getCompanyId(),
                                InformCmdEnum.ISSUED_INFORM.getCmd(), JSONUtil.toJsonStr(cmdMessageSOList));
                    }
                    if (CollectionUtils.isNotEmpty(cmdForceMessageSOList)) {
                        issuedUserHandler.issuedUser(ListUtil.toList(event.getEquipmentId()), event.getCompanyId(),
                                InformCmdEnum.ISSUED_FORCE_INFORM.getCmd(), JSONUtil.toJsonStr(cmdForceMessageSOList));
                    }
                }

            }
        } catch (Exception e) {
            log.error("设备激活全局通知策略下发异常：" + event.getEquipmentId(), e);
        }
    }

}