package com.bcxin.ins.coninsweb.scheduling;

import com.bcxin.ins.service.order.ComTaskResidualAPIService;
import com.bcxin.ins.service.order.PolicyService;
import com.bcxin.ins.service.preservation.InsPreservationPayAPIService;
import com.bcxin.ins.service.preservation.InsPreservationRecordAPIService;
import com.bcxin.ins.service.preservation.InsPreservationResultSetAPIService;
import com.bcxin.ins.core.entity.SysLog;
import com.bcxin.ins.core.service.ComDeployConfigService;
import com.bcxin.ins.core.service.SysLogService;
import com.bcxin.ins.service.product.InsProductAPIService;
import com.bcxin.ins.spring.util.JedisUtils;
import com.bcxin.ins.util.DateUtil;
import com.bcxin.ins.vo.ConstProp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.Date;

@Component
@Lazy(false)
public class Scheduling {
	
	private  static Logger logger = LoggerFactory.getLogger(Scheduling.class);

	@Autowired
	SysLogService logS;

	@Autowired
	private PolicyService policyService;

	@Autowired
	private ComDeployConfigService comDeployConfigService;

	@Autowired
	private InsPreservationPayAPIService insPreservationPayAPIService;

	@Autowired
	private InsProductAPIService insProductAPIService;

	@Autowired
	private InsPreservationRecordAPIService insPreservationRecordAPIService;
	@Autowired
	private InsPreservationResultSetAPIService insPreservationResultSetAPIService;
	@Autowired
	private ComTaskResidualAPIService comTaskResidualAPIService;

//	@Autowired
//	private ShipmentReceiveAmountsServiece shipmentReceiveAmountsServiece;
//
//	@Autowired
//	private ShipmentDeclarationService shipmentDeclarationService;

//	public Scheduling(){
//		logger.info("时间"+dateFormat);
//	}
	//@Scheduled(fixedDelay=1000)  //第一种方式
	//fixedDelay延时多少毫秒，多少毫秒执行一次
	//@Scheduled(cron="0 * * * * *")     //第二种方式
	//1 Seconds (0-59)
	//2 Minutes (0-59)
	//3 Hours (0-23)
	//4 Day of month (1-31)
	//5 Month (1-12 or JAN-DEC)
	//6 Day of week (1-7 or SUN-SAT)
	//7 Year (1970-2099)
	//取值：可以是单个值，如6；
	//	也可以是个范围，如9-12；
	//	也可以是个列表，如9,11,13
	//	也可以是任意取值，使用*
	//0 * * * * * 代表每分钟执行一次
	//•"0 0 * * * *" = the top of every hour of every day.
	//•"*/10 * * * * *" = every ten seconds.
	//•"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.
	//•"0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day.
	//•"0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays
	//•"0 0 0 25 12 ?" = every Christmas Day at midnight
	/*@Scheduled(cron="0 0/30 * * * *")*/

	/*@Scheduled(fixedDelay = 180000)
	public void testTimer() throws Exception { //测试
		System.out.println("----------:testTimer:start!");
		policyService.HTTP_TPC_XYX_CB(991611013647409153L);
		System.out.println("----------:testTimer:end!");
	}*/

	@Scheduled(cron="0 0 23 * * ?")
	public void Policy_overdue() throws ParseException { //改待支付保单为已过期
		try{
			policyService.findPolicyListByLapsed();
			logS.save(getLog(null,"1","定时任务-改待支付保单为已过期"));
		}catch (Exception ex){
			logger.error("",ex);
			logS.save(getLog(ex,"2","定时任务-改待支付保单为已过期"));
		}
	}

	@Scheduled(cron="0 30 1 * * ?")
	public void policyExpireInform() throws ParseException {
		try{
			policyService.policyExpireInform();
			logS.save(getLog(null,"1","定时任务-检索即将到期或已到期保单发送邮件"));
		}catch (Exception ex){
			logger.error("",ex);
			logS.save(getLog(ex,"2","定时任务-检索即将到期或已到期保单发送邮件"));
		}
	}

//	@Scheduled(cron="0 0 0 1/1 * ?")//每天零点执行一次
//	public void calculateShipmentOverDueStatus(){ //出运逾期判断
//		shipmentReceiveAmountsServiece.calculateShipmentOverDueStatus();
//	}

