package com.saye.hospitalgd.controller.quartz;

import java.util.*;

import com.saye.hospitalgd.commons.log.LogUtil;
import com.saye.hospitalgd.service.system.DicinfoService;
import org.apache.shiro.SecurityUtils;
import org.quartz.CronTrigger;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.TriggerKey;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageInfo;
import com.saye.hospitalgd.commons.date.DateDUtil;
import com.saye.hospitalgd.commons.log.ExceptionDUtil;
import com.saye.hospitalgd.commons.page.PageUtil;
import com.saye.hospitalgd.commons.page.TemplatePage;
import com.saye.hospitalgd.commons.string.StringDUtil;
import com.saye.hospitalgd.model.BaseQuartzConfigEntity;
import com.saye.hospitalgd.model.Users;
import com.saye.hospitalgd.scheduler.MySchedulerFactory;
import com.saye.hospitalgd.service.quartz.BaseQuartzConfigService;

/**
 * @description: 定时任务
 * @author thuang
 * @date 2021/10/18 9:46
 * @version 1.0
 */
@Controller
@RequestMapping("/quartzConfig")
public class BaseQuartzConfigController{
	
	@Autowired
	private BaseQuartzConfigService baseQuartzConfigService;

	@Autowired
	private MySchedulerFactory mySchedulerFactory;

	@Autowired
	private DicinfoService dicinfoService;

	/**
	 * @description 跳转到定时任务管理页面
	 * @author thuang
	 * @created 2025/10/24
	 * @return
	 */
	@RequestMapping("/toQuartzManage")
	public String toQuartzManage() {
		return "system/quartzManage";
	}

