package com.reptileclient.jlifeapp.schedule;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;

import com.reptileclient.jlifeapp.config.SendSms;
import com.reptileclient.jlifeapp.dao.hm.HmBookOrderMapper;
import com.reptileclient.jlifeapp.dao.hm.HmPaymentOrderMapper;
import com.reptileclient.jlifeapp.service.*;

import com.reptileclient.jlifeapp.util.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author fuxubing
 */
@Async
@Component
public class HmETLTask {
	private static final Logger logger = LoggerFactory.getLogger(HmETLTask.class);
	@Resource
	private HmBookOrderService hmBookOrderService;
	@Resource
	private HmPaymentOrderService hmPaymentOrderService;
	@Resource
	private HmPaymentOrderMapper paymentOrderMapper;

	@Resource
	private HmBookTradeOrderService hmBookTradeOrderService;

	@Resource
	private HmEncryptPhoneRepairService phoneRepairService;

	@Autowired
	SendSms sms;

	private static String runDate;
	
	private static DateTime tempEndTime;//抓付款单上次时间

	public void startJob() throws InterruptedException {
		if (LocalDateTime.now().getHour() == 8 && (StringUtils.isEmpty(runDate) || !runDate.equals(DateUtils.getCurrentDay()))) {
			runDate = DateUtils.getCurrentDay();
			this.runTask();
		}

		//每3小时 执行一次工单查询
		if (LocalDateTime.now().getHour() % 3 == 0)
			this.runDeleteTask();
	}


	/**
	 * 每天20点执行一次 更新和增量合成一个job 如果没有一条盒马数据，则全量跑 如有有盒马数据，只更新最近一个月的
	 * 注：
	 * 因为盒马在2023-6-1日对手机就行加密 发编译接口速度太慢 所以这些调优 规则如下
	 * 1, 第二步 更新hm_book_order表---此表phone明码 可以用来更新payment和trade_order
	 * 2，第二步hm_payment_order表
	 * 3，第三步 更新hm_book_trade_order表
	 * 4，根据hm_payment_order.payment_no更新2个服务表中的手机号（更新规则要前三、后四相同 因为存在预约手机和购买手机不是同一个）
	 * 5, hm_book_order，hm_book_trade_order表 如果还有未编译的手机号  统一接口更新
	 */
	@Scheduled(cron = "0 10 20 * * ?")
	public void runTask() throws InterruptedException {
		Timer timer = new Timer();
		TimerTask timerTask = new TimerTask() {
			@Override
			public void run() {
				logger.info("开始执行同步盒马数据");
				try {
					/********************第一步 抓取服务工单（创建时间和预约时间 2个维度）   创建时间 更新上个月->改为上周到现在的所有bookorder*/
					//新增只查询待履约的服务单、待派单
					//参数：服务单创建时间
					int row = hmBookOrderService.addBookOrderList();
					logger.info("执行完成盒马服务单总条数：{}", row);
					if (row == 0) {
						//经常出问题，重试一次 大约30分钟跑完
						row = hmBookOrderService.addBookOrderList();
						if (row == 0) {
							SendSms.toSendMs_null("bokodr");
						}

					}
					//更新只查询服务已提供、已完成、已取消；因为是服务完成 所以只需要取历史到今天的数据即可
					//参数：预约时间
					hmBookOrderService.syncUpdateByBookTime(DateUtil.offsetDay(new DateTime(), -10), new DateTime());
					hmBookOrderService.deleteDistinctData(DateUtil.today()); // 数据去重 删除存在与今日更新的数据

					/********************第二步 抓取支付单****************************/
					tempEndTime=new DateTime();
					DateTime offsetDay = DateUtil.offsetDay(new DateTime(), -2);
					row = hmPaymentOrderService.addPaymentOrderList(offsetDay);
					logger.info("执行完成支付单总条数：{}", row);
					if (row == 0) {
						row = hmPaymentOrderService.addPaymentOrderList(offsetDay);
						if (row == 0) {
							SendSms.toSendMs_null("paymtord");
						}
					}
					hmPaymentOrderService.deleteDistinctData(offsetDay);

					/******取消退款******/
					hmPaymentOrderService.updatePaymentOrderCancelOrder();//只取最近取消5页数据


					/********************第三步 获取从当前时间开始的新增服务单--******************************/
					//第一步 获取新增的预约单（前2天到后30天）
					row = hmBookTradeOrderService.addHmBookTradeList();
					logger.info("执行完成总条数runTask：{}", row);
					if (row == 0) {
						SendSms.toSendMs_null("boktrdod1");
					}
					//第二步更新历史服务单状态（前面15天到今天 服务已提供、已完成）
					hmBookTradeOrderService.updateHmBookTradeList(DateUtil.offsetDay(DateTime.now(), -10), DateTime.now());

					logger.info("第二步更新历史服务单状态---完成");
					//第三步 已取消的 （前面2天到后面10天 20240314改为前7后7天）
					hmBookTradeOrderService.deleteHmBookTradeList(DateUtil.offsetDay(DateTime.now(), -7), DateUtil.offsetDay(DateTime.now(), 7));
					logger.info("第三步 已取消的---完成");

					/******************第四步 根据payment表 更新2个从表*******************************/
					paymentOrderMapper.sp_update_phone_by_payment();
					logger.info("第四步---完成");

					/********************第五步 统一修复不正确的手机号*****************************/
					phoneRepairService.repair();


					logger.info("结束执行同步盒马数据");

				} catch (Exception e) {
					SendSms.toSendMs();
					e.printStackTrace();
				}
			}
		};
		timer.schedule(timerTask, this.getWaitTime("每日定时盒马数据"));
	}