	@Scheduled(cron="0 0 0 1/1 * ?")//每天零点执行一次
	public void closeCopyCount(){ //清除每天订单复制次数缓存
		JedisUtils.batchDel(ConstProp.REDIS_HEAD_CPOY);
	}

	@Scheduled(cron="0 15 12,15,18 * * ?")
	public void policyEndStatus() throws ParseException{ //对接太保：接口107002，通过投保单号查找保单号设置保单状态
		try {
			policyService.policyEndStatus("");
			logS.save(getLog(null,"1","定时任务-对接太保：接口107002，通过投保单号查找保单号设置保单状态"));
		}catch (Exception ex){
			logger.error("定时任务-policyEndStatus",ex);
			logS.save(getLog(ex,"2","定时任务-对接太保：接口107002，通过投保单号查找保单号设置保单状态"));
		}
	}

	@Scheduled(cron="0 0 12,18,22 * * ?")
	public void TYX_TK_02() throws ParseException{ //团意险查询待支付订单列表调泰康02查询保单接口获取保单号并保存（批量处理）
	    try {
	    	policyService.TYX_TK_02();
			logS.save(getLog(null,"1","定时任务-团意险查询待支付订单列表调泰康02查询保单接口获取保单号并保存"));
		}catch (Exception ex){
			logger.error("定时任务-TYX_TK_02",ex);
			logS.save(getLog(ex,"2","定时任务-团意险查询待支付订单列表调泰康02查询保单接口获取保单号并保存"));
		}
	}

	@Scheduled(cron="0 40 11,17,21 * * ?")
	public void XYX_TB_CB() throws ParseException{ //小微信用险查询待承保订单列表调太保承保接口获取保单号并保存
	    try {
	    	policyService.XYX_TB_CB();
			logS.save(getLog(null,"1","定时任务-小微信用险查询待承保订单列表调太保承保接口获取保单号并保存"));
		}catch (Exception ex){
			logger.error("定时任务-XYX_TB_CB",ex);
			logS.save(getLog(ex,"2","定时任务-小微信用险查询待承保订单列表调太保承保接口获取保单号并保存"));
		}
	}