	/**
	 * @description 查询所有的定时任务
	 * @author thuang
	 * @created 2020年1月7日 下午5:10:21
	 * @param configId
	 * @param quartz_name
	 * @return
	 */
	@RequestMapping("/findQuartzConfig")
	@ResponseBody
	public TemplatePage findQuartzConfig(String configId,String quartz_name,String quartz_type){
		PageInfo<BaseQuartzConfigEntity> appsPageInfo=null;
		try {
			HashMap<Object, Object> map=new HashMap<Object, Object>();
			map.put("configId", configId);
			map.put("quartz_name", quartz_name);
			map.put("quartz_type", quartz_type);

			appsPageInfo = new PageInfo<BaseQuartzConfigEntity>(baseQuartzConfigService.findAll(map));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return PageUtil.loadJsonPage(appsPageInfo);
	}

	/**
	 * @description 修改定时任务设置
	 * @author thuang
	 * @created 2020年1月7日 下午2:10:04
	 * @param map
	 * @return
	 */
	@RequestMapping("/changestatus")
	@ResponseBody
    public HashMap<Object, Object> changestatus(@RequestBody Map<Object, Object> map){
    	HashMap<Object, Object> responseMap=new HashMap<Object, Object>();
		String errCode="0";
		String errMsg="";

    	try {
    		Users user = (Users) SecurityUtils.getSubject().getPrincipal();
			String status = StringDUtil.changeNullToEmpty(map.get("status"));
			String configid = StringDUtil.changeNullToEmpty(map.get("quartzId"));
			if (StringDUtil.isNotBlank(configid) && StringDUtil.isNotBlank(status)) {
				BaseQuartzConfigEntity quartzConfigEntity = baseQuartzConfigService.get(configid);
				if ("0".equals(status)) {
					//修改为0，并且恢复运行
					quartzConfigEntity.setStatus("1");
					mySchedulerFactory.resumeJob(configid);
				}else {
					//修改为1，并且暂停
					quartzConfigEntity.setStatus("0");
					mySchedulerFactory.pauseJob(configid);
				}
				baseQuartzConfigService.updateQuartzConfig(quartzConfigEntity);
				LogUtil.debug(this.getClass(),"用户"+ user.getTrueName()+"修改定时任务："+configid);
			}else {
				errCode="998";
				errMsg="修改定时任务参数不全";
			}

		} catch (Exception e) {
			 errCode="999";
			 errMsg="修改定时任务失败";
			 LogUtil.error(this.getClass(), "修改定时任务失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}

    	responseMap.put("errCode", errCode);
    	responseMap.put("errMsg", errMsg);
    	return responseMap;
    }


	/**
	 * @description 新增定时任务
	 * @author thuang
	 * @created 2020年1月7日 下午2:10:04
	 * @param map
	 * @return
	 */
	@RequestMapping("/addNewQuartz")
	@ResponseBody
	public HashMap<Object, Object> addNewQuartz(@RequestBody HashMap<Object, Object> map){
		HashMap<Object, Object> responseMap=new HashMap<Object, Object>();
		String errCode="0";
		String errMsg="";

		try{
			String time = StringDUtil.changeNullToEmpty(map.get("time"));
			String dataStr = StringDUtil.changeNullToEmpty(map.get("dataStr"));
			String remark = StringDUtil.changeNullToEmpty(map.get("remark"));
			String jobType = StringDUtil.changeNullToEmpty(map.get("jobType"));
			String quartz_class = StringDUtil.changeNullToEmpty(map.get("quartz_class"));
			String quartzName = StringDUtil.changeNullToEmpty(map.get("quartzName"));

			Users user = (Users) SecurityUtils.getSubject().getPrincipal();
			String userId = user.getUserId();

			String cronStr = getCron(map);

			//查询任务最大任务id号 生成新的id号
			List<HashMap<Object, Object>> list =this.baseQuartzConfigService.findMaxId();

			String id="";
			if(list!=null && list.size()>0){
				id=""+(Integer.parseInt(StringDUtil.changeNullToEmpty(list.get(0).get("ID")))+1);
			}else {
				id="1";
			}
			HashMap<Object, Object> addMap=new HashMap<Object, Object>();
			addMap.put("id", id);
			addMap.put("quartzName", quartzName);
			addMap.put("status", "0");
			addMap.put("quartz_class", quartz_class);
			addMap.put("remark", remark);
			addMap.put("createuserid", userId);
			addMap.put("expression", cronStr);
			addMap.put("create_time", DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd_HH_mm_ss));
			addMap.put("quartz_type", jobType);
			this.baseQuartzConfigService.addQuartz(addMap);

			mySchedulerFactory.addJob(id,quartzName, null, cronStr, quartz_class);
			LogUtil.debug(this.getClass(),"用户"+ user.getTrueName()+"新增定时任务："+id);
		} catch (Exception e) {
			 errCode="999";
			 errMsg="新增定时任务失败";
			 LogUtil.error(this.getClass(), "新增定时任务失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}

		responseMap.put("errCode", errCode);
		responseMap.put("errMsg", errMsg);


		return responseMap;
	}

	/**
	 * @description 删除定时任务
	 * @author thuang       
	 * @created 2020年1月7日 下午2:10:04 
	 * @param map
	 * @return
	 */
	@RequestMapping("/deleteQuartz")
	@ResponseBody
	public HashMap<Object, Object> deleteQuartz(@RequestBody HashMap<Object, Object> map){
		HashMap<Object, Object> responseMap=new HashMap<Object, Object>();
		String errCode="0";
		String errMsg="";
		try{
			Users user = (Users) SecurityUtils.getSubject().getPrincipal();
			String id = StringDUtil.changeNullToEmpty(map.get("configId"));
			
			mySchedulerFactory.pauseJob(id);
			
			this.baseQuartzConfigService.deleteQuartzConfigById(id);
			LogUtil.debug(this.getClass(),"用户"+ user.getTrueName()+"删除定时任务："+id);
		} catch (Exception e) {
			 errCode="999";
			 errMsg="删除定时任务失败";
			 LogUtil.error(this.getClass(), "删除定时任务失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}
		
		responseMap.put("errCode", errCode);
		responseMap.put("errMsg", errMsg);
	
	
	return responseMap;
	}
	
	/**
	 * @description 修改定时任务
	 * @author thuang       
	 * @created 2020年1月7日 下午2:10:04 
	 * @param map
	 * @return
	 */
	@RequestMapping("/modifyQuartz")
	@ResponseBody
	public HashMap<Object, Object> modifyQuartz(@RequestBody HashMap<Object, Object> map){
		HashMap<Object, Object> responseMap=new HashMap<Object, Object>();
		String errCode="0";
		String errMsg="";
		try{
			Users user = (Users) SecurityUtils.getSubject().getPrincipal();
			String configId = StringDUtil.changeNullToEmpty(map.get("configId"));
			String quartzName = StringDUtil.changeNullToEmpty(map.get("quartzName"));
			String quartzGroup = StringDUtil.changeNullToEmpty(map.get("quartzGroup"));
			String quartzClass = StringDUtil.changeNullToEmpty(map.get("quartz_class"));
			String remark = StringDUtil.changeNullToEmpty(map.get("remark"));
			String quartzType=StringDUtil.changeNullToEmpty(map.get("jobType"));
			String time=StringDUtil.changeNullToEmpty(map.get("time"));
			
			if(time==null || "".equals(time)){
				throw new RuntimeException("time为空");
			}
			
			String cronStr = getCron(map);
			
			HashMap<Object, Object> updateMap=new HashMap<Object, Object>();
			updateMap.put("configId", configId);
			updateMap.put("quartzName", quartzName);
			updateMap.put("quartzGroup", quartzGroup);
			updateMap.put("quartzClass", quartzClass);
			updateMap.put("remark", remark);
			updateMap.put("expression", cronStr);
			updateMap.put("quartzType", quartzType);
			this.baseQuartzConfigService.updateQuartzConfigById(updateMap);
			
			// 查询当前任务状态，如果是运行中状态则重启任务
			BaseQuartzConfigEntity currentEntity = baseQuartzConfigService.get(configId);
			if(currentEntity != null && "1".equals(currentEntity.getStatus())){
				mySchedulerFactory.pauseJob(configId);
				Thread.sleep(100);
				mySchedulerFactory.resumeJob(configId);
			}
			LogUtil.debug(this.getClass(),"用户"+ user.getTrueName()+"修改定时任务："+configId);
		} catch (Exception e) {
			 errCode="999";
			 errMsg="修改定时任务失败";
			 LogUtil.error(this.getClass(), "修改定时任务失败，原因:"+ExceptionDUtil.getDetailExceptionMsg(e));
		}
		
		responseMap.put("errCode", errCode);
		responseMap.put("errMsg", errMsg);
		return responseMap;
	}

	/**
	 * @description: 获取定时任务工厂中所有的任务
	 * @author thuang
	 * @date 2021/9/9 14:28
	 * @version 1.0
	 */
	@RequestMapping("/get_all_jobs")
	@ResponseBody
	public HashMap<Object,Object> getAllJobs() {
		HashMap<Object,Object> responseMap=new HashMap<>();


		List<HashMap<Object,Object>> quartzJobsVOList = new ArrayList<>();
		try {
			//获取Scheduler
			Scheduler scheduler = mySchedulerFactory.getScheduler();
			//再获取Scheduler下的所有group
			List<String> triggerGroupNames = scheduler.getTriggerGroupNames();
			for (String groupName : triggerGroupNames) {
				//组装group的匹配，为了模糊获取所有的triggerKey或者jobKey
				GroupMatcher groupMatcher = GroupMatcher.groupEquals(groupName);
				//获取所有的triggerKey
				Set<TriggerKey> triggerKeySet = scheduler.getTriggerKeys(groupMatcher);
				for (TriggerKey triggerKey : triggerKeySet) {
					//通过triggerKey在scheduler中获取trigger对象
					CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
					//获取trigger拥有的Job
					JobKey jobKey = trigger.getJobKey();
					JobDetailImpl jobDetail = (JobDetailImpl) scheduler.getJobDetail(jobKey);
					//组装页面需要显示的数据
					HashMap<Object,Object> map=new HashMap<>();
					map.put("configId",jobDetail.getName());
					map.put("groupName",groupName);
					map.put("cron",trigger.getCronExpression());
					quartzJobsVOList.add(map);
				}
			}
			responseMap.put("quartzJobsVOList",quartzJobsVOList);

		} catch (Exception e) {
			LogUtil.error(this.getClass(),"获取定时任务信息出错，原因："+e.getMessage());
		}
		return responseMap;
	}
	

	//获取cron表达式
	public String getCron(HashMap<Object, Object> map){
		
		String dataStr = StringDUtil.changeNullToEmpty(map.get("dataStr"));
		String time = StringDUtil.changeNullToEmpty(map.get("time"));
		
		//拼接cron表达式
		String cronStr= "";
		
		// 如果dataStr包含空格，说明是完整的cron表达式，直接返回
		if(StringDUtil.isNotBlank(dataStr) && dataStr.contains(" ")){
			return dataStr;
		}
		
		//拆分时分秒
		String[] split = dataStr.split(":");
		
		if(split.length==3){
			//先秒
			cronStr=cronStr+split[2]+" "; 
			//分
			cronStr=cronStr+split[1]+" "; 
			//时
			cronStr=cronStr+split[0]+" "; 
		}
		
		//每周
		if("1".equals(time)){
			String weekTime = StringDUtil.changeNullToEmpty(map.get("weekTime"));//周几
			
			cronStr=cronStr+"? * ";
			
			//国外第一天是礼拜天国内是礼拜一所以转一下
			if("7".equals(weekTime)){
				weekTime="1";
			}else{
				int week = Integer.parseInt(weekTime);
				weekTime=""+(week+1);
			}
			cronStr=cronStr+weekTime;
		}
		
		//每月
		if("2".equals(time)){
			String dayOfMonth = StringDUtil.changeNullToEmpty(map.get("dayOfMonth"));
			cronStr=cronStr+dayOfMonth+" * ?";
		}
		
		//每季度
		if ("3".equals(time)) {
			String month = StringDUtil.changeNullToEmpty(map.get("month"));//第几个月
			String dayOfMonth = StringDUtil.changeNullToEmpty(map.get("dayOfMonth"));
			cronStr=cronStr+dayOfMonth+" "+month+"/3 ?";
		}
		
		//每年
		if ("4".equals(time)) {
			String month = StringDUtil.changeNullToEmpty(map.get("month"));//那一个月
			String dayOfMonth = StringDUtil.changeNullToEmpty(map.get("dayOfMonth"));
			cronStr=cronStr+dayOfMonth+" "+month+" ?";
		}
		
		return cronStr;
	}



}
