package com.tofly.scada.handle;

import cn.hutool.core.date.DateUtil;
import com.tofly.em.StatisticsTypeEnum;
import com.tofly.scada.service.ScadaService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@EnableScheduling   // 1.开启定时任务
@EnableAsync        // 2.开启多线程
@Slf4j
@Service
@AllArgsConstructor
public class ScheduledTask {

    private final ScadaService scadaService;
    private final ScadaHandler scadaHandler;

    /**
     *
     * 	每天3点同步设备指标信息
     */
    @Async
    @Scheduled(cron = "0 0 3 * * ? ")
    @SneakyThrows
    public  void originToScadaHistoryData(){
        scadaService.origDeviceAndIndex();
    }

    /**
     * 每小时同步今日缓存表按小时数据
     *
     */
    @Async
    @Scheduled(cron = "0 0 0/1 * * ? ")
    @SneakyThrows
    public void syncHourCacheToday(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (DateUtil.format(calendar.getTime(),"HH").equals("00")) {
            calendar.add(Calendar.DATE, -1);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date endTime = calendar.getTime();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date startTime = calendar.getTime();
        scadaHandler.syncTwentyFourHourData(startTime, endTime);
    }

    /**
     * 每天6点同步前五天缓存表按小时数据
     *
     */
    @Async
    @Scheduled(cron = "0 0 6 * * ? ")
    @SneakyThrows
    public void syncHourCacheLastWeek(){
        log.info("...........................同步前五天缓存表按小时数据开始...........................");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<Map<String, String>> dateList = new ArrayList<>();
        for (int i=0;i<5;i++) {
            calendar.add(Calendar.DATE, -1);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            Date endTime = calendar.getTime();
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Date startTime = calendar.getTime();
            Map<String, String> map = new HashMap<>();
            map.put("startTime", DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss"));
            map.put("endTime", DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss"));
            dateList.add(map);
        }
        dateList.forEach(date -> scadaHandler.syncTwentyFourHourData(DateUtil.parse(date.get("startTime"), "yyyy-MM-dd HH:mm:ss"),
                DateUtil.parse(date.get("endTime"), "yyyy-MM-dd HH:mm:ss")));
        log.info("...........................同步前五天缓存表按小时数据结束...........................");
    }

    /**
     * 每小时的30分同步今日缓存表按天数据
     *
     */
    @Async
    @Scheduled(cron = "0 30 0/1 * * ? ")
    @SneakyThrows
    public void syncDayCacheToday(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (DateUtil.format(calendar.getTime(),"HH").equals("00")) {
            calendar.add(Calendar.DATE, -1);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date endTime = calendar.getTime();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date startTime = calendar.getTime();
        scadaHandler.saveHistoryCode(DateUtil.parse(DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"),
                DateUtil.parse(DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"),
                StatisticsTypeEnum.ONE_DAY.getType());
    }

    /**
     * 每天7点同步前五天缓存表按天数据
     *
     */
    @Async
    @Scheduled(cron = "0 0 7 * * ? ")
    @SneakyThrows
    public void syncDayCacheLastWeek(){
        log.info("...........................同步前五天缓存表按天数据开始...........................");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<Map<String, String>> dateList = new ArrayList<>();
        for (int i=0;i<5;i++) {
            calendar.add(Calendar.DATE, -1);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            Date endTime = calendar.getTime();
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Date startTime = calendar.getTime();
            Map<String, String> map = new HashMap<>();
            map.put("startTime", DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss"));
            map.put("endTime", DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss"));
            dateList.add(map);
        }
        dateList.forEach(date -> scadaHandler.saveHistoryCode(DateUtil.parse(date.get("startTime"), "yyyy-MM-dd HH:mm:ss"),
                DateUtil.parse(date.get("endTime"), "yyyy-MM-dd HH:mm:ss"),
                StatisticsTypeEnum.ONE_DAY.getType()));
        log.info("...........................同步前五天缓存表按天数据结束...........................");
    }

    /**
     * 每天8:10同步缓存表按月数据
     *
     */
    @Async
    @Scheduled(cron = "0 10 8 * * ? ")
    @SneakyThrows
    public void syncMonthCache(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (DateUtil.format(calendar.getTime(),"dd").equals("01")) {
            calendar.add(Calendar.MONTH, -1);
        }
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date startTime = calendar.getTime();
        // 获取某月最大天数
        int lastDay;
        //2月的平年瑞年天数
        if(DateUtil.format(calendar.getTime(),"MM").equals("02")) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        Date endTime = calendar.getTime();
        String startDate = DateUtil.format(startTime,"yyyy-MM-dd") + " 00:00:00";
        String endDate = DateUtil.format(endTime,"yyyy-MM-dd") + " 23:59:59";
        scadaHandler.saveStatisticsCode(DateUtil.parse(startDate, "yyyy-MM-dd HH:mm:ss"),
                DateUtil.parse(endDate, "yyyy-MM-dd HH:mm:ss"),
                StatisticsTypeEnum.TWO_MONTH.getType());
    }

    /**
     * 每天11:40同步缓存表按年数据
     *
     */
    @Async
    @Scheduled(cron = "0 40 11 * * ? ")
    @SneakyThrows
    public void syncYearCache(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (DateUtil.format(calendar.getTime(),"MM").equals("01") && DateUtil.format(calendar.getTime(),"dd").equals("01")) {
            calendar.add(Calendar.YEAR, -1);
        }
        String startDate = DateUtil.format(calendar.getTime(),"yyyy") + "-01-01 00:00:00";
        String endDate = DateUtil.format(calendar.getTime(),"yyyy") + "-12-31 23:59:59";
        scadaHandler.saveStatisticsCode(DateUtil.parse(startDate, "yyyy-MM-dd HH:mm:ss"),
                DateUtil.parse(endDate, "yyyy-MM-dd HH:mm:ss"),
                StatisticsTypeEnum.THREE_YEAR.getType());
    }

    /**
     * 每小时同步今日净累计差值处理(5分钟求值)
     *
     */
    @Async
    @Scheduled(cron = "0 0 0/1 * * ? ")
    @SneakyThrows
    public void syncNetFlowDiffToday() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        if (DateUtil.format(calendar.getTime(),"HH").equals("00")) {
            calendar.add(Calendar.DATE, -1);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date endTime = calendar.getTime();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date startTime = calendar.getTime();
        scadaHandler.sendCumulativeFlowDifference(DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss"), DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 每天5点同步前五天累计差值处理(5分钟求值)
     *
     */
    @Async
    @Scheduled(cron = "0 0 5 * * ? ")
    @SneakyThrows
    public void syncNetFlowDiffLastWeek() {
        log.info("...........................同步前五天累计差值处理(5分钟求值)开始...........................");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        List<Map<String, Date>> dateList = new ArrayList<>();
        for (int i=0;i<5;i++) {
            calendar.add(Calendar.DATE, -1);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            Date endTime = calendar.getTime();
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Date startTime = calendar.getTime();
            Map<String, Date> map = new HashMap<>();
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            dateList.add(map);
        }
        dateList.forEach(date -> scadaHandler.sendCumulativeFlowDifference(DateUtil.format(date.get("startTime"), "yyyy-MM-dd HH:mm:ss"),
                DateUtil.format(date.get("endTime"), "yyyy-MM-dd HH:mm:ss")));
        log.info("...........................同步前五天累计差值处理(5分钟求值)结束...........................");
    }

    /**
     *
     * 	每小时20分自动同步汇中流量计历史数据
     */
    @Async
    @Scheduled(cron = "0 20 0/1 * * ? ")
    @SneakyThrows
    public void synHzFlowMeter(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calYesterday = Calendar.getInstance();
        calYesterday.add(Calendar.DATE, -1);
        calYesterday.set(Calendar.HOUR, 23);
        calYesterday.set(Calendar.MINUTE, 59);
        calYesterday.set(Calendar.SECOND, 59);
        Date endYesterday = calYesterday.getTime();
        calYesterday.set(Calendar.HOUR, 0);
        calYesterday.set(Calendar.MINUTE, 0);
        calYesterday.set(Calendar.SECOND, 0);
        Date startYesterday = calYesterday.getTime();
        String startYesterdayDate = sdf.format(startYesterday);
        String endYesterdayDate = sdf.format(endYesterday);
        scadaService.synHzFlowMeterHis(startYesterdayDate, endYesterdayDate);

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date end = calendar.getTime();
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date start = calendar.getTime();
        String startDate = sdf.format(start);
        String endDate = sdf.format(end);
        scadaService.synHzFlowMeterHis(startDate, endDate);
    }

//    /**
//     *
//     * 	每5分钟自动同步指标报警状态
//     */
//    @Async
//    @Scheduled(cron = "0 0/5 * * * ? ")
//    @SneakyThrows
//    public void autoIndexAlarmStatus(){
//        scadaService.autoIndexAlarmStatus();
//    }

    /**
     *
     * 	每小时同步设备指标信息
     */
    @Async
    @Scheduled(cron = "0 0 0/1 * * ? ")
    @SneakyThrows
    public  void sendIndexNotice(){
        scadaService.sendIndexNotice();
    }
}
