package com.dxhy.core.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dxhy.api.model.custom.TdxCustomsRecord;
import com.dxhy.api.model.db.TDxZzsDkdjWspzEntity;
import com.dxhy.api.model.db.TdxPoolLogEntity;
import com.dxhy.api.model.db.TdxRecordInvoiceEntity;
import com.dxhy.api.model.ncp.ncpCustoms.TdxCustomsNcpJjkcEntity;
import com.dxhy.api.model.ncp.ncpJjkcInvoice.TdxInvoiceNcpJjkcEntity;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.core.job.entity.ScheduleJobEntity;
import com.dxhy.core.job.service.ScheduleJobService;
import com.dxhy.core.job.thread.PoolPushHandle;
import com.dxhy.customs.dao.CustomsNcpJjkcCustomsDao;
import com.dxhy.jxpt.baseService.dao.TdxPoolLogDao;
import com.dxhy.jxpt.baseService.dao.TdxRecordInvoiceDao;
import com.dxhy.jxpt.baseService.dao.ZzsDkdjWspzDao;
import com.dxhy.jxpt.baseService.ncpInvoice.dao.NcpJjkcRecordInvoiceDao;
import com.dxhy.jxpt.baseService.rzInvoice.dao.TdxCustomsRecordDao;
import com.github.pagehelper.PageHelper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

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

/**
* @Description TODO
* @Return
* @Author wangruwei
* @Date 2024/10/29 10:13
**/
@Component("poolPushTask")
@Slf4j
public class PoolPushTask {
    @Resource
    private ScheduleJobService scheduleJobService;
    @Resource
    private TdxPoolLogDao tdxPoolLogDao;
    @Resource
    private TdxRecordInvoiceDao tdxRecordInvoiceDao;
    @Resource
    private TdxCustomsRecordDao tdxCustomsRecordDao;
    @Resource
    private ZzsDkdjWspzDao zzsDkdjWspzDao;

    @Resource
    private NcpJjkcRecordInvoiceDao ncpJjkcRecordInvoiceDao;
    @Resource
    private CustomsNcpJjkcCustomsDao customsNcpJjkcCustomsDao;

    private static List<PoolType> poolTypeList = new ArrayList<>();
    static {
        PoolType fpsj = new PoolType();
        fpsj.setSjlx("1");
        fpsj.setBglx("1");
        poolTypeList.add(fpsj);
        PoolType fpzt = new PoolType();
        fpzt.setSjlx("1");
        fpzt.setBglx("2");
        poolTypeList.add(fpzt);
        PoolType fpywj = new PoolType();
        fpywj.setSjlx("1");
        fpywj.setBglx("3");
        poolTypeList.add(fpywj);
        PoolType fpjjkc = new PoolType();
        fpjjkc.setSjlx("1");
        fpjjkc.setBglx("5");
        poolTypeList.add(fpjjkc);
        PoolType jksjjkc = new PoolType();
        jksjjkc.setSjlx("2");
        jksjjkc.setBglx("5");
        poolTypeList.add(jksjjkc);
        PoolType dkdjSj = new PoolType();
        dkdjSj.setSjlx("3");
        dkdjSj.setBglx("1");
        poolTypeList.add(dkdjSj);
        PoolType dkdjZt = new PoolType();
        dkdjZt.setSjlx("3");
        dkdjZt.setBglx("2");
        poolTypeList.add(dkdjZt);
        PoolType jksSj = new PoolType();
        jksSj.setSjlx("2");
        jksSj.setBglx("1");
        poolTypeList.add(jksSj);
        PoolType jksZt = new PoolType();
        jksZt.setSjlx("2");
        jksZt.setBglx("2");
        poolTypeList.add(jksZt);
        PoolType jksSqsj = new PoolType();
        jksSqsj.setSjlx("");
        jksSqsj.setBglx("1");
        poolTypeList.add(jksSqsj);
        PoolType jksSqZt = new PoolType();
        jksSqZt.setSjlx("");
        jksSqZt.setBglx("4");
        poolTypeList.add(jksSqZt);
    }

