/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 山洪灾害运维系统
 * 创建日期:2023/8/4
 */
package org.springblade.jobtask;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.business.data.dto.RtuDataRainDTO;
import org.springblade.modules.business.data.entity.*;
import org.springblade.modules.business.data.service.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;

/***
 * Date:2023/8/4
 * Title: 雨量统计
 * Description：统计雨量5分钟数据，生成1小时、3小时、6小时、12小时及24小时成果表
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@Slf4j
@Component
@EnableScheduling
public class RainDataCountProcessor {

	private static ThreadFactory rainDataCountThreadFactory = new ThreadFactoryBuilder().setNameFormat("rain-data-count-thread-pool-%d").build();
	private static ExecutorService rainDataCountThreadPool = new ThreadPoolExecutor(1, 1,
		0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), rainDataCountThreadFactory, new ThreadPoolExecutor.AbortPolicy());

	@Resource
	private IRtuDataRainH1Service h1Service;

	@Resource
	private IRtuDataRainH3Service h3Service;

	@Resource
	private IRtuDataRainH6Service h6Service;

	@Resource
	private IRtuDataRainH12Service h12Service;

	@Resource
	private IRtuDataRainH24Service h24Service;

	@Resource
	private IRtuDataRainStoreService rainStoreService;

	@Resource
	private IRtuDataRainService rainService;

	@Value("${spring.task-config.rain-count-task}")
	private boolean rainCountTaskRun;

//	@Scheduled(cron = "0 0/5 * * * * ")
	public void rainDataCountTask() {
		try {
			if (rainCountTaskRun) {
				Date dt = new Date();
				log.info("雨量统计任务创建 {}", Func.formatDateTime(dt));
				RainDataCountTask task = new RainDataCountTask(dt);
				FutureTask<Integer> futureTask = new FutureTask<>(task);
				rainDataCountThreadPool.execute(futureTask);
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage());
		}
	}

	private RtuDataRainH1Entity updateH1RainData(Date countTime, String rtuCode, Double drp) {
		try {
			LambdaQueryWrapper<RtuDataRainH1Entity> rainh1Wrapper = Wrappers.<RtuDataRainH1Entity>query().lambda();
			rainh1Wrapper.eq(RtuDataRainH1Entity::getIsDeleted, 0);
			rainh1Wrapper.eq(RtuDataRainH1Entity::getRtuCode, rtuCode);
			RtuDataRainH1Entity rainH1Entity = h1Service.getOne(rainh1Wrapper);
			if (null == rainH1Entity) {
				rainH1Entity = new RtuDataRainH1Entity();
				rainH1Entity.setRtuCode(rtuCode);
			}
			rainH1Entity.setDrp(drp);
			rainH1Entity.setTm(countTime);
			rainH1Entity.setFromTime(countTime);
			return rainH1Entity;
		} catch (Exception e) {
			log.error(e.getMessage());
			return null;
		}
	}

	private RtuDataRainH3Entity updateH3RainData(Date countTime, String rtuCode, Double drp) {
		try {
			LambdaQueryWrapper<RtuDataRainH3Entity> rainh3Wrapper = Wrappers.<RtuDataRainH3Entity>query().lambda();
			rainh3Wrapper.eq(RtuDataRainH3Entity::getIsDeleted, 0);
			rainh3Wrapper.eq(RtuDataRainH3Entity::getRtuCode, rtuCode);
			RtuDataRainH3Entity rainH3Entity = h3Service.getOne(rainh3Wrapper);
			if (null == rainH3Entity) {
				rainH3Entity = new RtuDataRainH3Entity();
				rainH3Entity.setRtuCode(rtuCode);
			}
			rainH3Entity.setDrp(drp);
			rainH3Entity.setTm(countTime);
			rainH3Entity.setFromTime(countTime);
			return rainH3Entity;
		} catch (Exception e) {
			log.error(e.getMessage());
			return null;
		}
	}

	private RtuDataRainH6Entity updateH6RainData(Date countTime, String rtuCode, Double drp) {
		try {
			LambdaQueryWrapper<RtuDataRainH6Entity> rainh6Wrapper = Wrappers.<RtuDataRainH6Entity>query().lambda();
			rainh6Wrapper.eq(RtuDataRainH6Entity::getIsDeleted, 0);
			rainh6Wrapper.eq(RtuDataRainH6Entity::getRtuCode, rtuCode);
			RtuDataRainH6Entity rainH6Entity = h6Service.getOne(rainh6Wrapper);
			if (null == rainH6Entity) {
				rainH6Entity = new RtuDataRainH6Entity();
				rainH6Entity.setRtuCode(rtuCode);
			}
			rainH6Entity.setDrp(drp);
			rainH6Entity.setTm(countTime);
			rainH6Entity.setFromTime(countTime);
			return rainH6Entity;
		} catch (Exception e) {
			log.error(e.getMessage());
			return null;
		}
	}

	private RtuDataRainH12Entity updateH12RainData(Date countTime, String rtuCode, Double drp) {
		try {
			LambdaQueryWrapper<RtuDataRainH12Entity> rainh12Wrapper = Wrappers.<RtuDataRainH12Entity>query().lambda();
			rainh12Wrapper.eq(RtuDataRainH12Entity::getIsDeleted, 0);
			rainh12Wrapper.eq(RtuDataRainH12Entity::getRtuCode, rtuCode);
			RtuDataRainH12Entity rainH12Entity = h12Service.getOne(rainh12Wrapper);
			if (null == rainH12Entity) {
				rainH12Entity = new RtuDataRainH12Entity();
				rainH12Entity.setRtuCode(rtuCode);
			}
			rainH12Entity.setDrp(drp);
			rainH12Entity.setTm(countTime);
			rainH12Entity.setFromTime(countTime);
			return rainH12Entity;
		} catch (Exception e) {
			log.error(e.getMessage());
			return null;
		}
	}

	private RtuDataRainH24Entity updateH24RainData(Date countTime, String rtuCode, Double drp) {
		try {
			LambdaQueryWrapper<RtuDataRainH24Entity> rainh24Wrapper = Wrappers.<RtuDataRainH24Entity>query().lambda();
			rainh24Wrapper.eq(RtuDataRainH24Entity::getIsDeleted, 0);
			rainh24Wrapper.eq(RtuDataRainH24Entity::getRtuCode, rtuCode);
			RtuDataRainH24Entity rainH24Entity = h24Service.getOne(rainh24Wrapper);
			if (null == rainH24Entity) {
				rainH24Entity = new RtuDataRainH24Entity();
				rainH24Entity.setRtuCode(rtuCode);
			}
			rainH24Entity.setDrp(drp);
			rainH24Entity.setTm(countTime);
			rainH24Entity.setFromTime(countTime);
			return rainH24Entity;
		} catch (Exception e) {
			log.error(e.getMessage());
			return null;
		}
	}

	private class RainDataCountTask implements Callable<Integer> {

		private Date countTime;

		public RainDataCountTask(Date countTime) {
			this.countTime = countTime;
		}

		@Override
		public Integer call() throws Exception {
			try {
				log.info("雨量统计任务开始执行 {}", Func.formatDateTime(countTime));
				LambdaQueryWrapper<RtuDataRainEntity> dataWrapper = Wrappers.<RtuDataRainEntity>query().lambda();
				dataWrapper.eq(RtuDataRainEntity::getIsDeleted, 0);
				List<RtuDataRainEntity> list = rainService.list(dataWrapper);
				if (null != list && list.size() > 0) {
					List<RtuDataRainH1Entity> h1EntityList = new LinkedList<>();
					List<RtuDataRainH3Entity> h3EntityList = new LinkedList<>();
					List<RtuDataRainH6Entity> h6EntityList = new LinkedList<>();
					List<RtuDataRainH12Entity> h12EntityList = new LinkedList<>();
					List<RtuDataRainH24Entity> h24EntityList = new LinkedList<>();
					Calendar calendar = Calendar.getInstance();
					//近1小时
					calendar.setTime(countTime);
					calendar.set(Calendar.SECOND, 0);
					calendar.add(Calendar.HOUR_OF_DAY, -1);
					log.info("近1小时统计时间 {}", Func.formatDateTime(calendar.getTime()));
					Date h1Time = calendar.getTime();
					//近3小时
					calendar.setTime(countTime);
					calendar.set(Calendar.SECOND, 0);
					calendar.add(Calendar.HOUR_OF_DAY, -3);
					log.info("近3小时统计时间 {}", Func.formatDateTime(calendar.getTime()));
					Date h3Time = calendar.getTime();
					//近6小时
					calendar.setTime(countTime);
					calendar.set(Calendar.SECOND, 0);
					calendar.add(Calendar.HOUR_OF_DAY, -6);
					log.info("近6小时统计时间 {}", Func.formatDateTime(calendar.getTime()));
					Date h6Time = calendar.getTime();
					//近12小时
					calendar.setTime(countTime);
					calendar.set(Calendar.SECOND, 0);
					calendar.add(Calendar.HOUR_OF_DAY, -12);
					log.info("近12小时统计时间 {}", Func.formatDateTime(calendar.getTime()));
					Date h12Time = calendar.getTime();
					//近24小时
					calendar.setTime(countTime);
					calendar.set(Calendar.SECOND, 0);
					calendar.add(Calendar.HOUR_OF_DAY, -24);
					log.info("近24小时统计时间 {}", Func.formatDateTime(countTime));
					Date h24Time = calendar.getTime();
					for (RtuDataRainEntity entity : list) {
						//log.info("upcount code {}", entity.getRtuCode());
						Double h1Drp = 0.0;
						Double h3Drp = 0.0;
						Double h6Drp = 0.0;
						Double h12Drp = 0.0;
						Double h24Drp = 0.0;

//						RtuDataRainDTO dataRainDTO = new RtuDataRainDTO();
//						dataRainDTO.setRtuCode(entity.getRtuCode());
//						dataRainDTO.setBeginTime(h1Time);
//						Double drp = rainStoreService.rainDrpCount(dataRainDTO);
//						if (null != drp) {
//							h1Drp = drp;
//						}
//						dataRainDTO.setBeginTime(h3Time);
//						drp = rainStoreService.rainDrpCount(dataRainDTO);
//						if (null != drp) {
//							h3Drp = drp;
//						}
//						dataRainDTO.setBeginTime(h6Time);
//						drp = rainStoreService.rainDrpCount(dataRainDTO);
//						if (null != drp) {
//							h6Drp = drp;
//						}
//						dataRainDTO.setBeginTime(h12Time);
//						drp = rainStoreService.rainDrpCount(dataRainDTO);
//						if (null != drp) {
//							h12Drp = drp;
//						}
//						dataRainDTO.setBeginTime(h24Time);
//						drp = rainStoreService.rainDrpCount(dataRainDTO);
//						if (null != drp) {
//							h24Drp = drp;
//						}


						RtuDataRainDTO dataRainDTO = new RtuDataRainDTO();
						dataRainDTO.setRtuCode(entity.getRtuCode());
						dataRainDTO.setBeginTime(h24Time);
						List<RtuDataRainStoreEntity> rainStoreEntityList = rainStoreService.selectList(dataRainDTO);
						if (rainStoreEntityList != null && rainStoreEntityList.size() > 0) {
							for (RtuDataRainStoreEntity rainStoreEntity : rainStoreEntityList) {
								//近1小时
								if (rainStoreEntity.getTm().after(h1Time)) {
									h1Drp += rainStoreEntity.getDrp();
								}
								//近3小时
								if (rainStoreEntity.getTm().after(h3Time)) {
									h3Drp += rainStoreEntity.getDrp();
								}
								//近6小时
								if (rainStoreEntity.getTm().after(h6Time)) {
									h6Drp += rainStoreEntity.getDrp();
								}
								//近12小时
								if (rainStoreEntity.getTm().after(h12Time)) {
									h12Drp += rainStoreEntity.getDrp();
								}
								//近24小时
								h24Drp += rainStoreEntity.getDrp();
							}
						}

						RtuDataRainH1Entity h1Entity = updateH1RainData(countTime, entity.getRtuCode(), h1Drp);
						if (h1Entity != null) {
							h1EntityList.add(h1Entity);
						}
						RtuDataRainH3Entity h3Entity = updateH3RainData(countTime, entity.getRtuCode(), h3Drp);
						if (h3Entity != null) {
							h3EntityList.add(h3Entity);
						}
						RtuDataRainH6Entity h6Entity = updateH6RainData(countTime, entity.getRtuCode(), h6Drp);
						if (h6Entity != null) {
							h6EntityList.add(h6Entity);
						}
						RtuDataRainH12Entity h12Entity = updateH12RainData(countTime, entity.getRtuCode(), h12Drp);
						if (h12Entity != null) {
							h12EntityList.add(h12Entity);
						}
						RtuDataRainH24Entity h24Entity = updateH24RainData(countTime, entity.getRtuCode(), h24Drp);
						if (h24Entity != null) {
							h24EntityList.add(h24Entity);
						}
					}
					h1Service.saveOrUpdateBatch(h1EntityList);
					h3Service.saveOrUpdateBatch(h3EntityList);
					h6Service.saveOrUpdateBatch(h6EntityList);
					h12Service.saveOrUpdateBatch(h12EntityList);
					h24Service.saveOrUpdateBatch(h24EntityList);
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("雨量数据统计任务异常 {}", e.getMessage());
			} finally {
				log.error("雨量数据统计任务完成 {} 毫秒", System.currentTimeMillis() - countTime.getTime());
			}
			return 0;
		}
	}
}