	/**
	 * 定时次月第一天的00:00点查询暂存状态的保全缴费单列表并重置状态为待处理
	 * @throws ParseException
	 */
	/*@Scheduled(cron="0 0 0 1 * ?")*/
	@Scheduled(cron="0 0 0 1 * ?")
	public void activateInsPreservationPay_month(){
	    try {
			insPreservationPayAPIService.findInsPreservationPayByPaymentType("2");
			logS.save(getLog(null,"1","定时任务-次月第一天的00:00点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}catch (Exception ex){
			logger.error("定时任务-activateInsPreservationPay_month",ex);
			logS.save(getLog(ex,"2","定时任务-次月第一天的00:00点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}
	}

	/**
	 * 定时每月第一天的00:10点生成保单初始月结账单记录
	 * @throws ParseException
	 */
	/*@Scheduled(cron="0 0 0 1 * ?")*/
//	@Scheduled(cron="0 10 0 1 * ?")
	@Scheduled(cron="0 1 * * * ?")
	public void initInsPreservationPayThisMonth(){
	    try {
			Date star = DateUtil.convertString2Date(DateUtil.convertDateToString(DateUtil.getFirstDayOfThisMonth(),DateUtil.FORMAT2)+" 00:00:00");
			Date end = DateUtil.convertString2Date(DateUtil.convertDateToString(DateUtil.getLastDayOfThisMonth(),DateUtil.FORMAT2)+" 23:59:59");
//			insPreservationPayAPIService.createInsPreservationPayByThisMonth("",star,end);
			logS.save(getLog(null,"1","定时任务-次月第一天的00:10点生成保单初始月结账单记录"));
		}catch (Exception ex){
			logger.error("定时任务-initInsPreservationPayThisMonth",ex);
			logS.save(getLog(ex,"2","定时任务-次月第一天的00:10点生成保单初始月结账单记录"));
		}
	}

	/**
	 * 定时次季度第一天的00:20点查询暂存状态的保全缴费单列表并重置状态为待处理
	 * @throws ParseException
	 */
	/*@Scheduled(cron="0 20 0 1 3,6,9,12 ?")*/
	@Scheduled(cron="0 20 0 2 3,6,9,12 ?")
	public void activateInsPreservationPay_quarter(){
	    try {
			insPreservationPayAPIService.findInsPreservationPayByPaymentType("3");
			logS.save(getLog(null,"1","定时任务-次季度第一天的00:20点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}catch (Exception ex){
			logger.error("定时任务-activateInsPreservationPay_quarter",ex);
			logS.save(getLog(ex,"2","定时任务-次季度第一天的00:20点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}
	}

	/**
	 * 定时次半年第一天的00:40点查询暂存状态的保全缴费单列表并重置状态为待处理
	 * @throws ParseException
	 */
	@Scheduled(cron="0 40 0 1 6,12 ?")
	public void activateInsPreservationPay_semester(){
		try {
			insPreservationPayAPIService.findInsPreservationPayByPaymentType("4");
			logS.save(getLog(null,"1","定时任务-次半年第一天的00:40点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}catch (Exception ex){
			logger.error("定时任务-activateInsPreservationPay_semester",ex);
			logS.save(getLog(ex,"2","定时任务-次半年第一天的00:40点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}
	}

	/**
	 * 定时次年第一天的01:00点查询暂存状态的保全缴费单列表并重置状态为待处理
	 * @throws ParseException
	 */
	@Scheduled(cron="0 0 0 1 1 ?")
	public void activateInsPreservationPay_year(){
		try {
			insPreservationPayAPIService.findInsPreservationPayByPaymentType("5");
			logS.save(getLog(null,"1","定时任务-次年第一天的01:00点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}catch (Exception ex){
			logger.error("定时任务-activateInsPreservationPay_month",ex);
			logS.save(getLog(ex,"2","定时任务-次年第一天的01:00点查询暂存状态的保全缴费单列表并重置状态为待处理"));
		}
	}

	/**
	 * 每天定时跑保全申请单中已审核的单子如果生效日期小于当前日期就变更状态为已生效
	 * @throws ParseException
	 */
	@Scheduled(cron="0 15 1 * * ?")
	public void setInsPreservationRecordStatus(){
		try {
			insPreservationRecordAPIService.setInsPreservationRecordStatus();
			logS.save(getLog(null,"1","定时任务-每天定时跑保全申请单中已审核的单子如果生效日期小于当前日期就变更状态为已生效"));
		}catch (Exception ex){
			logger.error("定时任务-setInsPreservationRecordStatus",ex);
			logS.save(getLog(ex,"2","定时任务-每天定时跑保全申请单中已审核的单子如果生效日期小于当前日期就变更状态为已生效"));
		}
	}

	/**
	 * 一些第三方推送接口执行不成功或者有需要进行推送任务记录到表中，通过定时器半小时跑一次，进行遗留历史任务重复推送
	 * @throws ParseException
	 */
	@Scheduled(cron="0 0/3 * * * ?")
	public void disposeComTaskResidual(){
		try {
			comTaskResidualAPIService.disposeComTaskResidualList("0");
//			logS.save(getLog(null,"1","定时任务-查询表记录通过各属性反射出对应方法并执行"));
		}catch (Exception ex){
			logger.error("定时任务-disposeComTaskResidual",ex);
//			logS.save(getLog(ex,"2","定时任务-查询表记录通过各属性反射出对应方法并执行"));
		}
	}

	/**
	 * 一些第三方推送接口执行不成功或者有需要进行推送任务记录到表中，通过定时器每天3点跑一次，进行遗留历史任务重复推送
	 * @throws ParseException
	 */
	@Scheduled(cron="0 0 3 * * ?")
	public void disposeComTaskResidual2() throws ParseException {
		try {
			comTaskResidualAPIService.disposeComTaskResidualList("1");
			logS.save(getLog(null,"1","定时任务-查询表记录通过各属性反射出对应方法并执行(夜间执行)"));
		}catch (Exception ex){
			logger.error("定时任务-disposeComTaskResidual2",ex);
			logS.save(getLog(ex,"2","定时任务-查询表记录通过各属性反射出对应方法并执行(夜间执行)"));
		}
	}

	//平安获取token定时器废弃（目前都实时请求获取）
	/*@Scheduled(cron="0 0 1 * * *")
	public void setPianAnCode(){
		//cron="0 0 1 * * *"
		//设置平安code 防止过期
		String  url=  GlobalResources.PNS_GET_ACCESS_TOKEN_URL;
		//发送 GET 请求
		logger.info("===========================PNS_GET_ACCESS_TOKEN_URL-START======================");
		try {
			String s= RequestUtil.sendGet(url, null);
			if(StringUtils.isNotEmpty(s)){
				JSONObject json= JSON.parseObject(s);
				String status=json.get("ret").toString();
				if("0".equals(status)){
					String data=json.getString("data");
					logger.info("平安返回值："+data);
					JSONObject result=JSONObject.parseObject(data);
					ComDeployConfig config= new ComDeployConfig();
					config.setConfig_type(GlobalResources.ENVI);
					config.setConfig_key("PN_ACCESS_TOKEN");
					//new EntityWrapper<SysRoleMenu>().addFilter("role_id={0}",roleId)
					ComDeployConfig  configNow =comDeployConfigService.selectOne(new EntityWrapper<>(config));
					configNow.setConfig_value(result.getString("PN_ACCESS_TOKEN"));
					comDeployConfigService.updateById(configNow);
					GlobalResources.PN_ACCESS_TOKEN=result.getString("PN_ACCESS_TOKEN");
					logger.info("===========================PNS_GET_ACCESS_TOKEN_URL-END======================");

				}
			}
			logS.save(getLog(null,"1","定时任务-设置平安code 防止过期"));
		}catch (Exception ex){
			logger.error("ACCESS_TOKEN",ex);
			logS.save(getLog(ex,"2","定时任务-设置平安code 防止过期"));
		}
	}*/

	/*@Scheduled(cron="0 0 8,19 * * *")
	public void recordPush() throws ParseException { //查找外部平台已审核的保全申请单推送，同时变更保全单状态为已推送
		try{
			List<String> strList = new ArrayList<String>();
			List<String> arsList = insPreservationRecordAPIService.selectRecordIdByWebType("ARS");
			List<String> saasList = insPreservationRecordAPIService.selectRecordIdByWebType("SAAS");
			strList.addAll(arsList);
			strList.addAll(saasList);
			for(String str : strList){
				policyService.pushRecordInfo(str);
			}
			logS.save(getLog(null,"1","定时任务-保全已生效或已审核的外部平台下的保全单推送"));
		}catch (Exception ex){
			logger.error("",ex);
			logS.save(getLog(ex,"2","定时任务-保全已生效或已审核的外部平台下的保全单推送"));
		}
	}*/

	@Scheduled(cron="0 35 0 * * *")
	public void gainDZBDByTiming() throws ParseException { //查询已承保但未获取电子保单的订单，定时跑接口查询
		try{
			policyService.gainDZBDByTiming();
			logS.save(getLog(null,"1","定时任务-查询已承保但未获取电子保单的订单"));
		}catch (Exception ex){
			logger.error("",ex);
			logS.save(getLog(ex,"2","定时任务-查询已承保但未获取电子保单的订单"));
		}
	}

	@Scheduled(cron="0 15 0 * * *")
	public void initAllOrderToResultSet() throws ParseException { //初始化有效订单的保全结果集（复制在保人员信息到结果集表）
		try{
			String[] arr = {ConstProp.TYX, ConstProp.GZZRX};
			for (int i = 0; i < arr.length; i++) {
				insPreservationResultSetAPIService.initAllOrderToResultSet(arr[i]);
			}
			logS.save(getLog(null,"1","定时任务-初始化有效订单的保全结果集（复制在保人员信息到结果集表）"));
		}catch (Exception ex){
			logger.error("",ex);
			logS.save(getLog(ex,"2","定时任务-初始化有效订单的保全结果集（复制在保人员信息到结果集表）"));
		}
	}

	private SysLog getLog(Exception ex,String type,String title) {
		SysLog sysLog = new SysLog();
		sysLog.setCreateTime(new Date());
		if (ex != null){
			sysLog.setException(ex.toString());
		}
		sysLog.setType(type);
		sysLog.setTitle(title);
		return sysLog;
	}
}
