package com.m2pool.pool.task;

import com.m2pool.common.core.utils.DateUtils;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.redis.service.RedisService;
import com.m2pool.pool.dto.*;
import com.m2pool.pool.enums.Pools;
import com.m2pool.pool.mapper.NoticeMapper;
import com.m2pool.pool.mapper.PoolMapper;
import com.m2pool.system.api.RemoteMailService;
import com.m2pool.system.api.entity.EmailEntity;
import com.m2pool.system.api.entity.EmailTemplateEntity;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 离线通知定时任务
 * @Date 2024/6/14 14:03
 * @Author dy
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "task.notice")
@EnableScheduling
public class OffLineNoticeTask {
    private boolean enable;

    @Autowired
    private PoolMapper poolMapper;

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private RemoteMailService mailService;

    @Autowired
    private RedisService redisService;


    //@Scheduled(cron = "0 0/2 * * * ?")
    //public void test(){
    //    Map<String, Object> map = new HashMap<>();
    //    map.put("user","yyb");
    //    map.put("coin","sha3x");
    //    map.put("offOnlineNumbers",24);
    //    EmailTemplateEntity test = new EmailTemplateEntity("1416014977@qq.com", "测试邮件", "emailoffline-en", map);
    //    mailService.sendHtmlMailMessage(test);
    //
    //    Map<String, Object> a = new HashMap<>();
    //    a.put("user","yyb");
    //    a.put("coin","sha3x");
    //    a.put("offOnlineNumbers",24);
    //    EmailTemplateEntity b = new EmailTemplateEntity("yaoyoubo89@gmail.com", "测试邮件", "emailoffline-en", a);
    //    mailService.sendHtmlMailMessage(b);
    //
    //    //Map<String, Object> code = new HashMap<>();
    //    //code.put("code","123456");
    //    //code.put("type","Login");
    //    //EmailTemplateEntity test1 = new EmailTemplateEntity("1416014977@qq.com", "登录", "emailCode-en", code);
    //    //mailService.sendHtmlMailMessage(test1);
    //}

