package com.yeejoin.amos.boot.module.jxiop.biz.listener;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jxiop.biz.service.impl.CommonServiceImpl;
import com.yeejoin.amos.boot.module.jxiop.biz.service.impl.TdengineTimeServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.component.emq.EmqxListener;

import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 */
@Component
@Slf4j
@EnableScheduling
public class SyncESDataToTdengineMqttListener extends EmqxListener {

	@Autowired
	private CommonServiceImpl commonServiceImpl;

	@Autowired
	private TdengineTimeServiceImpl tdengineTimeService;

	@Autowired
	private RedisUtils redisUtils;

	private final static String JXIOP_ANALYSE_TIME = "JXIOP_ANALYSE_TIME";

	@PostConstruct
	public void test() {
		// 每次启动清空redis
		// redisUtils.set(JXIOP_ANALYSE_TIME, "2024-07-30 13:40:00");
		redisUtils.del(JXIOP_ANALYSE_TIME);
	}

	// @Async("async")
	@Scheduled(cron = "0 */10 * * * ?")
	public void run() throws ParseException {
		Date time = new Date();
		time = DateUtil.offsetMinute(time, -DateUtil.minute(time) % 10);
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
		time = DateUtil.parse(format, "yyyy-MM-dd HH:mm:00");
		if (redisUtils.get(JXIOP_ANALYSE_TIME) != null) {
			// 如果相差20分钟 按10分钟处理 可能装备发消息晚了
			String lastformat = String.valueOf(redisUtils.get(JXIOP_ANALYSE_TIME));
			Date oldTime = DateUtil.parse(lastformat, "yyyy-MM-dd HH:mm:00");
			long diffInMillies = Math.abs(time.getTime() - oldTime.getTime());
			long diffInMinutes = TimeUnit.MINUTES.convert(diffInMillies, TimeUnit.MILLISECONDS);
			if (diffInMinutes == 20) {
				time = DateUtil.offsetMinute(time, -10);
				format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
			}
		}
		redisUtils.set(JXIOP_ANALYSE_TIME, format);
		System.out.println(format);
		final Date timeF = time;

		CompletableFuture<String> fan = CompletableFuture.supplyAsync(() -> {
			try {
				commonServiceImpl.healthWarningMinuteByFan(timeF);
			} catch (Exception e) {
				e.printStackTrace();
			}
			String fanResult = "风电任务完成..";
			System.out.println(fanResult);
			return fanResult;
		});

		CompletableFuture<String> pv = CompletableFuture.supplyAsync(() -> {
			try {
				commonServiceImpl.healthWarningMinuteByPv(timeF);
			} catch (Exception e) {
				e.printStackTrace();
			}
			String pvResult = "光伏任务完成..";
			System.out.println(pvResult);
			return pvResult;
		});
		try {
			String fanResult = fan.get();
			String pvResult = pv.get();
			// 区域 全域最后统一生成
			tdengineTimeService.insertMomentDataAll(format);
			if (isWholeHour(format)) {
				tdengineTimeService.insertHourData();
			}
			if (isWholeDay(format)) {
				tdengineTimeService.insertDayData();
			}
		} catch (InterruptedException | ExecutionException e) {
			System.out.println("任务执行异常");
			e.printStackTrace();
		}
	}

	@Override
	public void processMessage(String topic, MqttMessage mqttMessage) throws ParseException {
		log.info(topic + "收到数据同步成功，开始计算健康指数！");
		byte[] payload = mqttMessage.getPayload();
		String str = new String(payload);
		String msg = JSON.parse(str).toString();
		JSONObject jsonObject = JSONObject.parseObject(msg);
		String flag = jsonObject.get("sync_flag").toString();
		if ("success".equals(flag)) {
			run();
//			
//			ExecutorService excutorService = Executors.newFixedThreadPool(10);
//			int taskCount = 2;
//			final CountDownLatch latch = new CountDownLatch(taskCount);
//			excutorService.submit(() -> {
//				commonServiceImpl.healthWarningMinuteByFan(timeF);
//				System.out.println("风电任务完成..");
//				latch.countDown();
//			});
//			excutorService.submit(() -> {
//				commonServiceImpl.healthWarningMinuteByPv(timeF);
//				System.out.println("光伏任务完成..");
//				latch.countDown();
//			});
//
//			try {
//				System.out.println("等待所有任务完成..");
//				latch.await();
//				System.out.println("所有任务完成");
//			} catch (InterruptedException e) {
//				System.out.println("任务执行异常");
//				e.printStackTrace();
//				Thread.currentThread().interrupt();
//			}
//			// 结束线程池
//			excutorService.shutdown();
			// 区域 全域最后统一生成
//			tdengineTimeService.insertMomentDataAll(format);

//			// 开始异步计算光伏的健康指数算法
//			new Thread(() -> {
//				// 调用光伏的健康指数算法
//				commonServiceImpl.healthWarningMinuteByPv();
//			}).start();
//			// 开始异步计算风机的健康指数算法
//			new Thread(() -> {
//				// 调用风机的健康指数算法
//				commonServiceImpl.healthWarningMinuteByFan();
//			}).start();
		}
//		if ("pvsuccess".equals(flag)) {
//			// 开始异步计算光伏的健康指数算法
//			new Thread(() -> {
//				// 调用光伏的健康指数算法
//				commonServiceImpl.healthWarningMinuteByPv();
//			}).start();
//		}
//		if ("fansuccess".equals(flag)) {
//			// 开始异步计算光伏的健康指数算法
//			new Thread(() -> {
//				// 调用光伏的健康指数算法
//				commonServiceImpl.healthWarningMinuteByFan();
//			}).start();
//		}
	}

	private boolean isWholeHour(String dateTimeStr) {
		try {
			DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, FORMATTER);
			return dateTime.getMinute() == 0 && dateTime.getSecond() == 0;
		} catch (DateTimeParseException e) {
			return false;
		}
	}

	private boolean isWholeDay(String dateTimeStr) {
		try {
			DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, FORMATTER);
			return dateTime.getMinute() == 0 && dateTime.getSecond() == 0 && dateTime.getHour() == 0;
		} catch (DateTimeParseException e) {
			return false;
		}
	}
}
