package com.steerinfo.task;

import com.steerinfo.ems.Utils.DateUtils;
import com.steerinfo.ems.bfhyd.service.IBfhydService;
import com.steerinfo.ems.dzmaterialsf.service.IDzMaterialSfService;
import com.steerinfo.ems.emsetiming.service.IEmsETimingService;
import com.steerinfo.ems.emsgmpcjh.service.IEmsGmPcJhService;
import com.steerinfo.ems.emsprodplanroundweight.service.IEmsProdplanRoundWeightService;
import com.steerinfo.ems.emsscqklg.service.IEmsScqkLgService;
import com.steerinfo.ems.emsscqklg.service.ILgRealService;
import com.steerinfo.ems.emswaterrealtime.service.IEmsWaterRealtimeService;
import com.steerinfo.ems.foldthevalues.service.IFoldTheValuesService;
import com.steerinfo.ems.ifemsmesactitem.service.IIfEmsMesActitemService;
import com.steerinfo.ems.ifmesemsproductorder.service.IIfMesEmsProductorderService;
import com.steerinfo.ems.ifmesemsswapfile.service.IIfMesEmsSwapfileService;
import com.steerinfo.ems.ifmesemswatermonitor.service.IIfMesEmsWatermonitorService;
import com.steerinfo.ems.mesemsdieseloil.service.IMesEmsDieseloilService;
import com.steerinfo.ems.rttable.service.IRttableService;
import com.steerinfo.ems.tcm0312.controller.TCm0312Controller;
import com.steerinfo.ems.tcm0318.service.ITCm0318Service;
import com.steerinfo.ems.tcm0348.service.ITCm0348Service;
import com.steerinfo.ems.trmactvalue.service.ITRmActValueService;
import com.steerinfo.ems.trmbalancevalue.service.ITRmBalanceValueService;
import com.steerinfo.ems.trmcalpoint.service.ITRmCalpointService;
import com.steerinfo.ems.trmcalpointvalue.service.ITRmCalpointValueService;
import com.steerinfo.ems.trmdfvalue.service.ITRmDfValueService;
import com.steerinfo.ems.trmdwvalue.service.ITRmDwValueService;
import com.steerinfo.ems.trmindexvalue.service.ITRmIndexValueService;
import com.steerinfo.ems.trmplanvalue.service.ITRmPlanValueService;
import com.steerinfo.ems.trmtransfereactvalue.service.ITRmTransfereActValueService;
import com.steerinfo.ems.trmworkprocmaterialvalue.service.ITRmWorkprocMaterialValueService;
import com.steerinfo.ems.trmworkprocproductvalue.service.ITRmWorkprocProductValueService;
import com.steerinfo.ems.usagedata.service.IUsageDataService;
import com.steerinfo.ems.zghbjkbzlog.service.IZghbjkbzLogService;
import org.apache.axis2.AxisFault;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

@EnableScheduling
@Service(value = "springCronTask")
public class SpringCronTask implements SchedulingConfigurer{

	private static final Logger logger = LoggerFactory.getLogger(SpringCronTask.class);

	private ScheduledTaskRegistrar taskRegistrar;

	private Map<String, ScheduledFuture<?>>  taskFutures = new ConcurrentHashMap<String, ScheduledFuture<?>>();