    /**
    * @Description 推送发票数据定时任务---增量变动推送
    * @param
    * @Return void
    * @Author wangruwei
    * @Date 2024/10/29 10:10
    **/
    public void pushInvoiceData() {
        log.info("推送发票数据-任务执行开始-");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity =
                scheduleJobService.queryByBeanName("poolPushTask", "pushInvoiceData");
        if (scheduleJobEntity != null && "0".equals(scheduleJobEntity.getJobStatus())) {
            try {
                scheduleJobEntity.setJobStatus("1");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
                // 准备请求参数
                ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 15, 5, TimeUnit.SECONDS,
                        new LinkedBlockingQueue<>(30), new ThreadPoolExecutor.CallerRunsPolicy());
                // 查询数据库 遍历数据源
                int pageSize = 200;
                //本次推送了多少条
                int logUnitSize = 0;
                //定义推送数据类型
                //票据类型：1.进项发票，2.缴款书，3.代扣代缴完税凭
                //变更类型：1.数据变更，2.状态变更，3.源文件变更，4、属期状态变更，5.农产品加计扣除
                for (int i = 0; i < poolTypeList.size(); i++) {
                    PoolType poolType = poolTypeList.get(i);
                    String sjlx = poolType.getSjlx();
                    String bglx = poolType.getBglx();
                    LambdaQueryWrapper<TdxPoolLogEntity> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(TdxPoolLogEntity::getSjlx, sjlx);  //数据类型
                    queryWrapper.eq(TdxPoolLogEntity::getBglx, bglx);  //变更类型
                    queryWrapper.eq(TdxPoolLogEntity::getClzt, "0");  //未推送--固定
                    queryWrapper.eq(TdxPoolLogEntity::getSfyx, "1");  //有效--固定
                    long count = tdxPoolLogDao.selectCount(queryWrapper);

                    log.info("本次请求共有{}条数据发起。sjlx:{},bglx:{}",count,sjlx,bglx);
                    if (count > 0) {
                        long m = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
                        for (int k = 0; k < m; k++) {
                            PageHelper.startPage(k + 1, pageSize);
                            List<TdxPoolLogEntity> poolLogList = tdxPoolLogDao.selectList(queryWrapper);
                            logUnitSize+=poolLogList.size();
                            if (!threadPoolExecutor.isShutdown()) {
                                List<String> uuids = poolLogList.stream().map(TdxPoolLogEntity::getUuid).collect(Collectors.toList());
                                threadPoolExecutor.execute(new PoolPushHandle(uuids,sjlx,bglx,false));
                            }
                        }
                    }
                }

                log.info("新票池--增量变动推送，本次共推{}条",logUnitSize);


                threadPoolExecutor.shutdown();
                threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
                log.info("推送发票数据-任务执行结束--");
            } catch (Exception e) {
                log.info("业务处理异常：{}", e);
            } finally {
                log.info("推送发票数据-重置执行状态");
                scheduleJobEntity.setJobStatus("0");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
            }
        }
    }

    @Data
    public static class PoolType{
        private String sjlx;
        private String bglx;
    }

    /**
     * @Description 推送发票数据定时任务---历史未推送数据
     * @param
     * @Return void
     * @Author wangruwei
     * @Date 2024/10/29 10:10
     **/
    public void pushInvoiceDataHistory() {
        log.info("推送发票数据历史未推送-任务执行开始-");
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        ScheduleJobEntity scheduleJobEntity =
                scheduleJobService.queryByBeanName("poolPushTask", "pushInvoiceDataHistory");
        if (scheduleJobEntity != null && "0".equals(scheduleJobEntity.getJobStatus())) {
            try {
                scheduleJobEntity.setJobStatus("1");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
                // 准备请求参数
                ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 15, 5, TimeUnit.SECONDS,
                        new LinkedBlockingQueue<>(30), new ThreadPoolExecutor.CallerRunsPolicy());
                // 查询数据库 遍历数据源
                int pageSize = 200;

                //发票
                LambdaQueryWrapper<TdxRecordInvoiceEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(TdxRecordInvoiceEntity::getPushPool, "0");
                long count = tdxRecordInvoiceDao.selectCount(queryWrapper);
                if (count > 0) {
                    log.info("本次请求共有{}条数据发起。发票数据",count);
                    long m = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
                    for (int k = 0; k < m; k++) {
                        PageHelper.startPage(k + 1, pageSize);
                        List<TdxRecordInvoiceEntity> recordList = tdxRecordInvoiceDao.selectList(
                                queryWrapper.select(TdxRecordInvoiceEntity::getUuid)
                        );
                        if (!threadPoolExecutor.isShutdown()) {
                            List<String> uuids = recordList.stream().map(TdxRecordInvoiceEntity::getUuid).collect(Collectors.toList());
                            threadPoolExecutor.execute(new PoolPushHandle(uuids,"1","1",true));
                        }
                    }
                }

                //缴款书
                LambdaQueryWrapper<TdxCustomsRecord> customsQueryWrapper = new LambdaQueryWrapper<>();
                customsQueryWrapper.eq(TdxCustomsRecord::getPushPool, "0");
                long customsCount = tdxCustomsRecordDao.selectCount(customsQueryWrapper);
                if (customsCount > 0) {
                    log.info("本次请求共有{}条数据发起。缴款书数据",customsCount);
                    long m = customsCount % pageSize == 0 ? customsCount / pageSize : customsCount / pageSize + 1;
                    for (int k = 0; k < m; k++) {
                        PageHelper.startPage(k + 1, pageSize);
                        List<TdxCustomsRecord> recordList = tdxCustomsRecordDao.selectList(
                                customsQueryWrapper.select(TdxCustomsRecord::getCustomsCode)
                        );
                        if (!threadPoolExecutor.isShutdown()) {
                            List<String> uuids = recordList.stream().map(TdxCustomsRecord::getCustomsCode).collect(Collectors.toList());
                            threadPoolExecutor.execute(new PoolPushHandle(uuids,"2","1",true));
                        }
                    }
                }

                //代扣代缴
                LambdaQueryWrapper<TDxZzsDkdjWspzEntity> dkdjQueryWrapper = new LambdaQueryWrapper<>();
                dkdjQueryWrapper.eq(TDxZzsDkdjWspzEntity::getPushPool, "0");
                long dkdjCount = zzsDkdjWspzDao.selectCount(dkdjQueryWrapper);
                if (dkdjCount > 0) {
                    log.info("本次请求共有{}条数据发起。代扣代缴数据",dkdjCount);
                    long m = dkdjCount % pageSize == 0 ? dkdjCount / pageSize : dkdjCount / pageSize + 1;
                    for (int k = 0; k < m; k++) {
                        PageHelper.startPage(k + 1, pageSize);
                        List<TDxZzsDkdjWspzEntity> recordList = zzsDkdjWspzDao.selectList(dkdjQueryWrapper.
                                select(TDxZzsDkdjWspzEntity::getDkdjwspzh)
                        );
                        if (!threadPoolExecutor.isShutdown()) {
                            List<String> uuids = recordList.stream().map(TDxZzsDkdjWspzEntity::getDkdjwspzh).collect(Collectors.toList());
                            threadPoolExecutor.execute(new PoolPushHandle(uuids,"3","1",true));
                        }
                    }
                }

                //加计扣除---发票
                LambdaQueryWrapper<TdxInvoiceNcpJjkcEntity> fpJjkcQueryWrapper = new LambdaQueryWrapper<>();
                fpJjkcQueryWrapper.eq(TdxInvoiceNcpJjkcEntity::getPushPool, "0");
                fpJjkcQueryWrapper.in(TdxInvoiceNcpJjkcEntity::getClzt, "4","8");
                long fpJjkcCount = ncpJjkcRecordInvoiceDao.selectCount(fpJjkcQueryWrapper);
                if (fpJjkcCount > 0) {
                    log.info("本次请求共有{}条数据发起。加计扣除---发票数据",fpJjkcCount);
                    long m = fpJjkcCount % pageSize == 0 ? fpJjkcCount / pageSize : fpJjkcCount / pageSize + 1;
                    for (int k = 0; k < m; k++) {
                        PageHelper.startPage(k + 1, pageSize);
                        List<TdxInvoiceNcpJjkcEntity> recordList = ncpJjkcRecordInvoiceDao.selectList(fpJjkcQueryWrapper.
                                select(TdxInvoiceNcpJjkcEntity::getUuid,TdxInvoiceNcpJjkcEntity::getJjssq)
                        );
                        if (!threadPoolExecutor.isShutdown()) {
                            List<String> uuids = recordList.stream().map(e->e.getUuid()+"@"+e.getJjssq()).collect(Collectors.toList());
                            threadPoolExecutor.execute(new PoolPushHandle(uuids,"1","5",true));
                        }
                    }
                }

                //加计扣除---缴款书
                LambdaQueryWrapper<TdxCustomsNcpJjkcEntity> jksJjkcQueryWrapper = new LambdaQueryWrapper<>();
                jksJjkcQueryWrapper.eq(TdxCustomsNcpJjkcEntity::getPushPool, "0");
                jksJjkcQueryWrapper.in(TdxCustomsNcpJjkcEntity::getClzt, "4","8");
                long jksJjkcCount = customsNcpJjkcCustomsDao.selectCount(jksJjkcQueryWrapper);
                if (jksJjkcCount > 0) {
                    log.info("本次请求共有{}条数据发起。加计扣除---缴款书数据",jksJjkcCount);
                    long m = jksJjkcCount % pageSize == 0 ? jksJjkcCount / pageSize : jksJjkcCount / pageSize + 1;
                    for (int k = 0; k < m; k++) {
                        PageHelper.startPage(k + 1, pageSize);
                        List<TdxCustomsNcpJjkcEntity> recordList = customsNcpJjkcCustomsDao.selectList(jksJjkcQueryWrapper.
                                select(TdxCustomsNcpJjkcEntity::getCustomsCode,TdxCustomsNcpJjkcEntity::getJjssq)
                        );
                        if (!threadPoolExecutor.isShutdown()) {
                            List<String> uuids = recordList.stream().map(e->e.getCustomsCode()+"@"+e.getJjssq()).collect(Collectors.toList());
                            threadPoolExecutor.execute(new PoolPushHandle(uuids,"2","5",true));
                        }
                    }
                }

                log.info("新票池--全量历史推送，本次共推{}条",(count+customsCount+dkdjCount+fpJjkcCount+jksJjkcCount));

                threadPoolExecutor.shutdown();
                threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS);
                log.info("推送发票数据历史未推送-任务执行结束--");
            } catch (Exception e) {
                log.info("业务处理异常：{}", e);
            } finally {
                log.info("推送发票数据历史未推送-重置执行状态");
                scheduleJobEntity.setJobStatus("0");
                DynamicContextHolder.push(DbConstant.BASICS_WRITE);
                scheduleJobService.updateById(scheduleJobEntity);
            }
        }
    }

}
