package com.dxhy.core.job.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dxhy.api.model.config.CollectionControlModel;
import com.dxhy.common.constant.ConfigureConstant;
import com.dxhy.common.constant.CoreConstants;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.util.JsonUtils;
import com.dxhy.common.utils.Base64Encoding;
import com.dxhy.common.utils.CommonUtil;
import com.dxhy.core.job.dao.TDxApplyDkdjWspzDao;
import com.dxhy.core.job.dao.TDxZzsDkdjWspzDao;
import com.dxhy.core.job.dao.TDxhttpLogDkdjWspzDao;
import com.dxhy.core.job.entity.*;
import com.dxhy.core.job.pojo.BaseResJson;
import com.dxhy.core.job.service.DkdjwspzService;
import com.dxhy.core.util.DateUtils;
import com.dxhy.core.util.Dqyjkdyutil;
import com.dxhy.jxpt.baseService.poolPush.PoolLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Allen
 * @description 代扣代缴完税凭证业务实现
 * @date 2023/12/7 15:17
 */

@Service
@Slf4j
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
public class DkdjwspzServiceImpl implements DkdjwspzService {
    private final static String LOG_MSG ="代扣代缴完税凭证业务实现--";
    @Autowired
    private TDxZzsDkdjWspzDao tDxZzsDkdjWspzDao;
    @Resource
    private PoolLogService poolLogService;

    @Autowired
    private TDxhttpLogDkdjWspzDao tDxhttpLogDkdjWspzDao;

    @Autowired
    private TDxApplyDkdjWspzDao tDxApplyDkdjWspzDao;