	/**
	 * 每3小时抓取盒马取消的工单并依据工单号将trade_order中该数据删除
	 */
	@Scheduled(cron = "0 0 7-18/3 * * ?")
	public void runDeleteTask() throws InterruptedException {

		Timer timer = new Timer();
		TimerTask timerTask = new TimerTask() {
			@Override
			public void run() {
				logger.info("开始执行删除当日已取消的工单数据删除");
				try {//因为服务者小程序用hm_book_trade_order 数据实时性高，防止当日取消后面2天的工单没刷新
					int row = hmBookTradeOrderService.deleteHmBookTradeList(DateUtil.beginOfDay(DateTime.now()), DateUtil.offsetDay(DateTime.now(), 1));
					logger.info("执行完成总条数runDeleteTask：{}", row);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};

		timer.schedule(timerTask, this.getWaitTime("取消工单删除"));

	}
	
	
	 /**
     *  每2小时抓取一次付款单PaymentOrder
     */
    @Scheduled(cron="0 20 7-19/2 * * ?")
    public void runTaskForHourly(){
    	
    	Timer timer = new Timer();
		TimerTask timerTask = new TimerTask() {
			@Override
			public void run() {
			        try {
			        	DateTime start=DateUtil.beginOfDay(DateUtil.parse(DateUtil.now()));//默认当天0点
			        	if(tempEndTime != null) {//后续都从上次时间开始
			        		start=tempEndTime;
			        	} 
			        	tempEndTime=new DateTime();
			        	
			        	logger.info("开始每2小时执行同步盒马服务付款单数据"+start);
			            int row = hmPaymentOrderService.addPaymentOrderList(start);
			            logger.info("每2小时执行同步盒马服务付款单数据总条数：{}", row);
			 
						paymentOrderMapper.sp_update_phone_by_payment();
						phoneRepairService.repair();
						
						logger.info("每2小时执行同步盒马服务付款单数据完成");
			        } catch (Exception e) {
			            e.printStackTrace();
			        }
			}
		};

		timer.schedule(timerTask, this.getWaitTime("每2小时执行同步盒马服务付款单数据完成"));
    }

	//获取随机等待时间1-60分钟
	public Long getWaitTime(String jobName) {
		int waitTime = new Random().nextInt(30);
		logger.info("等待 " + waitTime + " 分后执行脚本--" + jobName);
		return (long) waitTime * 60 * 1000;
	}

	public static void main(String[] args) throws InterruptedException {
//		System.out.println(DateUtil.beginOfDay(DateUtil.parse(DateUtil.now())));
	}

}
