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

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxhy.api.model.config.CollectionControlModel;
import com.dxhy.api.model.config.sys.SysGroupConfigEntity;
import com.dxhy.api.model.invoice.TDxHttpLog;
import com.dxhy.api.model.invoice.TDxRecordInvoice;
import com.dxhy.api.model.lq.TdxLqRzApplyLog;
import com.dxhy.api.model.rz.rzInvoice.page.TdxLqRzInvoice;
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.dao.*;
import com.dxhy.core.job.dao.TDxRecordInvoiceJobDao;
import com.dxhy.core.job.entity.TAcOrg;
import com.dxhy.core.job.entity.TDxHttpLogZzsfpgjEntity;
import com.dxhy.core.job.pojo.BaseQueJson;
import com.dxhy.core.job.pojo.BaseResJson;
import com.dxhy.core.job.pojo.ReturnStateInfo;
import com.dxhy.core.model.rzInvoice.*;
import com.dxhy.core.service.rzInvoice.RzInvoiceDqyService;
import com.dxhy.core.util.DateUtils;
import com.dxhy.core.util.Dqyjkdyutil;
import com.dxhy.jxpt.baseService.poolPush.PoolLogService;
import com.github.pagehelper.PageHelper;
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 javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Service("rzInvoiceDqyService")
@Slf4j
public class RzInvoiceDqyServiceImpl
		extends ServiceImpl<CoreSysGroupConfigDao, SysGroupConfigEntity>
		implements RzInvoiceDqyService {

	@Resource
	private CoreTdxDqyRzInvoiceDao tdxDqyRzInvoiceDao;
	@Resource
	private CoreTDxRecordInvoiceDao coreTDxRecordInvoiceDao;
	@Resource
	private PoolLogService poolLogService;

	@Resource
	private TDxHttpZzsfpgjDao tDxHttpZzsfpgjDao;

	@Autowired(required = false)
	private CoreTdxDqyRzApplyLogDao coreTdxDqyRzApplyLogDao;
	@Resource
	private TDxRecordInvoiceJobDao tDxRecordInvoiceJobDao;

	@Resource
	private CoreConfirmDao coreConfirmDao;

	@Override
	public SysGroupConfigEntity getGroupInfo(String company) {
		DynamicContextHolder.push(DbConstant.BASICS_WRITE);
		SysGroupConfigEntity sysGroupConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysGroupConfigEntity>().eq(SysGroupConfigEntity::getCompany, company));
		return sysGroupConfig;
	}

	@Override
	public Map<String, String> getApplyKeyByNsrsbh(String nsrsbh) {
		DynamicContextHolder.push(DbConstant.BASICS_READ);
		return baseMapper.getApplyKeyByNsrsbh(nsrsbh);
	}

	/**
	 * @Description 批量上传入账发票接口
	 * @Return void
	 * @Author wangruwei
	 * @Date 2023/2/21 17:14
	 **/
	@Override
	public void rzInvoiceUpload(TAcOrg collectionControlModel) {
		DynamicContextHolder.push(collectionControlModel.getDbName() + DbConstant.BUSINESS_READ);
		//查询可以发起调用的税号信息
		String taxno = collectionControlModel.getTaxno();
		String aceId = collectionControlModel.getAceId();
		String aceKey = collectionControlModel.getAceKey();
		String dbName = collectionControlModel.getDbName();
		String company = collectionControlModel.getCompany();

		//SysEnterpriseConfigEntity sysEnterpriseConfigEntity = sysEnterpriseConfigDao.selectOne(new LambdaQueryWrapper<SysEnterpriseConfigEntity>().eq(SysEnterpriseConfigEntity::getNsrsbh, taxno));


		BaseQueJson bqj = new BaseQueJson();
		int pageSize = 200;
		log.info("批量上传入账发票接口查询可以发起调用的税号信息开始:nsrsbh{}", taxno);
		log.info("入账申请状态：1申请入账，2发送入账请求，3入账失败，4入账成功，5申请撤销，6发送撤销申请，7撤销失败，8撤销成功");
		try {
			// 通过税号查询发票数据
			// 查询需要入账的发票
			LambdaQueryWrapper<TdxLqRzInvoice> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(TdxLqRzInvoice::getNsrsbh, taxno);
			queryWrapper.in(TdxLqRzInvoice::getFprzAuthStatus, Arrays.asList("1","5"));
			long count = tdxDqyRzInvoiceDao.selectCount(queryWrapper);

			log.info("本次请求共有{}条数据发起",count);
			if (count > 0) {
				long m = count%pageSize == 0 ? count/pageSize : count/pageSize + 1;
				for (int k = 0; k < m; k++) {
					// 保存请求记录
					//TDxHttpLog httpLog = new TDxHttpLog();
					//httpLog.setTaxno(taxno);
					//httpLog.setType("60");
					//httpLog.setReqDate(new Date());
					//httpLog.setCompany(collectionControlModel.getCompany());

					PageHelper.startPage(k+1, pageSize);
					List<TdxLqRzInvoice> rzList = tdxDqyRzInvoiceDao.selectList(queryWrapper);

					//批量上传入账发票接口 接口
					RzInvoiceReq collectData = new RzInvoiceReq();
					String batchNo = UUID.randomUUID().toString().replace("-", "");
					collectData.setBatchNo(batchNo);
					collectData.setBuyerTaxNo(taxno);
					List<RzInvoiceReqInvoice> fpmx = new LinkedList<>();
					for (TdxLqRzInvoice item:rzList) {
						RzInvoiceReqInvoice reqitem = new RzInvoiceReqInvoice();
						reqitem.setBuyerTaxNo(item.getNsrsbh());
						reqitem.setInvoiceCode(item.getInvoiceCode());
						reqitem.setInvoiceNo(item.getInvoiceNo());
						reqitem.setInvoiceDate(DateUtils.dateToStr(item.getInvoiceDate(),"yyyy-MM-dd"));
						reqitem.setApplyTaxPeriod(item.getFprzsq());
						//reqitem.setApplyAccountType("1");
						reqitem.setApplyAccountPurpose(item.getFprzlx());
						reqitem.setApplyAccountDate(DateUtils.dateToStr(new Date(),"yyyy-MM-dd"));
						fpmx.add(reqitem);
					}
					collectData.setInvoices(fpmx);
					collectData.setContentRows(fpmx.size());

					// 保存请求记录
					TDxHttpLog httpLog = new TDxHttpLog();
					httpLog.setTaxno(taxno);
					httpLog.setType("60");
					httpLog.setReqText(JSON.toJSONString(collectData));
					httpLog.setCompany(company);
					// 得到返回报文，解析拿出返回的数量，累加用于判断数量
					httpLog.setReqDate(new Date());

					//String responseJson = HttpUtil.post(collectUrl, collectDataStr, 240000);

					BaseResJson gatherData = Dqyjkdyutil.call(new HashMap<>(), CoreConstants.invoiceRz, aceId, aceKey, collectData);
					httpLog.setResDate(new Date());
					httpLog.setResText(JSON.toJSONString(gatherData));
					httpLog.setStatus("1");
					log.info(JSON.toJSONString(gatherData));
					log.info("响应请求数据为=" + JSON.toJSONString(gatherData));
					coreConfirmDao.insert(httpLog);
					try {
						if (gatherData != null && gatherData.getReturnStateInfo() != null ) {
							//ResponesJson gatherData = JSONObject.parseObject(responseJson, ResponesJson.class);
							ReturnStateInfo returnStateInfo = gatherData.getReturnStateInfo();
							if ("0000".equals(returnStateInfo.getReturnCode())) {
								log.info("入账申请成功");
								//更新本次申请的票状态
								//1 更新t_dx_lq_rz_invoice里的发票状态
								//2 更新底账表的状态
								for (TdxLqRzInvoice item:rzList) {
									//如果是 1申请入账
									if("1".equals(item.getFprzAuthStatus())){
										//更新 t_dx_lq_rz_invoice 为 2发送入账请求
										TdxLqRzInvoice update = new TdxLqRzInvoice();
										update.setId(item.getId());
										update.setFprzAuthStatus("2");
										tdxDqyRzInvoiceDao.updateById(update);
										//更新底账表为 04-入账中
										TDxRecordInvoice updateRecord = new TDxRecordInvoice();
										updateRecord.setLqRzzt("04");
										coreTDxRecordInvoiceDao.update(updateRecord,new LambdaUpdateWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, item.getUuid()));

									}else if("5".equals(item.getFprzAuthStatus())){
										//5申请撤销
										//更新 t_dx_lq_rz_invoice 为 6发送撤销申请
										TdxLqRzInvoice update = new TdxLqRzInvoice();
										update.setId(item.getId());
										update.setFprzAuthStatus("6");
										tdxDqyRzInvoiceDao.updateById(update);
										//更新底账表为 05-撤销中
										TDxRecordInvoice updateRecord = new TDxRecordInvoice();
										updateRecord.setLqRzzt("05");
										coreTDxRecordInvoiceDao.update(updateRecord,new LambdaUpdateWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, item.getUuid()));
									}
								}
								//3 往申请表里插入一条数据
								TdxLqRzApplyLog tdxLqRzApplyLog = new TdxLqRzApplyLog();
								tdxLqRzApplyLog.setNsrsbh(taxno);
								tdxLqRzApplyLog.setPclsh(batchNo);
								tdxLqRzApplyLog.setTdlx("0");
								tdxLqRzApplyLog.setRzlx("0");
								tdxLqRzApplyLog.setResultStatus("N");
								tdxLqRzApplyLog.setCreateTime(new Date());
								coreTdxDqyRzApplyLogDao.insert(tdxLqRzApplyLog);

							}else if("9997".equals(returnStateInfo.getReturnCode())){
								log.info("入账申请失败返回code:{}，更新t_dx_lq_rz_invoice表中状态",returnStateInfo.getReturnCode());
								String data = returnStateInfo.getData();
								RzInvoiceResp rzInvoiceResp = JSON.toJavaObject(JSONObject.parseObject(Base64.decodeStr(data)), RzInvoiceResp.class);
								List<RzInvoiceRespInvoice> errorInvoices = rzInvoiceResp.getErrorInvoices();
								if(errorInvoices.size()>0){
									for (RzInvoiceRespInvoice item: errorInvoices) {
										/**
										 * 2015	代码与号码长度不符
										 * 7001	日期格式不正确
										 * 7002	申请入账用途不能为空
										 * 7003	鉴权税号与发票税号不一致
										 * 7005	存在处理中的数据
										 **/
										if("7005".equals(item.getErrorCode())){
											log.info("如果错误码是处理中数据不变" );
										}else{
											//如果不是处理中，把申请表里的数据更新成错误
											//如果是 1申请入账
											TdxLqRzInvoice rzInvoice = rzList.stream().filter(e -> e.getInvoiceCode().equals(item.getInvoiceCode()) && e.getInvoiceNo().equals(item.getInvoiceNo())).findFirst().get();
											if("1".equals(rzInvoice.getFprzAuthStatus())){
												//更新 t_dx_lq_rz_invoice 为 2发送入账请求
												TdxLqRzInvoice update = new TdxLqRzInvoice();
												update.setId(rzInvoice.getId());
												update.setFprzAuthStatus("2");
												tdxDqyRzInvoiceDao.updateById(update);
												//更新底账表为 04-入账中
												TDxRecordInvoice updateRecord = new TDxRecordInvoice();
												updateRecord.setLqRzzt("04");
												coreTDxRecordInvoiceDao.update(updateRecord,new LambdaUpdateWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, rzInvoice.getUuid()));

											}else if("5".equals(rzInvoice.getFprzAuthStatus())){
												//5申请撤销
												//更新 t_dx_lq_rz_invoice 为 6发送撤销申请
												TdxLqRzInvoice update = new TdxLqRzInvoice();
												update.setId(rzInvoice.getId());
												update.setFprzAuthStatus("6");
												tdxDqyRzInvoiceDao.updateById(update);
												//更新底账表为 05-撤销中
												TDxRecordInvoice updateRecord = new TDxRecordInvoice();
												updateRecord.setLqRzzt("05");
												coreTDxRecordInvoiceDao.update(updateRecord,new LambdaUpdateWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, rzInvoice.getUuid()));
											}
										}
									}
								}


							}
						}else{
							log.info("大企业接口返回失败：{}", JsonUtils.getInstance().toJsonString(gatherData));
						}
					}catch (Exception e) {
						log.info("批量上传入账发票执行失败:{}",e);
					}
				}
			} else {
				log.info("数据库没有需要入账的发票");
			}
		} catch (Exception e) {
			log.info("批量上传入账发票执行失败:{}",e);
		}
	}

	/**
	 * @Description 入账发票结果获取接口
	 * @Return void
	 * @Author wangruwei
	 * @Date 2023年9月20日09:57:39
	 **/
	@Override
	public void rzInvoiceResult(TAcOrg collectionControlModel) {
		DynamicContextHolder.push(collectionControlModel.getDbName() + DbConstant.BUSINESS_READ);
		//查询可以发起调用的税号信息
		String taxno = collectionControlModel.getTaxno();
		String aceId = collectionControlModel.getAceId();
		String aceKey = collectionControlModel.getAceKey();
		String dbName = collectionControlModel.getDbName();
		String company = collectionControlModel.getCompany();
		BaseQueJson bqj = new BaseQueJson();

		log.info("查询发票入账处理结果接口查询可以发起调用的税号信息开始:nsrsbh{}", taxno);

		try {

			LambdaQueryWrapper<TdxLqRzApplyLog> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(TdxLqRzApplyLog::getNsrsbh, taxno);
			queryWrapper.eq(TdxLqRzApplyLog::getResultStatus, "N");
			queryWrapper.eq(TdxLqRzApplyLog::getRzlx, "0");
			List<TdxLqRzApplyLog> list = coreTdxDqyRzApplyLogDao.selectList(queryWrapper);
			log.info("找到要获取结果的pclsh数据");
			if (list != null && list.size() > 0) {
				for (TdxLqRzApplyLog tdxLqRzApplyLog : list) {
					String pclsh = tdxLqRzApplyLog.getPclsh();

					//入账发票结果获取
					RzInvoiceResultReq req = new RzInvoiceResultReq();
					req.setBatchNo(pclsh);
					req.setBuyerTaxNo(tdxLqRzApplyLog.getNsrsbh());

					// 保存请求记录
					TDxHttpLog httpLog = new TDxHttpLog();
					httpLog.setTaxno(taxno);
					httpLog.setType("61");
					httpLog.setReqText(JSON.toJSONString(req));
					httpLog.setCompany(company);

					String resText = "";
					try {
						BaseResJson gatherData = Dqyjkdyutil.call(new HashMap<>(), CoreConstants.invoiceRzResult, aceId, aceKey, req);

						// 得到返回报文，解析拿出返回的数量，累加用于判断数量
						httpLog.setReqDate(new Date());
						resText = JSON.toJSONString(gatherData);
						httpLog.setResText(resText);
						httpLog.setResDate(new Date());
						httpLog.setStatus("1");
						log.info(JSON.toJSONString(gatherData));
						log.info("响应请求数据为=" + JSON.toJSONString(gatherData));
						coreConfirmDao.insert(httpLog);

						if (gatherData != null && gatherData.getReturnStateInfo() != null ) {
							RzInvoiceResultResp rzInvoiceResultResp = JSONObject.parseObject(Base64.decodeStr(gatherData.getData()), RzInvoiceResultResp.class);
							if(!CollectionUtils.isEmpty(rzInvoiceResultResp.getInvoices())){
								log.info("authState状态 2:待申请,3:已申请入账,4:入账成功,5:入账失败");
								List<RzInvoiceResultRespInvoice> collect = rzInvoiceResultResp.getInvoices().stream().filter(e -> "2".equals(e.getAuthState()) || "3".equals(e.getAuthState())).collect(Collectors.toList());
								if(collect.size()>0){
									log.info("筛选返回的发票数据里的authState状态，只要有一条是2或者3，代表没处理完，等待下次定时任务继续执行");
									log.info("显示其中一条发票数据:发票代码:{},发票号码:{}",collect.get(0).getInvoiceCode(),collect.get(0).getInvoiceNo());
									continue;
								}else{
									log.info("返回的状态都是4或者5，代表此批次的发票都处理完成，更新t_dx_lq_rz_apply_log的状态");
									TdxLqRzApplyLog updateApply = new TdxLqRzApplyLog();
									updateApply.setResultStatus("Y");
									updateApply.setReturnCode("00");
									updateApply.setUpdateTime(new Date());
									coreTdxDqyRzApplyLogDao.update(updateApply,new LambdaUpdateWrapper<TdxLqRzApplyLog>().eq(TdxLqRzApplyLog::getPclsh, pclsh));
								}

								//要推送票池的uuid集合
								List<String> uuids = new LinkedList();
								for (RzInvoiceResultRespInvoice item: rzInvoiceResultResp.getInvoices()) {
									log.info("发票代码:{},发票号码:{}",item.getInvoiceCode(),item.getInvoiceNo());
									/**
									 * 入账处理状态
									 * 2	待申请
									 * 3	已申请入账
									 * 4	入账成功
									 * 5	入账失败
									 **/
									String authState = item.getAuthState();
									if("2".equals(authState)||"3".equals(authState)){
										log.info("发票处于 待申请 或 已申请入账 状态，不做处理");
									}else if("4".equals(authState)){
										log.info("入账成功，更新t_dx_lq_rz_invoice表和record表");
										//判断原先数据是入账还是撤销入账
										String uuid = (StringUtils.isEmpty(item.getInvoiceCode())?"":item.getInvoiceCode()) + item.getInvoiceNo();
										TdxLqRzInvoice rzInvoice = tdxDqyRzInvoiceDao.selectOne(new LambdaQueryWrapper<TdxLqRzInvoice>().eq(TdxLqRzInvoice::getUuid, uuid));
										TdxLqRzInvoice update = new TdxLqRzInvoice();
										update.setUpdateTime(new Date());
										if(StringUtils.isNotEmpty(item.getAccountPurpose())){
											update.setFprzlx(item.getAccountPurpose());
										}
										if(StringUtils.isNotEmpty(item.getAccountDate())){
											update.setFprzsj(item.getAccountDate());
										}
										if(StringUtils.isNotEmpty(item.getAccountPeriod())){
											update.setFprzsq(item.getAccountPeriod());
										}
										//底账入账状态recordRzzt：01-未入账，02-已入账，03-已入账撤销，04-入账中，05-撤销中
										String recordRzzt = "";
										//发票入账申请
										if("2".equals(rzInvoice.getFprzAuthStatus())){
											update.setFprzAuthStatus("4");
											recordRzzt = "02";
										}else{
											//发票撤销入账申请
											//"6".equals(rzInvoice.getFprzAuthStatus())
											update.setFprzAuthStatus("8");
											recordRzzt = "03";
										}
										tdxDqyRzInvoiceDao.update(update, new LambdaUpdateWrapper<TdxLqRzInvoice>().eq(TdxLqRzInvoice::getUuid,uuid ));
										//更新底账表为
										TDxRecordInvoice updateRecord = new TDxRecordInvoice();
										updateRecord.setLqRzzt(recordRzzt);
										coreTDxRecordInvoiceDao.update(updateRecord,new LambdaUpdateWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, uuid));

									}else if("5".equals(authState)){
										//入账失败 ，判断失败原因，根据失败原因去更新 t_dx_lq_rz_invoice 和 t_dx_record_invoice状态

										//判断原先数据是入账还是撤销入账
										String uuid = (StringUtils.isEmpty(item.getInvoiceCode())?"":item.getInvoiceCode()) + item.getInvoiceNo();
										TdxLqRzInvoice rzInvoice = tdxDqyRzInvoiceDao.selectOne(new LambdaQueryWrapper<TdxLqRzInvoice>().eq(TdxLqRzInvoice::getUuid, uuid));
										TdxLqRzInvoice update = new TdxLqRzInvoice();
										update.setUpdateTime(new Date());
										if(StringUtils.isNotEmpty(item.getAccountPurpose())){
											update.setFprzlx(item.getAccountPurpose());
										}
										if(StringUtils.isNotEmpty(item.getAccountDate())){
											update.setFprzsj(item.getAccountDate());
										}
										if(StringUtils.isNotEmpty(item.getAccountPeriod())){
											update.setFprzsq(item.getAccountPeriod());
										}
										//底账入账状态recordRzzt：01-未入账，02-已入账，03-已入账撤销，04-入账中，05-撤销中
										String recordRzzt = "";
										//发票入账申请 失败
										if("2".equals(rzInvoice.getFprzAuthStatus())){
											update.setFprzAuthStatus("3");
											recordRzzt = "01";
											//判断，如果失败原因是  4 该票已入账，票是入账成功
											if("4".equals(item.getFailureReason())){
												update.setFprzAuthStatus("4");
												recordRzzt = "02";
											}
										}else{
											//"6".equals(rzInvoice.getFprzAuthStatus())
											//发票撤销入账申请 失败
											update.setFprzAuthStatus("7");
											recordRzzt = "02";
										}

										//失败原因设置
										update.setFprzsbyy(getFprzSbyy(item.getFailureReason()));

										tdxDqyRzInvoiceDao.update(update, new LambdaUpdateWrapper<TdxLqRzInvoice>().eq(TdxLqRzInvoice::getUuid,uuid ));
										//更新底账表为
										TDxRecordInvoice updateRecord = new TDxRecordInvoice();
										updateRecord.setLqRzzt(recordRzzt);
										coreTDxRecordInvoiceDao.update(updateRecord,new LambdaUpdateWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, uuid));
									}

									if("4".equals(authState)){
										uuids.add(CommonUtil.getUuid(item.getInvoiceCode(),item.getInvoiceNo()));
									}
								}
								//推送新票池记录表
								poolLogService.pushChangeToPool(ConfigureConstant.POOL_SJLX_JXFP_1, uuids, ConfigureConstant.POOL_BGLX_ZTBG_2);

							}
						}
					}catch (Exception e){
						httpLog.setReqDate(new Date());
						httpLog.setResText(StringUtils.isBlank(resText)?"error":resText);
						httpLog.setResDate(new Date());
						httpLog.setStatus("2");
						coreConfirmDao.insert(httpLog);
						log.info("入账发票结果获取接口异常:{}",e);
					}
				}
			} else {
				log.info("数据库没有未返回认证结果的记录");
			}
		} catch (Exception e) {
			log.info("发票入账结果获取执行失败:{}",e);
		}

	}
	/**
	* @Description 入账失败原因设置
	* @Author wangruwei
	* @Date 2024/3/21 16:59
	**/
	private String getFprzSbyy(String failureReason) {
		String str;
		switch (failureReason) {
			case "2":
				str = "无此票";
				break;
			case "3":
				str = "该票异常无法入账";
				break;
			case "4":
				str = "该票已入账";
				break;
			case "6":
				str = "该票已申请入账";
				break;
			case "8":
				str = "其他异常";
				break;
			case "10":
				str = "红票不能入账";
				break;
			case "12":
				str = "用户无权限";
				break;
			case "13":
				str = "token超过五天未获取";
				break;
			default:
				str = "";
				break;
		}
		return str;
	}

	/**
	 * @Description 已入账发票采集
	 * @Return void
	 * @Author wangruwei
	 * @Date 2023/12/8 9:41
	 **/
    @Override
    public void alreadyRzInvoiceGj(CollectionControlModel ccm) {
		log.info("已入账发票采集...企业信息:{}", JsonUtils.getInstance().toJsonString(ccm));
		DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_READ);
		try {
			Map<String, Object> httpLogMap = new HashMap<>();

			int totalRow = 0;
			int addRow = 0;
			//组装请求数据
			// 随机生成32位批次号
			String batchNo = Dqyjkdyutil.getBatchNo();
			AlreadyRzInvoiceGjReq alreadyRzInvoiceGjReq = new AlreadyRzInvoiceGjReq();
			alreadyRzInvoiceGjReq.setBuyerTaxNo(ccm.getNsrsbh());
			alreadyRzInvoiceGjReq.setBatchNo(batchNo);
			alreadyRzInvoiceGjReq.setAcquisitionDateBegin(getBeginTime(ccm, "03", null));
			alreadyRzInvoiceGjReq.setAcquisitionDateEnd(Dqyjkdyutil.getEndTime());
			alreadyRzInvoiceGjReq.setStartRow(1);
			alreadyRzInvoiceGjReq.setStatus("1");

			DynamicContextHolder.push(ccm.getDbName() + DbConstant.BUSINESS_WRITE);
			while (true) {
				TDxHttpLogZzsfpgjEntity thlzf = new TDxHttpLogZzsfpgjEntity();
				//调用大企业接口
				BaseResJson gatherData = Dqyjkdyutil.call(httpLogMap, CoreConstants.alreadyRzInvoiceGj, ccm.getAceId(), ccm.getAcekey(), alreadyRzInvoiceGjReq);

				if (gatherData != null && gatherData.getReturnStateInfo() != null && gatherData.getReturnStateInfo().getReturnCode().equals(ConfigureConstant.SECCESS_CODE)) {
					if (StringUtils.isNotBlank(gatherData.getData())) {
						JSONObject jsonObject = JSON.parseObject(Base64Encoding.decodeToString(gatherData.getData()));
						if (jsonObject.getJSONArray("invoices") != null && jsonObject.getJSONArray("invoices").size() > 0) {
							log.info("处理入账结果");
							dealInvoiceRz(jsonObject.getJSONArray("invoices"));

							//保存增值税发票归集记录表
							log.info("保存大企业已入账发票采集记录表");
							thlzf.setCompany(ccm.getCompany());
							thlzf.setBatchNo(batchNo);
							thlzf.setType("03");
							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")));
							tDxHttpZzsfpgjDao.insert(thlzf);
							totalRow = jsonObject.getIntValue("totalRows");
							addRow += jsonObject.getIntValue("contentRows");
						} else {
							log.info("大企业接口返回已入账发票采集节点为空：{}",JsonUtils.getInstance().toJsonString(gatherData));
							break;
						}
						if (addRow < totalRow) {
							alreadyRzInvoiceGjReq.setStartRow(addRow);
						} else {
							log.info("大企业接口当前批次调用完成");
							break;
						}
					} else {
						log.info("大企业接口返回data节点为空：{}",JsonUtils.getInstance().toJsonString(gatherData));
						break;
					}
				} else {
					log.info("大企业接口返回失败：{}",JsonUtils.getInstance().toJsonString(gatherData));
					break;
				}
			}
			log.info("---当前税号处理完成---");

		} catch (Exception e) {
			log.debug("已入账发票采集任务处理异常：{}",e);
		}
	}

	/**
	* @Description 处理已入账发票归集
	* @Author wangruwei
	* @Date 2023/12/8 10:57
	**/
	private void dealInvoiceRz(JSONArray invoicesArray) {
		List<AlreadyRzInvoiceGjRespInvoice> invoices = invoicesArray.toJavaList(AlreadyRzInvoiceGjRespInvoice.class);
		//要推送票池的uuid集合
		List<String> uuids = new LinkedList();
		for (AlreadyRzInvoiceGjRespInvoice item :invoices) {
			String uuid = item.getInvoiceCode() + item.getInvoiceNo();
			TDxRecordInvoice tDxRecordInvoice = coreTDxRecordInvoiceDao.selectOne(new LambdaQueryWrapper<TDxRecordInvoice>().eq(TDxRecordInvoice::getUuid, uuid));
			if(ObjectUtil.isNotEmpty(tDxRecordInvoice)){
				//底账表更新
				TDxRecordInvoice updateInvoice = new TDxRecordInvoice();
				if(StringUtils.isNotEmpty(item.getInvoiceStatus())){
					updateInvoice.setInvoiceStatus(item.getInvoiceStatus());
				}
				if(StringUtils.isNotEmpty(item.getGlzt())){
					updateInvoice.setGlzt(item.getGlzt());
				}
				if(StringUtils.isNotEmpty(item.getAccountStatus())){
					updateInvoice.setLqRzzt("0".equals(item.getAccountStatus())?"01":"02");
					//updateInvoice.setInAccountStatus(item.getAccountStatus());
				}
				//if(StringUtils.isNotEmpty(item.getAccountDate())){
				//	updateInvoice.setInAccountDate(DateUtils.strToDate(item.getAccountDate(), "yyyy-MM-dd"));
				//}
				updateInvoice.setId(tDxRecordInvoice.getId());
				coreTDxRecordInvoiceDao.updateById(updateInvoice);

				//入账表没有的话，插入，有则更新
				TdxLqRzInvoice tdxLqRzInvoice = tdxDqyRzInvoiceDao.selectOne(new LambdaQueryWrapper<TdxLqRzInvoice>().eq(TdxLqRzInvoice::getUuid, uuid));
				if(ObjectUtil.isEmpty(tdxLqRzInvoice)){
					TdxLqRzInvoice insert = new TdxLqRzInvoice();
					insert.setNsrsbh(tDxRecordInvoice.getGfTaxNo());
					insert.setInvoiceType(tDxRecordInvoice.getInvoiceType());
					insert.setInvoiceCode(tDxRecordInvoice.getInvoiceCode());
					insert.setInvoiceNo(tDxRecordInvoice.getInvoiceNo());
					insert.setEleInvoiceNo(tDxRecordInvoice.getEleInvoiceNo());
					insert.setUuid(tDxRecordInvoice.getUuid());
					insert.setInvoiceDate(tDxRecordInvoice.getInvoiceDate());
					insert.setFprzsq(item.getAccountPeriod());
					insert.setFprzAuthStatus("1".equals(item.getAccountStatus())?"4":"0");
					insert.setFprzlx(item.getAccountPurpose());
					insert.setFprzsj(DateUtils.dateToStr(DateUtils.strToDate(item.getAccountDate(),"yyyy-MM-dd"),"yyyyMMdd"));
					insert.setFprzsbyy("");
					insert.setCreateTime(new Date());
					tdxDqyRzInvoiceDao.insert(insert);
				}else{
					TdxLqRzInvoice update = new TdxLqRzInvoice();
					update.setFprzlx(item.getAccountPurpose());
					//采集回来属期空，则不处理属期字段
					if(StringUtils.isNotBlank(item.getAccountPeriod())){
						update.setFprzsq(item.getAccountPeriod());
					}
					update.setFprzAuthStatus("1".equals(item.getAccountStatus())?"4":"0");
					update.setFprzsj(DateUtils.dateToStr(DateUtils.strToDate(item.getAccountDate(),"yyyy-MM-dd"),"yyyyMMdd"));
					update.setId(tdxLqRzInvoice.getId());
					tdxDqyRzInvoiceDao.updateById(update);
				}

				uuids.add(uuid);
			}else{
				log.info("底账表不存在此数据，跳过处理下一条，当前uuid:{}",uuid);
				continue;
			}
		}
		//推送新票池记录表
		poolLogService.pushChangeToPool(ConfigureConstant.POOL_SJLX_JXFP_1, uuids, ConfigureConstant.POOL_BGLX_SJBG_1);
	}


	/**
	 * 获取开始时间
	 *
	 * @return
	 */
	private String getBeginTime(CollectionControlModel ccm, String type,String invoiceType) {
		//查询增值税发票归集上次请求时间
		String lastTime = tDxRecordInvoiceJobDao.selectZzsfpgjLastreqDate(ccm.getNsrsbh(), type,invoiceType);
		return Dqyjkdyutil.getBeginTime(lastTime, ccm.getFirstCollectDate());
	}

    private String getFailureMsg(String failureCode) {
		/**
		 * 2	无此票	可重复提交
		 * 3	该票异常无法入账	不可重复提交
		 * 4	该票已入账	不可重复提交
		 * 6	该票已申请入账	不可重复提交
		 * 8	其他异常	可重复提交
		 * 10	红票不能入账	不可重复提交
		 * 12	用户无权限	可重复提交
		 * 13	token超过五天未获取	可重复提交
		 **/
		String msg = "无对应编码:"+failureCode;
		switch (failureCode){
			case "2":
				msg = "无此票";
			case "3":
				msg = "该票异常无法入账";
			case "4":
				msg = "该票已入账";
			case "6":
				msg = "该票已申请入账";
			case "8":
				msg = "其他异常";
			case "10":
				msg = "红票不能入账";
			case "12":
				msg = "用户无权限";
			case "13":
				msg = "token超过五天未获取";
		}
		return msg;
	}


	/**
	 * 获取时间戳
	 *
	 * @return String
	 */
	public String getDataExchangeId() {
		// enterpriseCode+8 位日期
		// (YYYYMMDD)+9 位序列号
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		StringBuilder sb = new StringBuilder();
		Random rand = new Random();
		for (int i = 0; i < 9; i++) {
			sb.append(rand.nextInt(10));
		}
		String data = sb.toString();
		return CoreConstants.enterpriseCode + simpleDateFormat.format(new Date()) + data;
	}

	/**
	 * 加密方法
	 */
	public String makeAppSec(String data, String dataExchangeId, String interfaceCode, String aceId, String aceKey) {
		String srcStr =
				"POST/down/invoice/dii?authorize={\"appSecId\":\"" + aceId + "\"}&globalInfo={\"appId\":\"" + CoreConstants.appId
						+ "\",\"version\":\"" + CoreConstants.version + "\",\"interfaceCode\":\"" + interfaceCode + "\",\"enterpriseCode\":\""
						+ CoreConstants.enterpriseCode + "\",\"dataExchangeId\":\"" + dataExchangeId + "\"}&" + "data=" + data + "";
		log.info("待加密的请求：" + srcStr);
		SecretKeySpec keySpec = null;
		keySpec = new SecretKeySpec(aceKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");
		Mac mac = null;
		try {
			mac = Mac.getInstance("HmacSHA1");
		} catch (NoSuchAlgorithmException e) {
			log.info("加密异常:{}",e);
		}
		try {
			mac.init(keySpec);
		} catch (InvalidKeyException e) {
			log.info("加密异常mac.init:{}",e);
		}
		byte[] singBytes = new byte[0];
		singBytes = mac.doFinal(srcStr.getBytes(StandardCharsets.UTF_8));
		String appSec = Base64.encode(singBytes);
		log.info("interfaceCode接口生成的加密串=appSec：{}",appSec);
		return appSec;
	}

	/**
	 * 获取批次号
	 */
	public String getBatchNo() {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
		String date = simpleDateFormat.format(new Date());
		StringBuilder sb = new StringBuilder();
		Random rand = new Random();
		for (int i = 0; i < 24; i++) {
			sb.append(rand.nextInt(10));
		}
		String data = sb.toString();
		return date + data;
	}


}