    @Scheduled(cron = "20 15,45 * * * ?")
    public void NEXA30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            System.out.println("OffLineNoticeTask 定时任务已关闭，请在nacos修改配置");
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("nexa 预警定时任务执行时间:"+now);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.NEXA.getMhs() + "30m", nowStr);
        System.out.println("count:"+count);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.NEXA.getMhs() + "30m", nowStr);

            System.out.println("查询到离线矿机结果 "+list.size()+"条");
            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"nexa");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                // 获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.NEXA.getCoin());
                //System.out.println("查询到离线通知列表"+nmcList);
                //Map<String, List<String>> userEmails = nmcList.stream().collect(Collectors.groupingBy(NoticeMinerCoinListDto::getMiner, Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())));

                //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0 TODO 这里也没看到redis里面存储的位置
                Map<String, Long> map = redisService.getCacheMap("NEXA_USERS_OFFLINE");


                list.forEach(e -> {
                    long lastOff = 0;
                    if(StringUtils.isNotNull(map)){
                        lastOff = map.getOrDefault(e.getUser(),0L);
                    }
                    if(e.getOffline() > lastOff){
                        //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                        //仅当本次离线数大于上次离线数时才通知
                        //执行通知
                        List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                        if(StringUtils.isNotNull(emails)){

                            //emails为list，实际情况下，一个miner只会对应一个邮箱
                            emails.forEach(email ->{
                                System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.NEXA.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                mailService.sendHtmlMailMessage(entity);
                            });
                            redisService.setCacheMapValue("NEXA_USERS_OFFLINE",e.getUser(),e.getOffline());
                        }else {
                            System.out.println("该用户未添加离线通知 :"+userEmails.toString());

                        }

                    }else {
                        //不满足通知条件 不通知
                        System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                map.getOrDefault(e.getUser(),0L));
                    }


                });

                //TODO 离线警报数据入库或者修改

            }


        }else{
            //最新数据未入库暂不做处理
        }

    }

    @Scheduled(cron = "11 16,46 * * * ?")
    public void GRS30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("grs 30分钟定时任务执行时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.GRS.getMhs() + "30m", nowStr);

        System.out.println("二级表当前时间点数据条数："+count);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.GRS.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"grs");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.NEXA.getCoin());
                //System.out.println("查询到离线通知列表"+nmcList);
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("GRS_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.NEXA.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.GRS.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("GRS_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到nexa下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "12 17,47 * * * ?")
    public void MONA30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("mona 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.MONA.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.MONA.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"mona");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.MONA.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("MONA_USERS_OFFLINE");

                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff = map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.MONA.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.MONA.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("MONA_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到MONA下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "14 18,48 * * * ?")
    public void DGBO30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("DGBO 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.DGBO.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.DGBO.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"dgbo");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.DGBO.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("DGBO_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.DGBO.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.DGBO.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("DGBO_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到DGBO下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "16 19,49 * * * ?")
    public void DGBQ30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("DGBQ 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.DGBQ.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.DGBQ.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"dgbq");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.DGBQ.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("DGBQ_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.DGBQ.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.DGBQ.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("DGBQ_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到DGBO下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "18 20,50 * * * ?")
    public void DGBS30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("DGBS 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.DGBS.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.DGBS.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"dgbs");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.DGBS.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("DGBS_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.DGBS.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.DGBS.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("DGBS_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到DGBS下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "19 21,51 * * * ?")
    public void RXD30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("rxd 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.RXD.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.RXD.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"rxd");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.RXD.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("RXD_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.RXD.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.RXD.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("RXD_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到RXD下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "20 23,53 * * * ?")
    public void ALPH30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("alph 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.ALPH.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.ALPH.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"alph");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.ALPH.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("ALPH_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.ALPH.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.ALPH.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("ALPH_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到ALPH下相关的离线告警订阅信息");
                }

            }
        }

    }

    @Scheduled(cron = "21 25,55 * * * ?")
    public void ENX30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("enx 离线告警定时任务执行时间:"+now);
        System.out.println("格式化后的时间:"+nowStr);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.ENX.getMhs() + "30m", nowStr);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.ENX.getMhs() + "30m", nowStr);

            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"enx");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.ENX.getCoin());
                //
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0
                    Map<String, Long> map = redisService.getCacheMap("ENX_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.ENX.getName()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.ENX.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("ENX_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到ENX下相关的离线告警订阅信息");
                }

            }
        }

    }


    @Scheduled(cron = "25 26,46 * * * ?")
    public void MONERO30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            System.out.println("OffLineNoticeTask 定时任务已关闭，请在nacos修改配置");
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("MONERO 预警定时任务执行时间:"+now);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.MONERO.getMhs() + "30m", nowStr);
        System.out.println("count:"+count);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.MONERO.getMhs() + "30m", nowStr);

            System.out.println("查询到离线矿机结果 "+list.size()+"条");
            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"monero");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表 TODO 这里查询notice_info为空,notice_info 里面存的从哪里来？
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.MONERO.getCoin());
                //System.out.println("查询到离线通知列表"+nmcList);
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0 TODO 这里也没看到redis里面存储的位置
                    Map<String, Long> map = redisService.getCacheMap("MONERO_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.MONERO.getCoin()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.MONERO.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                                redisService.setCacheMapValue("MONERO_USERS_OFFLINE",e.getUser(),e.getOffline());
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到MONERO下相关的离线告警订阅信息");
                }

            }


        }else{
            //最新数据未入库暂不做处理
        }

    }

    @Scheduled(cron = "25 26,46 * * * ?")
    public void Sha3x30mDataToDB(){
        //String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
        if(!enable){
            return;
        }
        Date now = new Date();
        int minute = (now.getMinutes() / 30) * 30;
        now.setMinutes( minute);
        now.setSeconds(0);
        String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);

        System.out.println("SHA3X 预警定时任务执行时间:"+now);

        //检查二级表是否有当前时间数据
        int count = poolMapper.getLastDataTime(Pools.SHA3X.getMhs() + "30m", nowStr);
        System.out.println("count:"+count);

        if(count > 0) {
            //查询离线矿机数和离线矿机 按挖矿账户分
            List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.SHA3X.getMhs() + "30m", nowStr);

            System.out.println("查询到离线矿机结果 "+list.size()+"条");
            if(StringUtils.isNotEmpty(list)){
                //获取user 对应的邮箱
                List<NoticeMinerCoinListDto> nmcList = poolMapper.getEmailByUsers(list,"sha3x");
                Map<String, List<String>> userEmails = nmcList.stream().
                        collect(Collectors.groupingBy(
                                NoticeMinerCoinListDto::getMiner,
                                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                        ));

                //先获取通知列表 TODO 这里查询notice_info为空,notice_info 里面存的从哪里来？
                //List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.SHA3X.getCoin());
                //System.out.println("查询到离线通知列表"+nmcList);
                //Map<String, List<String>> userEmails = nmcList.stream().
                //        collect(Collectors.groupingBy(
                //                NoticeMinerCoinListDto::getMiner,
                //                Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
                //        ));


                if(StringUtils.isNotEmpty(userEmails)){
                    //获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0 TODO 这里也没看到redis里面存储的位置
                    Map<String, Long> map = redisService.getCacheMap("SHA3X_USERS_OFFLINE");
                    list.stream().forEach(e -> {
                        long lastOff = 0;
                        if(StringUtils.isNotNull(map)){
                            lastOff =map.getOrDefault(e.getUser(),0L);
                        }
                        if(e.getOffline() > lastOff){
                            //对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
                            //仅当本次离线数大于上次离线数时才通知
                            //执行通知
                            List<String> emails = userEmails.getOrDefault(e.getUser(), null);
                            if(StringUtils.isNotNull(emails)){
                                //String text = "您的"+Pools.SHA3X.getCoin()+"下挖矿账户: "+e.getUser()+"\n有" +
                                //        e.getOffline() + "台矿机离线!\n"+
                                //        "若您的矿机是因异常断开,请及时处理!";
                                emails.stream().forEach(email ->{
                                    System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
                                    Map<String, Object> text = new HashMap<>();
                                    text.put("user",e.getUser());
                                    text.put("coin",Pools.SHA3X.getCoin());
                                    text.put("offOnlineNumbers",e.getOffline());
                                    EmailTemplateEntity entity = new EmailTemplateEntity(email,"[M2Pool] Offline prompt for mining machine","emailoffline-en",text);
                                    mailService.sendHtmlMailMessage(entity);
                                });
                            }else {
                                System.out.println("该用户未添加离线通知 :"+userEmails.toString());
                            }
                            redisService.setCacheMapValue("SHA3X_USERS_OFFLINE",e.getUser(),e.getOffline());

                        }else {
                            //不满足通知条件 不通知
                            System.out.println("挖矿账户"+e.getUser()+"本次无需通知，本次离线为"+e.getOffline()+",上次离线数"+
                                    map.getOrDefault(e.getUser(),0L));
                        }
                    });
                }else {
                    System.out.println("未获取到SHA3X下相关的离线告警订阅信息");
                }

            }


        }else{
            //最新数据未入库暂不做处理
        }

    }


}