	@Autowired
	private JdbcTemplate jdbcTemplate;
	@Autowired
	IIfMesEmsSwapfileService ifMesEmsSwapfileService;
	@Autowired
	IIfMesEmsProductorderService ifMesEmsProductorderService;
	@Autowired
	ITRmWorkprocMaterialValueService tRmWorkprocMaterialValueService;
	@Autowired
	ITRmWorkprocProductValueService tRmWorkprocProductValueService;
	@Autowired
	ITRmCalpointValueService tRmCalpointValueService;
	@Autowired
	IUsageDataService usageDataService;
	@Autowired
	ITRmActValueService tRmActValueService;
	@Autowired
	ITRmPlanValueService tRmPlanValueService;
	@Autowired
	IEmsETimingService emsETimingService;
	@Autowired
	TCm0312Controller tCm0312Controller;
	@Autowired
	IIfMesEmsWatermonitorService ifMesEmsWatermonitorService;
	@Autowired
	IIfEmsMesActitemService ifEmsMesActitemService;
	@Autowired
	ITRmIndexValueService tRmIndexValueService;
	@Autowired
	ITRmBalanceValueService tRmBalanceValueService;
	@Autowired
	IZghbjkbzLogService zghbjkbzLogService;
	@Autowired
	IMesEmsDieseloilService mesEmsDieseloilService;
	@Autowired
	ITRmTransfereActValueService tRmTransfereActValueService;
	@Autowired
	ITRmDwValueService tRmDwValueService;
	@Autowired
	ITRmCalpointService tRmCalpointService;
	@Autowired
	ITRmDfValueService tRmDfValueService;
	@Autowired
	IBfhydService bfhydService;
	@Autowired
	ITCm0348Service tCm0348Service;
	@Autowired
	ITCm0318Service tCm0318Service;
	@Autowired
	IEmsWaterRealtimeService emsWaterRealtimeService;
	@Autowired
	IEmsGmPcJhService emsGmPcJhService;
	@Autowired
	IDzMaterialSfService dzMaterialSfService;
	@Autowired
	IRttableService rttableService;
	@Autowired
	IEmsScqkLgService emsScqkLgService;
	@Autowired
	ILgRealService lgRealService;
	@Autowired
	IFoldTheValuesService foldTheValuesService;
	@Autowired
	IEmsProdplanRoundWeightService emsProdplanRoundWeightService;
	/**
	 * SchedulingConfigurer接口的方法实现，加载后自动运行
	 */
	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
		taskScheduler.setThreadNamePrefix("ems-task-");
		taskScheduler.setPoolSize(4);
		taskScheduler.initialize();
		taskRegistrar.setTaskScheduler(taskScheduler);

