package com.dxhy.core.task;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.core.dao.BasisSysDeptCfgDao;
import com.dxhy.core.entity.BasisSysDeptCfg;
import com.dxhy.core.entity.TDxRecordInvoice;
import com.dxhy.core.job.entity.ScheduleJobEntity;
import com.dxhy.core.job.entity.TAcOrg;
import com.dxhy.core.job.thread.CheckHandler;
import com.dxhy.core.job.service.CheckOneService;
import com.dxhy.core.job.service.ScheduleJobService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 普票、二手车查验更新查验状态
 */
@Component("checkOneTask")
@Slf4j
public class CheckOneTask {

    @Resource
    private ScheduleJobService scheduleJobService;

    @Resource
    private CheckOneService checkOneService;

    @Value("${checkThreadNum}")
    private Integer threadNum;

    @Value("${checkDayNum}")
    private Integer totalCount;

    @Value("${checkRows}")
    private Integer rows;
    @Resource
    private BasisSysDeptCfgDao basisSysDeptCfgDao;

    /**
     * 历史普票、二手车进行查验更新查验状态
     */
    public void checkOneInvoice() {
        log.info("-------------普票查验更新状态任务开始----------------");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.queryByBeanName("checkOneTask", "checkOneInvoice");
        if (scheduleJobEntity != null && "0".equals(scheduleJobEntity.getJobStatus())) {
            try {
                scheduleJobEntity.setJobStatus("1");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
                //获取定时任务所需要的配置文件
                String checkConfig = checkOneService.getConfigValus("CHECK_CONFIG");
                List<TAcOrg> taxNoList = checkOneService.getTaxNo();
                if (StringUtils.isNotBlank(checkConfig)) {
                    JSONObject parse = JSONObject.parseObject(checkConfig);
                    Integer threadNums = (Integer) parse.get("threadNum");
                    Integer totalCounts = (Integer) parse.get("totalCount");
                    Integer row = (Integer) parse.get("rows");
                    if (totalCounts > 0 && threadNums > 0 && row > 0) {
                        threadNum = threadNums;
                        totalCount = totalCounts;
                        rows = row;
                    }
                }
                log.info("普票查验更新状态,threadNum{},totalCount{},rows{}",threadNum,totalCount,rows);
                if (!CollectionUtils.isEmpty(taxNoList)) {
                    // 设置请求线程池
                    ThreadPoolExecutor executor = new ThreadPoolExecutor(threadNum,
                            threadNum * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(totalCount),
                            r -> new Thread(r, "查验补全定时任务-" + r.hashCode()));
                    int tempCount = 0;
                    boolean contin = true;
                    for (TAcOrg taxOrg : taxNoList) {
                        DynamicContextHolder.push(DbConstant.BASICS_READ);
                        //判断是否为大企业税号
                        BasisSysDeptCfg baseSysDeptCfg = basisSysDeptCfgDao.selectOne(new QueryWrapper<BasisSysDeptCfg>().eq("nsrsbh", taxOrg.getTaxno()));
                        if (baseSysDeptCfg != null) {
                            continue;
                        }
                        while (contin) {
                            DynamicContextHolder.push(taxOrg.getDbName() + DbConstant.BUSINESS_READ);
                            List<TDxRecordInvoice> dxList = checkOneService.getRecordList(taxOrg.getTaxno(), rows);
                            if (dxList != null && dxList.size() > 0) {
                                log.info("-----------普票查验更新状态本批次处理开始-------" + tempCount + "----" + dxList.size());
                                for (TDxRecordInvoice recordInvoice : dxList) {
                                    DynamicContextHolder.push(taxOrg.getDbName() + DbConstant.BUSINESS_WRITE);
                                    checkOneService.updateStatus(recordInvoice.getInvoiceCode() + recordInvoice.getInvoiceNo());
                                    executor.submit(new CheckHandler(recordInvoice,taxOrg));
                                }
                                log.info("-----------普票查验更新状态本批次处理结束-------" + tempCount + "----" + dxList.size());
                            } else {
                                contin = false;
                            }
                            tempCount += rows;
                            if (tempCount >= totalCount) {
                                contin = false;
                            }
                        }
                    }
                    executor.shutdown();
                    executor.awaitTermination(60, TimeUnit.SECONDS);
                }
                log.info("---------------普票查验更新状态任务结束--------------");
            } catch (Exception e) {
                e.printStackTrace();
                log.error("---------------普票查验更新状态任务异常,{}--------------", e.getMessage());
            } finally {
                log.info("---------------普票查验更新状态任务重置--------------");
                scheduleJobEntity.setJobStatus("0");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
            }
        }
    }

