package com.dxhy.core.task;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dxhy.core.dao.BasisSysDeptCfgDao;
import com.dxhy.core.entity.BasisSysDeptCfg;
import com.dxhy.core.job.entity.ScheduleJobEntity;
import com.dxhy.core.job.service.ScheduleJobService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.core.dao.ConfirmDao;
import com.dxhy.core.job.pojo.CheckNoDetailInvoice;
import com.dxhy.core.job.service.CheckTaskService;
import com.dxhy.core.thread.CheckThread;

import lombok.extern.slf4j.Slf4j;

/**
 * 查验定时任务
 *
 * @author hp
 **/
@Component("checkTask")
@Slf4j

public class CheckTask {

    @Resource
    private CheckTaskService checkTaskService;
    @Resource
    private ConfirmDao confirmDao;
    @Resource
    private ScheduleJobService scheduleJobService;
    @Value("${check.corePoolSize}")
    private int corePoolSize;
    @Value("${check.maximumPoolSize}")
    private int maximumPoolSize;
    @Resource
    private BasisSysDeptCfgDao basisSysDeptCfgDao;

    public void checkInvoice() {
        log.info("发票查验执行开始--");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.queryByBeanName("checkTask","checkInvoice");
        if (scheduleJobEntity!=null && "0".equals(scheduleJobEntity.getJobStatus())){
            try {
                scheduleJobEntity.setJobStatus("1");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
                // 查询需要补全明细的数据
                // 查询需要遍历的数据库
                // 查询数据库 遍历数据源
                DynamicContextHolder.push(DbConstant.BASICS_READ);
                List<String> dbList = confirmDao.getDbSource();
                for (String db : dbList) {
                    DynamicContextHolder.push(db + DbConstant.BUSINESS_READ);
                    List<CheckNoDetailInvoice> list = checkTaskService.getNoDetailInvoice();
                    if (list!=null && list.size()>0){
                        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 5, TimeUnit.SECONDS,
                                new LinkedBlockingQueue<>(list.size()), new ThreadPoolExecutor.CallerRunsPolicy());
                        for (CheckNoDetailInvoice checkNoDetailInvoice : list) {
                            if ("14".equals(checkNoDetailInvoice.getInvoiceType())
                                    && StringUtils.isBlank(checkNoDetailInvoice.getCheckCode())) {
                                continue;
                            }
                            DynamicContextHolder.push(DbConstant.BASICS_READ);
                            //判断是否为大企业税号
                            BasisSysDeptCfg baseSysDeptCfg = basisSysDeptCfgDao.selectOne(new QueryWrapper<BasisSysDeptCfg>().eq("nsrsbh", checkNoDetailInvoice.getBuyerTaxNo()));
                            if (baseSysDeptCfg != null) {
                                continue;
                            }
                            Thread thread = new CheckThread(checkTaskService, db, checkNoDetailInvoice);
                            // 将线程放入池中进行执行

                            if (!threadPoolExecutor.isShutdown()) {
                                threadPoolExecutor.execute(thread);
                            }
                        }
                        threadPoolExecutor.shutdown();
                        threadPoolExecutor.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 checkInvoiceOld() {
        log.info("历史发票查验执行开始--");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.queryByBeanName("checkTask","checkInvoiceOld");
        if (scheduleJobEntity!=null && "0".equals(scheduleJobEntity.getJobStatus())){
            try {
                scheduleJobEntity.setJobStatus("1");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
                // 查询需要补全明细的数据
                // 查询需要遍历的数据库
                // 查询数据库 遍历数据源
                DynamicContextHolder.push(DbConstant.BASICS_READ);
                List<String> dbList = confirmDao.getDbSource();
                for (String db : dbList) {
                    DynamicContextHolder.push(db + DbConstant.BUSINESS_READ);
                    List<CheckNoDetailInvoice> list = checkTaskService.getNoDetailInvoiceOld();
                    if (list!=null && list.size()>0){
                        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 5, TimeUnit.SECONDS,
                                new LinkedBlockingQueue<>(list.size()), new ThreadPoolExecutor.CallerRunsPolicy());
                        for (CheckNoDetailInvoice checkNoDetailInvoice : list) {
                            if ("14".equals(checkNoDetailInvoice.getInvoiceType())
                                    && StringUtils.isBlank(checkNoDetailInvoice.getCheckCode())) {
                                continue;
                            }
                            DynamicContextHolder.push(DbConstant.BASICS_READ);
                            //判断是否为大企业税号
                            BasisSysDeptCfg baseSysDeptCfg = basisSysDeptCfgDao.selectOne(new QueryWrapper<BasisSysDeptCfg>().eq("nsrsbh", checkNoDetailInvoice.getBuyerTaxNo()));
                            if (baseSysDeptCfg != null) {
                                continue;
                            }
                            Thread thread = new CheckThread(checkTaskService, db, checkNoDetailInvoice);
                            // 将线程放入池中进行执行
                            if (!threadPoolExecutor.isShutdown()) {
                                threadPoolExecutor.execute(thread);
                            }
                        }
                        threadPoolExecutor.shutdown();
                        threadPoolExecutor.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);
            }
        }
        log.info("历史发票查验执行结束-");
    }

}