		this.taskRegistrar = taskRegistrar;
		// 初始化任务
		String sql = "select * from TASK_CONF order by id";
		List<Map<String, Object>> l = jdbcTemplate.queryForList(sql);
		if (l!=null && l.size()>0){
			for(int i =0; i<l.size(); i++){
				Map<String, Object> m = (Map<String, Object>)l.get(i);
				String taskId = m.get("ID").toString();
				String cron = m.get("CRON").toString();
				String status = m.get("STATUS") == null ? "" : m.get("STATUS").toString();
				if(status.equalsIgnoreCase("1") && !taskFutures.containsKey(taskId)){
					addTask(taskId, cron);
				}
				if(status.equalsIgnoreCase("0") && taskFutures.containsKey(taskId)){
					cancelTriggerTask(taskId);
				}
				logger.info("定时任务-" + taskId + " cron表达式：" + cron);
			}
		}
	}

	/**
	 * 添加定时任务(初始化)
	 *
	 * @param taskId
	 * @param cron
	 */
	public void addTask(String taskId, String cron) {
		if (!taskFutures.containsKey(taskId)) {
			TaskScheduler scheduler = taskRegistrar.getScheduler();
			ScheduledFuture<?> future = scheduler.schedule(doTask(taskId), new CronTrigger(cron));
			taskFutures.put(taskId, future);
			logger.info("当前定时任务队列长度：" + taskFutures.size());
		} else {
			throw new SchedulingException("the taskId[" + taskId + "] was added.");
		}
	}

	/**
	 * 添加或者更新定时任务
	 *
	 * @param taskId
	 */
	public void updateTask(String taskId) {
		if(taskFutures.containsKey(taskId)){
			cancelTriggerTask(taskId);
		}
		TaskScheduler scheduler = taskRegistrar.getScheduler();
		ScheduledFuture<?> future = scheduler.schedule(doTask(taskId), new CronTrigger(getCron(taskId)));
		taskFutures.put(taskId, future);
		logger.info("当前定时任务队列长度：" + taskFutures.size());
	}

	/**
	 * 取消任务
	 * @param taskId
	 */
	public void cancelTriggerTask(String taskId){
		ScheduledFuture<?> future = taskFutures.get(taskId);
		if (future != null){
			future.cancel(true);
		}
		taskFutures.remove(taskId);
	}
	/**
	 * 业务处理
	 *
	 * @param taskId
	 * @return
	 */
	private Runnable doTask(String taskId) {
		Properties props = System.getProperties(); // 系统属性
		return new Runnable() {
			@Override
			public void run() {
				if(!props.getProperty("os.name").equalsIgnoreCase("linux")){
					System.out.println("操作系统：" + props.getProperty("os.name") + ", 非linux环境不运行定时任务");
					return;
				}
//				if (taskId.equalsIgnoreCase("101")) { // 定时任务1的业务处理-MES数据同步
//					logger.info("定时任务触发时间：" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//					long start = System.currentTimeMillis();
//					ifMesEmsSwapfileService.synchronousMesAnEmsData(); // 获取MES投入产出数据
//					ifMesEmsProductorderService.synchronousMesAnEmsData(); // 获取MES生产计划数据
//					//usageDataService.getAutoSum(DateUtils.dateStr(new Date(start - 24*3600*1000L), "yyyy-MM-dd")); // 统计自动上传的能源上报数据（昨日）
//					//mesEmsDieseloilService.synchronousMesEmsData(); // 获取MES柴油数据
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if (taskId.equalsIgnoreCase("102")) {
//					// 计量点定时任务
//					long start = System.currentTimeMillis();
//					tRmCalpointValueService.statData(new Date());
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				}
				 if (taskId.equalsIgnoreCase("103")) {
					long start = System.currentTimeMillis();
					tRmActValueService.statDataforDay();// 每日数据统计（实绩定时任务）
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				 else if (taskId.equalsIgnoreCase("104")) {
					 // 能介计划数据生成
					long start = System.currentTimeMillis();
					tRmPlanValueService.state();// 每日数据统计（计划定时任务）
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				 else  if (taskId.equalsIgnoreCase("105")) {
					// 先计算产品，因为原材料计算单耗需要产品实绩数据参与计算
					long start = System.currentTimeMillis();
					//2022-07-11 张琰 注释，现有逻辑是从报表获取数据。
					//ifMesEmsSwapfileService.getLgDateProd();
					//try {
					//	ifMesEmsSwapfileService.getLgDateProd2();
					//} catch (ParseException e) {
					//	e.printStackTrace();
					//}
					tRmWorkprocProductValueService.setDate(new Date()); // 产品实绩产量、产品计划数据维护
					tRmWorkprocMaterialValueService.setDate(new Date()); // 原材料数据维护
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				else if (taskId.equalsIgnoreCase("119")) {
					 long start = System.currentTimeMillis();
					  bfhydService.getBfhyds();
					 try {
						 tCm0348Service.getDate();
					 } catch (ParseException e) {
						 e.printStackTrace();
					 }
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				 }
				 else if (taskId.equalsIgnoreCase("122")) {
					 long start = System.currentTimeMillis();
					 tCm0318Service.getDataAsLg(DateUtils.getDate());
					 tCm0318Service.getDataAsYlc(DateUtils.getDate());
					 tCm0318Service.getDataAsYgx(DateUtils.getDate());
					 tCm0318Service.getDataAsEgx(DateUtils.getDate());
					 tCm0318Service.getDataAsFdc(DateUtils.getDate());
					 tCm0318Service.getDataAsJjc(DateUtils.getDate());
					 tCm0318Service.getDataAsWscj(DateUtils.getDate());
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				 else if(taskId.equalsIgnoreCase("120")){
					 long start = System.currentTimeMillis();
					 // 获取大用户水系统数据、获取动力数据 5分钟一次
					 emsWaterRealtimeService.getWaterListByArmMeter();
					 emsWaterRealtimeService.dataGeneration();
					 rttableService.dataGeneration();
					 try {
						 emsWaterRealtimeService.getWaterListToMosaic();
					 } catch (AxisFault e) {
						 e.printStackTrace();
					 } finally {
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
					 }
				 } else if(taskId.equalsIgnoreCase("121")){
					 // 根据计量点配置生成动力数据、水数据 10分钟一次，传输到mosaic
					 long start = System.currentTimeMillis();
					 emsWaterRealtimeService.getWaterTenMinutes();
					 rttableService.getPowerTenMinutes();
						 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				 }
				 else if(taskId.equalsIgnoreCase("116")){
					// 动力、水、物料(计量点)小时表定时统计（自动补全24小时内的小时用量值）
					long start = System.currentTimeMillis();
					tRmCalpointService.statHourData();
					////水计量点统计，获取水系统历史数据，弃用,数据不准确
					// emsWaterRealtimeService.getWaterTenMinutes();
					// emsWaterRealtimeService.getWaterHour();
					// emsWaterRealtimeService.getHistoryWaterToHour();
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				 else if (taskId.equalsIgnoreCase("102")) {
					 // 计量点定时任务(天)
					 long start = System.currentTimeMillis();
					 tRmCalpointValueService.statData(new Date());
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				 }
				 else if (taskId.equalsIgnoreCase("123")) {
					 // 大宗物料收发数据，从炼钢mes调度日报生成生产日报每天(0点57分，4点57分,8点57分)
					 long start = System.currentTimeMillis();
					 dzMaterialSfService.dataGeneration();
					 emsScqkLgService.dateGenerate();
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				else if(taskId.equalsIgnoreCase("124")){
					 long start = System.currentTimeMillis();
					 try {
					 	 foldTheValuesService.getData();
					 	 foldTheValuesService.getDataForwl();
						 Calendar c = Calendar.getInstance();
						 if(c.get(Calendar.DATE) == 1){
						 foldTheValuesService.getMonthData();
						 }
						 foldTheValuesService.insertNewDate();
					 } catch (Exception e) {
						 e.printStackTrace();
					 }
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				 }
				 else  if(taskId.equalsIgnoreCase("127")){
					 long start = System.currentTimeMillis();
					 try {
						 emsProdplanRoundWeightService.getWeightForLg();
						 emsProdplanRoundWeightService.getWeightForGx();
					 } catch (Exception e) {
						 e.printStackTrace();
					 }
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				 }
				else if(taskId.equalsIgnoreCase("128")){
					 long start = System.currentTimeMillis();
					 try {
						 tRmCalpointValueService.insetDataForBb();
					 } catch (Exception e) {
						 e.printStackTrace();
					 }
					 logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				 } else if (taskId.equalsIgnoreCase("107")) { // 电统计(从mosaic到EMS)
					long start = System.currentTimeMillis();
					//emsETimingService.getData();
					 emsETimingService.getETimingTenData();
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
// 				 else if (taskId.equalsIgnoreCase("106")) {
//					// 获取MES水质监测数据
//					long start = System.currentTimeMillis();
//					ifMesEmsWatermonitorService.synchronousMesAnEmsData();
//					// 生成人工录入监测数据
//					tCm0312Controller.getmanualdata();
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if (taskId.equalsIgnoreCase("107")) { // 电统计(从南瑞到EMS)
//					long start = System.currentTimeMillis();
//					emsETimingSersvice.getData();
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if (taskId.equalsIgnoreCase("108")) {
//					// 从IF_MES_EMS_WATERMONITOR表获取水质监测数据到T_CM_0318表
//					tCm0312Controller.synchronousData();
//				} else if (taskId.equalsIgnoreCase("109")) { // 电计量点班数据计算
//					tRmCalpointValueService.statDataShift(new Date());
//				} else if (taskId.equalsIgnoreCase("110")) {
//					// 能耗数据获取
//					ifEmsMesActitemService.getUploadData();
//				} else if (taskId.equalsIgnoreCase("111")) {
//					// 指标管理数据生成
//					long start = System.currentTimeMillis();
//					tRmIndexValueService.statData();
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if (taskId.equalsIgnoreCase("112")) {
//					// 能源上报_晋泰信和
//					usageDataService.autoUpload();
//				}
				 else if (taskId.equalsIgnoreCase("111")) {
					// 指标管理数据生成
					long start = System.currentTimeMillis();
					tRmIndexValueService.statData();
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
				else if(taskId.equalsIgnoreCase("113")){
					//平衡数据维护
					long start = System.currentTimeMillis();
					tRmBalanceValueService.state();
					// 上报项目数据维护
					 // tRmDwValueService.state(new Date());
					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
				}
//				else if(taskId.equalsIgnoreCase("114")){
//					// 环保监控记录定时任务
//					zghbjkbzLogService.record();
//				} else if(taskId.equalsIgnoreCase("115")){
//					// 月初自动生成宾馆转供电记录
//					long start = System.currentTimeMillis();
//					tRmTransfereActValueService.createRecord();
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if(taskId.equalsIgnoreCase("116")){
//					// 动力、水小时表定时统计（自动补全24小时内的小时用量值）
//					long start = System.currentTimeMillis();
//					tRmCalpointService.statHourData();
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if(taskId.equalsIgnoreCase("117")){
//					// 财务投入产出数据生成
//					long start = System.currentTimeMillis();
//					tRmDfValueService.state(new Date());
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				} else if(taskId.equalsIgnoreCase("118")){
//					// 财务投入产出数据MES产量补全
//					long start = System.currentTimeMillis();
//					tRmDfValueService.state(new Date());
//					logger.info("定时任务"+taskId+"执行时长：" + (System.currentTimeMillis() - start)/1000 + "秒");
//				}
			}
		};
	}

	/**
	 * 获取任务时间表达式
	 * @param taskId
	 * @return
	 */
	public String getCron(String taskId) {
		String sql = "select cron from TASK_CONF t where id = ?";
		return jdbcTemplate.queryForObject(sql, new Object[]{taskId}, String.class);
	}
}