    /**
     * 历史普票、二手车查验失败发票重置为未查验
     */
    public void checkFailUpdate() {
        log.info("-------------查验失败状态重置开始----------------");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.queryByBeanName("checkOneTask", "checkFailUpdate");
        if (scheduleJobEntity != null && "0".equals(scheduleJobEntity.getJobStatus())) {
            try {
                scheduleJobEntity.setJobStatus("1");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
                List<TAcOrg> taxNoList = checkOneService.getTaxNo();
                if (!CollectionUtils.isEmpty(taxNoList)) {
                    for (int i = 0; i < taxNoList.size(); i++) {
                        TAcOrg tacOrg = taxNoList.get(i);
                        DynamicContextHolder.push(DbConstant.BASICS_READ);
                        //判断是否为大企业税号
                        BasisSysDeptCfg baseSysDeptCfg = basisSysDeptCfgDao.selectOne(new QueryWrapper<BasisSysDeptCfg>().eq("nsrsbh", tacOrg.getTaxno()));
                        if (baseSysDeptCfg != null) {
                            continue;
                        }
                        checkOneService.updateFailStatus(tacOrg);
                    }
                }
                log.info("-------------查验失败状态重置结束----------------");
            } catch (Exception e) {
                e.printStackTrace();
                log.error("-------------查验失败状态重置异常，{}-------------", e.getMessage());
            } finally {
                log.info("-------------查验失败状态重置任务重置-------------");
                scheduleJobEntity.setJobStatus("0");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
            }
        }
    }

    public void threeMonthCheck() {
        log.info("----------三个月普票查验更新状态任务开始----------");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.queryByBeanName("checkOneTask", "threeMonthCheck");
        if (scheduleJobEntity != null && "0".equals(scheduleJobEntity.getJobStatus())) {
            try {
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobEntity.setJobStatus("1");
                scheduleJobService.updateById(scheduleJobEntity);

                String checkConfig = checkOneService.getConfigValus("threeMonthCheck");
                if (StringUtils.isNotBlank(checkConfig)) {
                    JSONObject parse = JSONObject.parseObject(checkConfig);
                    Integer threadNums = (Integer) parse.get("threadNum");
                    Integer totalCounts = (Integer) parse.get("totalCount");
                    Integer row = (Integer) parse.get("rows");
                    if (totalCounts > 0 && threadNums > 0 && row > 0) {
                        threadNum = threadNums;
                        totalCount = totalCounts;
                        rows = row;
                    }
                }
                log.info("普票查验更新状态,threadNum{},totalCount{},rows{}",threadNum,totalCount,rows);

                List<TAcOrg> taxNoList = checkOneService.getTaxNo();
                if (!CollectionUtils.isEmpty(taxNoList)) {
                    ThreadPoolExecutor executor = new ThreadPoolExecutor(threadNum,
                            threadNum * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(totalCount),
                            r -> new Thread(r, "查验补全定时任务-" + r.hashCode()));
                    int tempCount = 0;
                    boolean contin = true;
                    for (TAcOrg tAcOrg : taxNoList) {
                        DynamicContextHolder.push(DbConstant.BASICS_READ);
                        //判断是否为大企业税号
                        BasisSysDeptCfg baseSysDeptCfg = basisSysDeptCfgDao.selectOne(new QueryWrapper<BasisSysDeptCfg>().eq("nsrsbh", tAcOrg.getTaxno()));
                        if (baseSysDeptCfg != null) {
                            continue;
                        }
                        while (contin) {
                            DynamicContextHolder.push(tAcOrg.getDbName() + DbConstant.BUSINESS_READ);
                            List<TDxRecordInvoice> dxList = checkOneService.getRecordListThreeMonth(tAcOrg.getTaxno(), rows);
                            if (dxList != null && dxList.size() > 0) {
                                log.info("-----------三个月普票查验更新状态本批次处理开始-------" + tempCount + "----" + dxList.size());
                                for (TDxRecordInvoice recordInvoice : dxList) {
                                    checkOneService.updateStatus(recordInvoice.getInvoiceCode() + recordInvoice.getInvoiceNo());
                                    executor.submit(new CheckHandler(recordInvoice,tAcOrg));
                                }
                                log.info("-----------三个月普票查验更新状态本批次处理结束-------" + tempCount + "----" + dxList.size());
                            } else {
                                contin = false;
                            }
                            tempCount += rows;
                            if (tempCount >= totalCount) {
                                contin = false;
                            }
                        }
                    }
                    executor.shutdown();
                    executor.awaitTermination(60, TimeUnit.SECONDS);
                }
                log.info("---------------三个月普票查验更新状态任务结束--------------");
            } catch (Exception e) {
                e.printStackTrace();
                log.error("----------三个月普票查验更新状态任务异常，{}----------", e.getMessage());
            } finally {
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobEntity.setJobStatus("0");
                scheduleJobService.updateById(scheduleJobEntity);
            }
        }
    }

}
