package cn.superdesk.uniorder.executor.scheduler.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.pagination.PageQueryParam;
import cn.superdesk.uniorder.common.queue.block.BaseTask;
import cn.superdesk.uniorder.common.queue.block.TaskInterface;
import cn.superdesk.uniorder.common.queue.block.TaskPriorityEnum;
import cn.superdesk.uniorder.common.queue.block.TaskScheduler;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.dao.entity.scheduler.SysQuartzScheduleTaskStatementOfAccount;
import cn.superdesk.uniorder.dubbo.consumer.scheduler.SysQuartzScheduleTaskStatementOfAccountDubboConsumerService;
import cn.superdesk.uniorder.common.mq.kafka.producer.FakeSuperdeskUniOrderProducerHandler;
import cn.superdesk.uniorder.common.numerical.AnCollectionUtils;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;


/**
 * @Description: 外层调度 任务执行 生成对账单 目前是有问题的
 * @Author: linjinyu
 * @CreateDate: 2020/12/23 下午4:51
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/12/23 下午4:51
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Component
public class StatementOfAccountDimOrderTask {

	private StatementOfAccountDimOrderTask() {
		log.info("call StatementOfAccountDimOrderTask 构建方法");
	}

//	@Resource
//	private ExecutorService executorService;

//	@Resource
//	private StandardThreadExecutor standardThreadExecutor;

	@Resource
	private FakeSuperdeskUniOrderProducerHandler fakeSuperdeskUniOrderProducerHandler;

	@Resource
	private SysQuartzScheduleTaskStatementOfAccountDubboConsumerService sysQuartzScheduleTaskStatementOfAccountDubboConsumerService;

	public void run(String params) {

//		log.info("String params {}", params);

		PageQueryParam pageQueryParam = AnJsonUtils.toObject(params, PageQueryParam.class);

//		log.info("PageQueryParam {}", JsonUtils.toJson(pageQueryParam));

		List<SysQuartzScheduleTaskStatementOfAccount> result = sysQuartzScheduleTaskStatementOfAccountDubboConsumerService.getToDoSysQuartzScheduleTaskStatementOfAccountList(
				pageQueryParam.getPageNo(),
				pageQueryParam.getPageSize()
		);

//		log.info("StatementOfAccountDimOrderTask 一层调度 , TODO size : {}", result.size());

		if (AnCollectionUtils.isNotEmpty(result)) {

			for (SysQuartzScheduleTaskStatementOfAccount entity : result) {

				/****************************************** 试验 kafka 效果还是不好 start ******************************************/
//				fakeSuperdeskUniOrderProducerHandler.kafkaStatementOfAccountDimOrderTask(entity);
				/****************************************** 试验 kafka 效果还是不好   end ******************************************/

				/****************************************** 试验 线程 达不到目的效果 start ******************************************/
//				executorService.execute(() -> runTask(entity));
//				standardThreadExecutor.execute(() -> runTask(entity));
				/****************************************** 试验 线程 达不到目的效果   end ******************************************/

				/****************************************** 此方案 只要服务器不死 不重启是没问题的 start ******************************************/
				TaskScheduler.getInstance().enqueue(new _StatementOfAccountDimOrderTask(
						StrUtil.format("#{}-{}#", TaskPriorityEnum.NICE_TO_HAVE, DateUtil.now()))
						.setDuration(0)
						.setPriority(TaskPriorityEnum.NICE_TO_HAVE)
						.setTaskParamsJson(AnJsonUtils.toJson(entity))
				);
				/****************************************** 此方案 只要服务器不死 不重启是没问题的 start ******************************************/
			}
		}


//		executorService.shutdown();


	}

	/**
	 * @param entity
	 */
	private synchronized void runTask(SysQuartzScheduleTaskStatementOfAccount entity) {

		log.info("\nStatementOfAccountDimOrderTask 二层执行\nrunTask \n{}", AnJsonUtils.toJson(entity));

		sysQuartzScheduleTaskStatementOfAccountDubboConsumerService.runTaskSysQuartzScheduleTaskStatementOfAccount(JwtUtil.FORGED_BACKEND_TOKEN, entity);

		log.info("StatementOfAccountDimOrderTask 任务完成");
	}

	public class _StatementOfAccountDimOrderTask extends BaseTask {

		private String taskName;

		private SysQuartzScheduleTaskStatementOfAccount entity;

		public _StatementOfAccountDimOrderTask(String taskName) {
			this.taskName = taskName;
		}

		/**
		 * 简单写吧
		 *
		 * @param taskParamsJson
		 * @return
		 */
		@Override
		public TaskInterface setTaskParamsJson(String taskParamsJson) {

			entity = AnJsonUtils.toObject(taskParamsJson, SysQuartzScheduleTaskStatementOfAccount.class);
			return this;
		}

//		public TaskInterface setEntity(SysQuartzScheduleTaskStatementOfAccount entity) {
//			this.entity = entity;
//
//		}

		// 执行任务方法,在这里实现你的任务具体内容
		@Override
		public void doTask() {
			log.info("LogTask-{}-doTask start", taskName);
			super.doTask();


			/****************************************** 回调的方案有空再弄吧 start ******************************************/
			// 如果这个Task的执行时间是不确定的,成功后需要手动调用
			// unLockBlock方法解除阻塞,例如:
			// doWhat(new CallBackInterface {
			// 	void onSuccess () {
			// 		unLockBlock();
			// 	}
			// });
			/****************************************** 回调的方案有空再弄吧 start ******************************************/

			/****************************************** 模拟任务执行耗时 start ******************************************/
			// long c = RandomUtil.randomLong(1000L, 9999L);
			// log.info("LogTask-{}-doTask 耗时 {}ms", taskName, c);
			// ThreadUtil.sleep(c);
			/****************************************** 模拟任务执行耗时 start ******************************************/

			log.info("\nStatementOfAccountDimOrderTask 二层执行\nrunTask \n{}", AnJsonUtils.toJson(entity));

			try {
				sysQuartzScheduleTaskStatementOfAccountDubboConsumerService.runTaskSysQuartzScheduleTaskStatementOfAccount(JwtUtil.FORGED_BACKEND_TOKEN, entity);
			} catch (Exception e) {
				e.printStackTrace();
				// TODO 再作个记录吧
			} finally {
				log.info("StatementOfAccountDimOrderTask 任务完成");
				unLockBlock();
			}


			log.info("LogTask-{}-doTask   end", taskName);
		}

		// 任务执行完的回调,在这里你可以做些释放资源或者埋点之类的操作
		@Override
		public void finishTask() {
			super.finishTask();
			log.info("LogTask-{}-finishTask", taskName);
		}
	}
}
