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.bo.MdmAppVersionBO;
import com.skr.mdm.bean.so.app.AppPushSO;
import com.skr.mdm.dao.MdmAppPushDao;
import com.skr.mdm.dao.MdmAppPushUserDao;
import com.skr.mdm.dao.MdmStrategyDeptDao;
import com.skr.mdm.entity.MdmAppPushDO;
import com.skr.mdm.entity.MdmAppPushUserDO;
import com.skr.mdm.entity.MdmStrategyDeptDO;
import com.skr.mdm.enums.AppPushCmdEnum;
import com.skr.mdm.enums.IssuedTypeEnum;
import com.skr.mdm.enums.StrategyDeptTypeEnum;
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.BeanUtils;
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 2023-01-10 17:37
 */
@Component
@Slf4j
public class GlobalAppPushObserver implements ApplicationListener<UserActiveEvent> {

    @Autowired
    private MdmAppPushDao appPushDao;
    @Autowired
    private MdmAppPushUserDao appPushUserDao;
    @Autowired
    private IssuedUserHandler issuedUserHandler;
    @Autowired
    private MdmStrategyDeptDao strategyDeptDao;

    @Override
    public void onApplicationEvent(UserActiveEvent event) {
        try {
            // 获取公司下所有的的全局策略
            List<MdmAppPushDO> appPushDOList = getGlobalAppPushDOList(event);
            if (CollectionUtils.isNotEmpty(appPushDOList)) {
                List<MdmAppPushUserDO> appPushUserDOList = Lists.newArrayListWithCapacity(appPushDOList.size());
                List<AppPushSO> appPushSOList = Lists.newArrayListWithCapacity(appPushDOList.size());
                for (MdmAppPushDO appPushDO : appPushDOList) {
                    MdmAppVersionBO appVersionBO = appPushDao.getMdmAppVersionBO(appPushDO.getId());
                    if (appVersionBO == null) {
                        continue;
                    }
                    Integer pushType = appPushDO.getPushType();
                    MdmAppPushUserDO appPushUserDO = getMdmAppPushUserDO(event, appPushDO, pushType);
                    // 查重
                    Long counted = new LambdaQueryChainWrapper<>(appPushUserDao)
                            .eq(MdmAppPushUserDO::getAppPushId, appPushUserDO.getAppPushId())
                            .eq(MdmAppPushUserDO::getEquipmentId, event.getEquipmentId())
                            .count();
                    if (counted > 0) {
                        continue;
                    }
                    // 未到推送时间只保存不下发
                    if (appPushDO.getPushTime().after(new Date())) {
                        // 如果是按需推送则推送类型不变
                        if (pushType.equals(1)) {
                            pushType = 2;
                        }
                        appPushUserDO.setPushType(pushType);
                        appPushUserDO.setState(StrategyEquipmentStateEnum.WAIT_ISSUED.getState());
                        appPushUserDO.setPushTime(appPushDO.getPushTime());
                        appPushUserDOList.add(appPushUserDO);
                        continue;
                    }
                    appPushUserDOList.add(appPushUserDO);
                    appPushSOList.add(getAppPushSO(appPushDO, appVersionBO, pushType));
                }
                // 保存
                if (CollectionUtils.isNotEmpty(appPushUserDOList)) {
                    appPushUserDao.insertBatch(appPushUserDOList);
                }
                // 下发
                if (CollectionUtils.isNotEmpty(appPushSOList)) {
                    issuedUserHandler.issuedUser(ListUtil.toList(event.getEquipmentId()), event.getCompanyId(),
                            AppPushCmdEnum.ISSUED_APP_PUSH.getCmd(), JSONUtil.toJsonStr(appPushSOList));
                }
            }
        } catch (Exception e) {
            log.error("设备激活全局应用推送下发异常：" + event.getEquipmentId(), e);
        }
    }

    private List<MdmAppPushDO> getGlobalAppPushDOList(UserActiveEvent event) {
        List<MdmAppPushDO> appPushDOList = new LambdaQueryChainWrapper<>(appPushDao)
                .eq(MdmAppPushDO::getGlobalType, IssuedTypeEnum.GLOBAL.getIssuedType())
                .eq(MdmAppPushDO::getCompanyId, event.getCompanyId())
                .list();
        // 获取用户的部门全局策略
        List<MdmStrategyDeptDO> strategyDeptDOList = new LambdaQueryChainWrapper<>(strategyDeptDao)
                .eq(MdmStrategyDeptDO::getDepartmentId, event.getDepartmentId())
                .eq(MdmStrategyDeptDO::getStrategyType, StrategyDeptTypeEnum.APP_PUSH.getStrategyType())
                .list();
        // 合并全局策略
        if (CollectionUtils.isNotEmpty(strategyDeptDOList)) {
            List<Integer> appPushIdList = strategyDeptDOList.stream().map(MdmStrategyDeptDO::getStrategyId).collect(Collectors.toList());
            List<MdmAppPushDO> appPushDOS = appPushDao.selectBatchIds(appPushIdList);
            if (CollectionUtils.isNotEmpty(appPushDOList)) {
                appPushDOList.addAll(appPushDOS);
            } else {
                appPushDOList = appPushDOS;
            }
        }
        return appPushDOList;
    }

    private MdmAppPushUserDO getMdmAppPushUserDO(UserActiveEvent event, MdmAppPushDO appPushDO, Integer pushType) {
        return MdmAppPushUserDO.builder()
                .appPushId(appPushDO.getId())
                .equipmentId(event.getEquipmentId())
                .state(StrategyEquipmentStateEnum.ISSUING.getState())
                .pushType(pushType)
                .pushTime(new Date())
                .isShortcutIcon(appPushDO.getIsShortcutIcon())
                .isSafeSpace(appPushDO.getIsSafeSpace())
                .isOnlyWifi(appPushDO.getIsOnlyWifi())
                .pauseStatus(appPushDO.getIsPause())
                .build();
    }

    private AppPushSO getAppPushSO(MdmAppPushDO appPushDO, MdmAppVersionBO appVersionBO, Integer pushType) {
        AppPushSO appPushSO = new AppPushSO();
        appPushSO.setId(appPushDO.getId());
        appPushSO.setPushType(pushType);
        appPushSO.setSendTime(new Date());
        appPushSO.setIsOnlyWifi(appPushDO.getIsOnlyWifi());
        appPushSO.setIsSafeSpace(appPushDO.getIsSafeSpace());
        appPushSO.setIsShortcutIcon(appPushDO.getIsShortcutIcon());
        BeanUtils.copyProperties(appVersionBO, appPushSO);
        return appPushSO;
    }

}