    /**
     * @description  增值税代扣代缴完税凭证采集
     * @author  Allen
     * @date    2023/12/7 15:22
     */
    @Override
    public void zzsdkdjwspzcj(CollectionControlModel ccm) {
        log.info("{} 增值税代扣代缴完税凭证采集开始：{}",LOG_MSG, JsonUtils.getInstance().toJsonString(ccm));
        try {
            DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_WRITE);
            Map<String, Object> httpLogMap = new HashMap<>();
            int totalRow = 0;
            int addRow = 0;
            //组装请求数据
            String batchNo = Dqyjkdyutil.getBatchNo();
            ZzsDkdjWspzcjReq req = new ZzsDkdjWspzcjReq();
            req.setBuyerTaxNo(ccm.getNsrsbh());
            req.setStatus("1");
            req.setBatchNo(batchNo);
            req.setStartRow(1);
            req.setAcquisitionDateBegin(getBeginTime(ccm,"01"));
            req.setAcquisitionDateEnd(Dqyjkdyutil.getEndTime());

            DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_READ);
            while (true) {
                TDxHttpLogDkdjWspzEntity thlzf = new TDxHttpLogDkdjWspzEntity();
                //调用大企业接口
                BaseResJson resp = Dqyjkdyutil.call(httpLogMap, CoreConstants.zzsdkdjwspzcj, ccm.getAceId(), ccm.getAcekey(), req);

                if (resp != null && resp.getReturnStateInfo() != null && resp.getReturnStateInfo().getReturnCode().equals(ConfigureConstant.SECCESS_CODE)) {
                    if (StringUtils.isNotBlank(resp.getData())) {
                        JSONObject jsonObject = JSON.parseObject(Base64Encoding.decodeToString(resp.getData()));
                        if (jsonObject.getJSONArray("invoices") != null && jsonObject.getJSONArray("invoices").size() > 0) {
                            //保存增值税代扣代缴完税凭证归集记录表
                            log.info("保存增值税代扣代缴完税凭证归集记录表");
                            thlzf.setCompany(ccm.getCompany());
                            thlzf.setBatchNo(batchNo);
                            thlzf.setType("01");
                            thlzf.setTaxno(ccm.getNsrsbh());
                            thlzf.setStatus("1");
                            thlzf.setReqDate((Date) httpLogMap.get(CoreConstants.reqDate));
                            thlzf.setReqText((String) httpLogMap.get(CoreConstants.reqText));
                            thlzf.setResDate((Date) httpLogMap.get(CoreConstants.resDate));
//                            thlzf.setResText((String) httpLogMap.get(CoreConstants.resText));
                            thlzf.setTotal(String.valueOf(jsonObject.getIntValue("contentRows")));
                            tDxhttpLogDkdjWspzDao.insert(thlzf);
                            JSONArray dkdjwspzs = jsonObject.getJSONArray("invoices");
                            //要推送票池的uuid集合
                            List<String> uuids = new LinkedList();
                            dkdjwspzs.forEach(wspz->{
                                JSONObject wspzObj = JSON.parseObject(wspz.toString());
                                log.info("保存增值税代扣代缴完税凭证信息：{}",wspz);
                                TDxZzsDkdjWspzInfo wi = new TDxZzsDkdjWspzInfo();
                                wi.setBkjnsrmc(wspzObj.getString("salerName"));
                                wi.setBkjnsrsbh(wspzObj.getString("salerTaxNo"));
                                wi.setJsje(new BigDecimal(wspzObj.getString("totalAmount")));
                                wi.setDkdjwspzh(wspzObj.getString("invoiceNo"));
                                wi.setKjywrmc(ccm.getTaxname());
                                wi.setKjywrsbh(wspzObj.getString("buyerTaxNo"));
                                wi.setSjje(new BigDecimal(wspzObj.getString("taxAmount")));
                                wi.setTfrq(CommonUtil.dateConvert(wspzObj.getString("invoiceDate")));
                                wi.setCreateTime(new Date());
                                wi.setTdly("0");
                                wi.setYxse(new BigDecimal(wspzObj.getString("yxse")));
                                wi.setRzzt(wspzObj.getString("rzhYesorno"));
                                wi.setGjrq(DateUtils.dateToStr(new Date(), "yyyyMMdd"));
                                if ("1".equals(wspzObj.getString("rzlx"))) {
                                    wi.setRzlx("01");
                                    wi.setRzzt("1");
                                }
                                if ("4".equals(wspzObj.getString("rzlx"))) {
                                    wi.setRzlx("03");
                                    wi.setRzzt("2");
                                    wi.setBdklx(wspzObj.getString("bdkMessage"));
                                    wi.setBdkyy(wspzObj.getString("bdkyyqt"));
                                }
                                wi.setRzsj(wspzObj.getString("confirmDate"));
                                wi.setRzssq(wspzObj.getString("rzhBelongDate"));

                                TDxZzsDkdjWspzInfo wspzInfo = tDxZzsDkdjWspzDao.selectOne(new QueryWrapper<TDxZzsDkdjWspzInfo>().eq("dkdjwspzh", wi.getDkdjwspzh()));
                                if (wspzInfo != null) {
                                    log.info("更新增值税代扣代缴完税凭证，完税凭证编号：{}",wi.getDkdjwspzh());
                                    wi.setId(wspzInfo.getId());
                                    wi.setUpdateTime(new Date());
                                    tDxZzsDkdjWspzDao.updateById(wi);
                                } else {
                                    log.info("新增增值税代扣代缴完税凭证，完税凭证编号：{}",wi.getDkdjwspzh());
                                    tDxZzsDkdjWspzDao.insert(wi);
                                }

                                uuids.add(wi.getDkdjwspzh());
                            });
                            totalRow = jsonObject.getIntValue("totalRows");
                            addRow += jsonObject.getIntValue("contentRows");

                            //推送新票池记录表-数据变更
                            poolLogService.pushChangeToPool(ConfigureConstant.POOL_SJLX_DKDJ_3, uuids, ConfigureConstant.POOL_BGLX_SJBG_1);
                        } else {
                            log.info("大企业接口返回发票数据节点为空：{}",JsonUtils.getInstance().toJsonString(resp));
                            break;
                        }
                        if (addRow < totalRow) {
                            req.setStartRow(addRow);
                        } else {
                            log.info("大企业接口当前批次调用完成");
                            break;
                        }
                    } else {
                        log.info("大企业接口返回data节点为空：{}",JsonUtils.getInstance().toJsonString(resp));
                        break;
                    }
                } else {
                    log.info("大企业接口返回失败：{}",JsonUtils.getInstance().toJsonString(resp));
                    break;
                }
            }
            log.info("---当前税号处理完成---");

        } catch (Exception e) {
            log.debug("增值税代扣代缴完税凭证采集任务处理异常：{}",e);
        }
    }


    /**
     * @description  增值税代扣代缴完税凭证认证申请
     * @author  Allen
     * @date    2023/12/7 17:51
    */
    @Override
    public void zzsdkdjwspzrzsq(CollectionControlModel ccm) {
        log.info("{} 增值税代扣代缴完税凭证认证申请开始：{}",LOG_MSG, JsonUtils.getInstance().toJsonString(ccm));
        try {
            DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_WRITE);

            //查询待上传完税凭证信息
            List<TDxZzsDkdjWspzInfo> wspzInfos = tDxZzsDkdjWspzDao.selectList(new QueryWrapper<TDxZzsDkdjWspzInfo>()
                    .eq("kjywrsbh", ccm.getNsrsbh())
                    .and(i->{i.eq("rzclzt", "1").or().eq("rzclzt", "5");})
                    );
            if (!CollectionUtils.isEmpty(wspzInfos)) {
                int pageSize = 200;
                int count = wspzInfos.size();
                int m = count%pageSize == 0 ? count/pageSize : count/pageSize + 1;
                for (int i = 1; i <= m; i++) {
                    List<TDxZzsDkdjWspzInfo> wspzList = CommonUtil.listLimit(wspzInfos, pageSize, i);
                    if (!CollectionUtils.isEmpty(wspzList)) {
                        Map<String, Object> httpLogMap = new HashMap<>();
                        //组装请求数据
                        String batchNo = Dqyjkdyutil.getBatchNo();
                        ZzsDkdjWspzrzsqReq req = buildReqData(wspzList,batchNo,ccm.getNsrsbh());
                        //调用大企业接口
                        BaseResJson resp = Dqyjkdyutil.call(httpLogMap, CoreConstants.zzsdkdjwspzrzsq, ccm.getAceId(), ccm.getAcekey(), req);
                        if (resp != null && resp.getReturnStateInfo() != null && resp.getReturnStateInfo().getReturnCode().equals(ConfigureConstant.SECCESS_CODE)) {
                            //保存请求批次记录表,更新完税凭证状态
                            saveHttpLogUpdateWspzzt(wspzList,ccm,batchNo);
                        } else if (resp != null && resp.getReturnStateInfo() != null && resp.getReturnStateInfo().getReturnCode().equals(ConfigureConstant.ERROR_CODE_9997)) {
                            log.info("大企业接口返回9997,更新完税凭证认证申请状态：{}", JsonUtils.getInstance().toJsonString(resp));
                            if (StringUtils.isNotBlank(resp.getData())) {
                                JSONArray jsonObject = JSON.parseObject(Base64Encoding.decodeToString(resp.getData())).getJSONArray("errorInvoices");
                                jsonObject.stream().forEach(errorDate->{
                                    JSONObject ed = JSON.parseObject(errorDate.toString());
                                    TDxZzsDkdjWspzInfo kjywrsbh = tDxZzsDkdjWspzDao.selectOne(
                                            new QueryWrapper<TDxZzsDkdjWspzInfo>()
                                                    .eq("dkdjwspzh", ed.getString("invoiceNo"))
                                                    .eq("bkjnsrsbh", ed.getString("salerTaxNo"))
                                    );
                                    if (kjywrsbh != null) {
                                        String rzclzt = "2";
                                        String rzsbyy = ed.getString("errorCode")+"："+ed.getString("errorMessage");
                                        if ("01".equals(kjywrsbh.getRzlx()) || "03".equals(kjywrsbh.getRzlx())) {
                                            rzclzt = "3";
                                        }
                                        if ("02".equals(kjywrsbh.getRzlx()) || "04".equals(kjywrsbh.getRzlx())) {
                                            rzclzt = "7";
                                        }
                                        tDxZzsDkdjWspzDao.update(null,new UpdateWrapper<TDxZzsDkdjWspzInfo>()
                                                .set("rzclzt",rzclzt)
                                                .set("rzsbyy",rzsbyy)
                                                .set("update_time",new Date())
                                                .eq("dkdjwspzh",kjywrsbh.getDkdjwspzh())
                                                .eq("bkjnsrsbh", kjywrsbh.getBkjnsrsbh())
                                        );
                                    }

                                });

                            }
                        } else {
                            log.info("大企业接口返回失败：{}", JsonUtils.getInstance().toJsonString(resp));
                        }
                    }
                }
            } else {
                log.info("没有待处理的数据",LOG_MSG);
            }
            log.info("---当前税号处理完成---");
        } catch (Exception e) {
            log.debug("增值税代扣代缴完税凭证认证申请任务处理异常：{}",e);
        }
    }

    /**
     * @description  增值税代扣代缴完税凭证认证结果查询
     * @author  Allen
     * @date    2023/12/8 9:51
     */
    @Override
    public void zzsdkdjwspzrzjgcx(CollectionControlModel ccm) {
        log.info("{} 增值税代扣代缴完税凭证认证结果查询开始：{}",LOG_MSG, JsonUtils.getInstance().toJsonString(ccm));
        try {
            DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_WRITE);
            Map<String, Object> httpLogMap = new HashMap<>();
            List<TDxApplyDkdjWspz> tDxApplyDkdjWspzList = tDxApplyDkdjWspzDao.selectList(new QueryWrapper<TDxApplyDkdjWspz>().select("batch_no")
                    .eq("nsrsbh", ccm.getNsrsbh())
                    .eq("result_status", "N")
                    .last("group by batch_no"));
            for (int i = 0; i < tDxApplyDkdjWspzList.size(); i++) {
                TDxApplyDkdjWspz tDxApplyDkdjWspz = tDxApplyDkdjWspzList.get(i);
                if (tDxApplyDkdjWspz != null) {
                    log.info("开始处理批次号：{}", tDxApplyDkdjWspz.getBatchNo());
                    //调用大企业接口
                    Map<String, String> req = new HashMap<>();
                    req.put("batchNo",tDxApplyDkdjWspz.getBatchNo());
                    req.put("buyerTaxNo",ccm.getNsrsbh());
                    BaseResJson resp = Dqyjkdyutil.call(httpLogMap, CoreConstants.zzsdkdjwspzrzjgcx, ccm.getAceId(), ccm.getAcekey(), req);
                    if (resp != null && resp.getReturnStateInfo() != null && resp.getReturnStateInfo().getReturnCode().equals(ConfigureConstant.SECCESS_CODE)) {
                        //处理业务数据
                        JSONArray jsonObject = JSON.parseObject(Base64Encoding.decodeToString(resp.getData())).getJSONArray("invoices");
                        //要推送票池的uuid集合
                        List<String> uuids = new LinkedList();
                        jsonObject.stream().forEach(mx->{
                            JSONObject mxObj = JSON.parseObject(mx.toString());
                            String rzzt = null;
                            String rzclzt = null;
                            String rzsbyy = null;
                            String rzssq = null;
                            String rzsj = null;
                            //撤销成功
                            boolean cxSuc = false;
                            TDxZzsDkdjWspzInfo wspzInfo = tDxZzsDkdjWspzDao.selectOne(new QueryWrapper<TDxZzsDkdjWspzInfo>()
                                    .eq("dkdjwspzh", mxObj.getString("invoiceNo"))
                                    .eq("bkjnsrsbh", mxObj.getString("salerTaxNo"))
                            );
                            if ("4".equals(mxObj.getString("authStatus"))) {
                                log.info("票据申请成功,更新票据状态，编号：{}", mxObj.getString("invoiceNo"));
                                //认证类型：01申请抵扣，02撤销抵扣，03申请不抵扣，04撤销不抵扣
                                if ("01".equals(wspzInfo.getRzlx())) {
                                    rzzt = "1";
                                    rzclzt = "4";
                                    rzssq = mxObj.getString("rzhBelongDate");
                                    rzsj = mxObj.getString("confirmDate");
                                }
                                //02撤销抵扣  04撤销不抵扣
                                if ("02".equals(wspzInfo.getRzlx())||"04".equals(wspzInfo.getRzlx())) {
                                    rzzt = "0";
                                    rzclzt = "8";
                                    cxSuc = true;
                                }
                                if ("03".equals(wspzInfo.getRzlx())) {
                                    rzzt = "2";
                                    rzclzt = "4";
                                    rzssq = mxObj.getString("rzhBelongDate");
                                    rzsj = mxObj.getString("confirmDate");
                                }
                            }
                            if ("5".equals(mxObj.getString("authStatus"))) {
                                log.info("票据申请失败,更新票据状态，编号：{}", mxObj.getString("invoiceNo"));
                                rzsbyy = mxObj.getString("failureReason");
                                if ("01".equals(wspzInfo.getRzlx())||"03".equals(wspzInfo.getRzlx())) {
                                    rzclzt = "3";
                                }
                                if ("02".equals(wspzInfo.getRzlx())||"04".equals(wspzInfo.getRzlx())) {
                                    rzclzt = "7";
                                }
                            }
                            UpdateWrapper<TDxZzsDkdjWspzInfo> tDxZzsDkdjWspzInfoUpdateWrapper = new UpdateWrapper<>();
                            tDxZzsDkdjWspzInfoUpdateWrapper.set(StringUtils.isNotBlank(rzclzt),"rzclzt",rzclzt);
                            tDxZzsDkdjWspzInfoUpdateWrapper.set(StringUtils.isNotBlank(rzzt),"rzzt",rzzt);
                            tDxZzsDkdjWspzInfoUpdateWrapper.set(StringUtils.isNotBlank(rzsj),"rzsj", rzsj);
                            tDxZzsDkdjWspzInfoUpdateWrapper.set(StringUtils.isNotBlank(rzssq),"rzssq",rzssq);
                            tDxZzsDkdjWspzInfoUpdateWrapper.set(StringUtils.isNotBlank(rzsbyy),"rzsbyy",rzsbyy);
                            tDxZzsDkdjWspzInfoUpdateWrapper.set("update_time",new Date());
                            if(cxSuc){
                                log.info("如果撤销抵扣，撤销不抵扣 成功，则更新属期，认证时间，认证人为空");
                                //tDxZzsDkdjWspzInfoUpdateWrapper.set("rzssq","");
                                tDxZzsDkdjWspzInfoUpdateWrapper.set("rzsj","");
                                tDxZzsDkdjWspzInfoUpdateWrapper.set("czr","");
                                tDxZzsDkdjWspzInfoUpdateWrapper.set("bdklx","");
                                tDxZzsDkdjWspzInfoUpdateWrapper.set("bdkyy","");
                            }
                            //更新代扣代缴完税凭证表状态
                            tDxZzsDkdjWspzDao.update(null,tDxZzsDkdjWspzInfoUpdateWrapper
                                    .eq("dkdjwspzh",mxObj.getString("invoiceNo"))
                                    .eq("bkjnsrsbh", mxObj.getString("salerTaxNo"))
                            );

                            //更新记录表状态
                            tDxApplyDkdjWspzDao.update(null, new UpdateWrapper<TDxApplyDkdjWspz>()
                                    .set("result_status", "Y")
                                    .eq("dkdjwspzbh",mxObj.getString("invoiceNo"))
                                    .eq("batch_no",tDxApplyDkdjWspz.getBatchNo()));

                            if ("4".equals(mxObj.getString("authStatus"))) {
                                uuids.add(mxObj.getString("invoiceNo"));
                            }
                        });

                        //推送新票池记录表-状态变更
                        poolLogService.pushChangeToPool(ConfigureConstant.POOL_SJLX_DKDJ_3, uuids, ConfigureConstant.POOL_BGLX_ZTBG_2);

                    } else {
                        log.info("---大企业接口返回失败---：{}",JsonUtils.getInstance().toJsonString(resp));
                    }
                }
            }

            log.info("---当前税号处理完成---");
        } catch (Exception e) {
            log.debug("增值税代扣代缴完税凭证认证结果查询异常：{}",e);
        }
    }

    private void saveHttpLogUpdateWspzzt(List<TDxZzsDkdjWspzInfo> wspzList, CollectionControlModel ccm,String batchNo) {
        wspzList.stream().forEach(wspz->{

            String wspzbh = wspz.getDkdjwspzh();
            String rzclzt = "2";
            if ("01".equals(wspz.getRzlx()) || "03".equals(wspz.getRzlx())) {
                rzclzt = "2";
            }
            if ("02".equals(wspz.getRzlx()) || "04".equals(wspz.getRzlx())) {
                rzclzt = "6";
            }
            tDxZzsDkdjWspzDao.update(null,new UpdateWrapper<TDxZzsDkdjWspzInfo>()
                    .set("rzclzt",rzclzt)
                    .set("update_time",new Date())
                    .eq("dkdjwspzh",wspzbh)
                    .eq("bkjnsrsbh", wspz.getBkjnsrsbh())
            );

            TDxApplyDkdjWspz entity = new TDxApplyDkdjWspz();
            entity.setDkdjwspzbh(wspz.getDkdjwspzh());
            entity.setCreateDate(new Date());
            entity.setAceKey(ccm.getAcekey());
            entity.setAceId(ccm.getAceId());
            entity.setBatchNo(batchNo);
            entity.setResultStatus("N");
            entity.setNsrsbh(ccm.getNsrsbh());
            tDxApplyDkdjWspzDao.insert(entity);
        });
    }

    private ZzsDkdjWspzrzsqReq buildReqData(List<TDxZzsDkdjWspzInfo> wspzList, String batchNo,String nsrsbh) {
        ZzsDkdjWspzrzsqReq req = new ZzsDkdjWspzrzsqReq();
        List<Map<String, String>> datas = new ArrayList<>();
        req.setBuyerTaxNo(nsrsbh);
        req.setBatchNo(batchNo);
        req.setContentRows(String.valueOf(wspzList.size()));
        wspzList.stream().forEach(wspz->{
            Map<String, String> map = new HashMap<>();
            map.put("buyerTaxNo",wspz.getKjywrsbh() );
            map.put("invoiceNo", wspz.getDkdjwspzh());
            map.put("salerTaxNo",wspz.getBkjnsrsbh() );
            String rzlx = null;
            if ("01".equals(wspz.getRzlx())) {
                rzlx = "1";
            }
            if ("02".equals(wspz.getRzlx())) {
                rzlx = "5";
            }
            if ("03".equals(wspz.getRzlx())) {
                rzlx = "4";
                map.put("bdkMessage", wspz.getBdklx());
                map.put("bdkyyqt", wspz.getBdkyy());
            }
            if ("04".equals(wspz.getRzlx())) {
                rzlx = "6";
            }
            map.put("applyRzlx", rzlx);
            map.put("applyTaxPeriod", wspz.getRzssq());
            datas.add(map);
        });
        req.setInvoices(datas);
        return req;
    }

    private String getBeginTime(CollectionControlModel ccm, String type) {
        DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_READ);
        String lastReqTime = tDxhttpLogDkdjWspzDao.selectLastreqDate(ccm.getNsrsbh(), type);
        DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_WRITE);
        return Dqyjkdyutil.getBeginTime(lastReqTime, ccm.getFirstCollectDate());
    }
}
