package com.jianshui.invoice.service.impl.api;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.core.domain.entity.Companyservice;
import com.jianshui.common.enums.ErrorCode;
import com.jianshui.common.exception.jianshui.JianshuiParamErrorException;
import com.jianshui.common.exception.jianshui.JianshuiServiceException;
import com.jianshui.common.utils.*;
import com.jianshui.common.utils.uuid.IdUtils;
import com.jianshui.invoice.constant.aisino.console.AisinoConsoleConstants;
import com.jianshui.invoice.domain.*;
import com.jianshui.invoice.domain.dto.*;
import com.jianshui.invoice.domain.dto.api.*;
import com.jianshui.invoice.domain.dto.api.aisino.console.*;
import com.jianshui.invoice.domain.vo.api.aisino.console.AisinoConsoleInvoiceAddVO;
import com.jianshui.invoice.mapper.BillInfoMapper;
import com.jianshui.invoice.mapper.InvoiceMapper;
import com.jianshui.invoice.mapper.RedinfoMapper;
import com.jianshui.invoice.mapper.SkDyjMapper;
import com.jianshui.invoice.service.IInvoiceApiService;
import com.jianshui.invoice.utils.BillInfoUtils;
import com.jianshui.invoice.utils.aisino.console.AisinoConsoleUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author dxk
 * @date 2022年06月27日 11:18
 * 总部控制台-开票
 */
@Component("aisino_console_invoice")
@Slf4j
public class AisinoConsoleInvoiceApiServiceImpl implements IInvoiceApiService {

    @Autowired
    private BillInfoMapper billInfoMapper;
    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private SkDyjMapper skDyjMapper;

    @Autowired
    private RedinfoMapper redinfoMapper;


    /**
     * 1.发票开具 SID = 1
     *
     * @param billInfo
     * @param companyservice
     * @return com.jianshui.invoice.domain.dto.HXResponse
     * @author dxk
     * @date 2022/6/27 16:50
     */
    @Override
    public HXResponse addInvoice(BillInfo billInfo, Companyservice companyservice) throws IllegalAccessException, InstantiationException {

        // 预处理：处理billinfo，计算税额等
        try {
            billInfo = BillInfoUtils.processBillInfo(billInfo, companyservice);
        } catch (JianshuiParamErrorException e) {
            return new HXResponse(e.getMessage());
        } catch (Exception e) {
            log.error("【销项】【总部控制台发票】开票接口校验异常", e);
            return new HXResponse("格式校验失败，请检查报文！");
        }

        // 发票类型处理 必填
        Integer invoceTypeTemp = CovertInvoiceType(billInfo.getInvoiceType());
        if (invoceTypeTemp == -1) {
            return new HXResponse("发票类型不存在！");
        }

        billInfo.setInvoiceType(String.valueOf(invoceTypeTemp));

        // 转换报文为总部控制台请求报文
        AisinoConsoleInvoiceAddDTO aisinoConsoleInvoiceAddDTO = BeanUtil.copyProperties(billInfo, AisinoConsoleInvoiceAddDTO.class);

        List<BillDetail> billDetailList = billInfo.getBillDetailList();
        if (CollectionUtils.isEmpty(billDetailList)) {
            return new HXResponse("发票明细不存在，请检查报文！");
        }

        aisinoConsoleInvoiceAddDTO.setInvoiceType(invoceTypeTemp);

        //购方地址电话
        String buyerAddress = billInfo.getBuyerAddress() != null ? billInfo.getBuyerAddress(): "";
        String buyerTelPhone = billInfo.getBuyerTelephone() !=null ? billInfo.getBuyerTelephone(): "";
        aisinoConsoleInvoiceAddDTO.setCustomerAddressTel(buyerAddress + buyerTelPhone);

        //购方银行账户
        String buyerBank = billInfo.getBuyerBank() != null ? billInfo.getBuyerBank():"";
        String buyerAccount = billInfo.getBuyerAccount() !=null ? billInfo.getBuyerAccount():"";
        aisinoConsoleInvoiceAddDTO.setCustomerBankAccountNr(buyerBank + buyerAccount);

        //销方银行账户
        String sellerBank = billInfo.getSellerBank();
        String sellerAccount = billInfo.getSellerAccount();
        if (StrUtil.isEmpty(sellerBank) || StrUtil.isEmpty(sellerAccount)) {
            return new HXResponse("销方银行账户不存在！");
        }
        aisinoConsoleInvoiceAddDTO.setSellerBankAccountNr(sellerBank + sellerAccount);

        // 销方地址电话
        // 2022/12/21 中举说浪潮的地址和电话都放到 sellerAddress字段里了
        /*String sellerAddress = billInfo.getSellerAddress();
        String sellerTelephone = billInfo.getSellerTelephone();
        if (StrUtil.isEmpty(sellerAddress) || StrUtil.isEmpty(sellerTelephone)) {
            return new HXResponse("销方地址电话不存在！");
        }
        aisinoConsoleInvoiceAddDTO.setSellerAddressTel(sellerAddress + sellerTelephone);*/
        String sellerAddress = billInfo.getSellerAddress();
        if (StrUtil.isEmpty(sellerAddress)) {
            return new HXResponse("销方地址电话不存在！");
        }
        aisinoConsoleInvoiceAddDTO.setSellerAddressTel(sellerAddress);

        //清单标志
        String qdbz = billInfo.getQdbz();
        if (StrUtil.isEmpty(qdbz)) {
            return new HXResponse("清单标志不存在！");
        }
        boolean qdbzTemp = qdbz.equals("1") ? true : false;
        aisinoConsoleInvoiceAddDTO.setListed(qdbzTemp);

        // 销售单号 非必填
        //aisinoConsoleInvoiceAddDTO.setDocumentNr("");
        // 开票校验标识 问了下主任这里默认塞 0 标识开票
        aisinoConsoleInvoiceAddDTO.setCheckEWM(0);

        //税额
        BigDecimal tax = billInfo.getTax();
        aisinoConsoleInvoiceAddDTO.setTax(Convert.toDouble(tax));

        //数量 非必填
        //aisinoConsoleInvoiceAddDTO.setQuantity(0.0D);

        //专票必填
        if (invoceTypeTemp == 0) {
            if (StrUtil.isEmpty(aisinoConsoleInvoiceAddDTO.getCustomerTaxNr())) {
                return new HXResponse("购方税号不存在，专票！");
            }
            if (StrUtil.isEmpty(aisinoConsoleInvoiceAddDTO.getCustomerAddressTel())) {
                return new HXResponse("购方地址电话不存在，专票！");
            }
            if (StrUtil.isEmpty(aisinoConsoleInvoiceAddDTO.getCustomerBankAccountNr())) {
                return new HXResponse("购方银行账户不存在，专票！");
            }
        }

        //处理备注
        String kpType = billInfo.getKptype() == null ? "":billInfo.getKptype() ;
        String redInvoiceCode = billInfo.getRedInvoiceInfoCode() == null ? "":billInfo.getRedInvoiceInfoCode();
        if("2".equals(kpType) && invoceTypeTemp == 0){
            //专票：红字信息表编号 开具红字发票：备注中注明“开具红字增值税专用发票信息表编号 XXXXXXXXXXXXXXXX”
           aisinoConsoleInvoiceAddDTO.setMemo("开具红字增值税专用发票信息表编号"+redInvoiceCode);
        }else if("2".equals(kpType) && invoceTypeTemp == 2){
            //普票：开具负数发票（普通发票负数发票）：备注中注明“对应正数发票代码 XXXXXXXXXX 号 码 YYYYYYYY”字样，其中“X”为发票左上角 10 或是 12 位代码数字，“Y”为发票右上角 8位号码数字
            aisinoConsoleInvoiceAddDTO.setMemo("对应正数发票代码"+billInfo.getOriginFpdm()+"号码"+billInfo.getOriginFphm());
        }

        //明细处理前条件校验
        ValidateUtils.validate(aisinoConsoleInvoiceAddDTO, companyservice, null);

        //发票明细处理
        List<AisinoConsoleInvoiceAddDetailDTO> invoiceItems = new ArrayList<>();
        List<Map<String,Object>> listMap = new ArrayList<>();
        for (BillDetail billDetail : billDetailList) {
            AisinoConsoleInvoiceAddDetailDTO addDetailDTO = BeanUtil.copyProperties(billDetail, AisinoConsoleInvoiceAddDetailDTO.class);

            //通过含税标志，区分含税单价不含税单价
            Integer hsbz = billDetail.getHsbz();
            if (hsbz == null) {
                return new HXResponse("含税标志不存在！");
            }
            addDetailDTO.setIncludeTax(hsbz == 1 ? true : false);
            //税率
            addDetailDTO.setTaxRate(Convert.toDouble(billDetail.getTaxrate()));
            //金额
            Double je = 0D;
            if (hsbz == 1) {
                je = Convert.toDouble(billDetail.getTaxamt());
            } else if (hsbz == 0) {
                je = Convert.toDouble(billDetail.getTaxfreeamt());
            } else {
                return new HXResponse("金额不存在！");
            }
            addDetailDTO.setValue(je);
            //单价
            addDetailDTO.setPrice(Convert.toDouble(billDetail.getPrice()));

            //是否享受优惠政策
            Integer yhzcbs = billDetail.getYhzcbs();
            if (yhzcbs == null) {
                return new HXResponse("优惠政策标识不存在！");
            }
            addDetailDTO.setTaxPre(String.valueOf(yhzcbs));
            //享受优惠政策内容 非必填
            //addDetailDTO.setTaxPreCon("");
            //企业自编码 非必填
            //addDetailDTO.setCropGoodsNo("");

            ValidateUtils.validate(addDetailDTO, companyservice, null);
            invoiceItems.add(addDetailDTO);
            Map<String,Object> mapDetail = BeanToMapUtils.fastJsonBean2Map(addDetailDTO);
            listMap.add(mapDetail);
        }
        aisinoConsoleInvoiceAddDTO.setInvoiceItems(invoiceItems);

        // 发起请求
        AjaxResult ajaxResult = null;
        try {
            //hutool的beancopy别名会与JSONUTIl冲突
            Map<String,Object> map = BeanToMapUtils.fastJsonBean2Map(aisinoConsoleInvoiceAddDTO);
            map.put("invoiceItems",listMap);
            ajaxResult = AisinoConsoleUtil.sendRequest(AisinoConsoleConstants.INVOICE_ADD, JSONUtil.parse(map), companyservice);
        } catch (Exception e) {
            log.error("【销项发票】【总部控制台接口】【发票开具】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(aisinoConsoleInvoiceAddDTO).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【总部控制台发票】发票开具请求拉取结果{}", ajaxResult.toString());

        //返回报文解析
        if (ajaxResult.isError()) {
            throw new JianshuiServiceException(ajaxResult.getMsg());
        }

        cn.hutool.json.JSONObject resultJSON = JSONUtil.parseObj(ajaxResult.get("data"));
        String retcode = resultJSON.get("retcode") != null ? resultJSON.get("retcode").toString() : "";
        String retmsg = resultJSON.get("retmsg") != null ? resultJSON.get("retmsg").toString() : "";
        if ("4011".equals(retcode)) {
            //回写发票代码、发票号码信息
            if(StrUtil.isEmpty(retmsg)){
                return new HXResponse(retcode);
            }
            AisinoConsoleInvoiceAddVO aisinoConsoleInvoiceAddVO = BeanUtil.copyProperties(resultJSON, AisinoConsoleInvoiceAddVO.class);
            if(StrUtil.isEmpty(aisinoConsoleInvoiceAddVO.getInfoNumber())){
                throw new JianshuiServiceException("开具的发票号码不存在！");
            }
            //更新发票状态
            billInfo.setState(2);
            billInfoMapper.updateBillInfo(billInfo);

            //插入invoice
            Invoice invoice = BeanUtil.copyProperties(billInfo,Invoice.class);
            List<InvoiceDetail> invoiceDetailList = BeanUtil.copyToList(billInfo.getBillDetailList(),InvoiceDetail.class);
            invoice.setInvoiceDetailList(invoiceDetailList);

            //发票代码
            invoice.setFpdm(aisinoConsoleInvoiceAddVO.getInfoTypeCode());
            //发票号码
            invoice.setFphm(aisinoConsoleInvoiceAddVO.getInfoNumber());
            //上一张发票代码
            invoice.setOriginFpdm(aisinoConsoleInvoiceAddVO.getHisInfoTypeCode());
            //上一张发票号码
            invoice.setOriginFphm(aisinoConsoleInvoiceAddVO.getHisInfoNumber());
            //上一张发票种类
            String hisInvoceTypeTemp = CovertInvoiceTypeReverse(aisinoConsoleInvoiceAddVO.getHisInfoKind());
            invoice.setInvoiceType(hisInvoceTypeTemp);
            invoice.setBillInfoId(billInfo.getId());

            long id = 0L;
            QueryWrapper<Invoice> invoiceQueryWrapper = new QueryWrapper<>();
            invoiceQueryWrapper.eq("fpdm",invoice.getFpdm()).eq("fphm",invoice.getFphm());
            List<Invoice> invoices = invoiceMapper.selectList(invoiceQueryWrapper);
            if(CollectionUtils.isEmpty(invoices)){
                invoiceMapper.insertInvoice(invoice);
                invoices = invoiceMapper.selectList(invoiceQueryWrapper);
                id = invoices.get(0).getId();
            }else{
                Invoice invoiceT = invoices.get(0);
                invoiceT = BeanUtil.copyProperties(invoice,Invoice.class);
                invoiceMapper.updateInvoice(invoiceT);
                id = invoiceT.getId();
            }
            invoiceDetailList.forEach(i -> i.setInvoiceId(invoice.getId()));
            invoiceMapper.batchInvoiceDetail(invoiceDetailList);

            HXResponse response = new HXResponse("0000", "同步成功");
            response.put("fpqqlsh", billInfo.getSystemOrderno());
            return response;
        } else {
            return new HXResponse(retmsg);
        }
    }


    /**
     * 发票打印
     * @author dxk
     * @date 2022/6/29 13:48
     * @param invoice
     * @param companyservice
     * @return com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult printInvoice(Invoice invoice, Companyservice companyservice) {
        return null;
    }


    /**
     * 发票作废
     * @author dxk
     * @date 2022/6/30 9:43
     * @param invoice
     * @param companyservice
     * @return com.jianshui.invoice.domain.dto.HXResponse
     */
    @Override
    public HXResponse deprecateInvoice(JSONObject invoice, Companyservice companyservice) {

        // kk: 2023/2/7  改为通用查询，流水号或发票代码发票号码
        // 查找原来的发票
        String fpqqlsh = invoice.getString("fpqqlsh");
        String fpdm = invoice.getString("fpdm");
        String fphm = invoice.getString("fphm");

        // 发票查询
        Invoice invoiceTemp = null;
        if (StringUtils.isNotEmpty(fpqqlsh)) {
            invoiceTemp = invoiceMapper.selectBySystemOrderNo(companyservice.getCompanyid(), fpqqlsh);
        } else if (StringUtils.isNotEmpty(fpdm) && StringUtils.isNotEmpty(fphm)) {
            invoiceTemp = invoiceMapper.selectByFpdmFphm(companyservice.getCompanyid(), fpdm, fphm);
        } else {
            throw new JianshuiParamErrorException(ErrorCode.EMPTY_FPQQLSH, companyservice, "invoice");
        }

        //发票不存在
        if (invoiceTemp == null) {
            throw new JianshuiParamErrorException(ErrorCode.INVOICE_NOT_EXISTS, companyservice, "invoice");
        }

        AisinoConsoleInvolidDTO consoleInvolidDTO = BeanUtil.copyProperties(invoiceTemp,AisinoConsoleInvolidDTO.class);

        //发票类型
        Integer invoceTypeTemp = CovertInvoiceType(invoiceTemp.getInvoiceType());
        if (invoceTypeTemp == -1) {
            throw new JianshuiParamErrorException(ErrorCode.ERROR_INVOICELINE, companyservice, "invoice");
        }
        consoleInvolidDTO.setInfoKind(invoceTypeTemp);

        ValidateUtils.validate(consoleInvolidDTO,companyservice,null);

        //发起请求
        AjaxResult ajaxResult = null;
        try{
            Map<String,Object> map = BeanToMapUtils.fastJsonBean2Map(consoleInvolidDTO);
            ajaxResult = AisinoConsoleUtil.sendRequest(AisinoConsoleConstants.INVOICE_INVOLID, JSONUtil.parse(map), companyservice);
        }catch (Exception e){
            log.error("【销项发票】【总部控制台接口】【发票作废】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(consoleInvolidDTO).toString(), JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }

        //返回报文解析
        if (ajaxResult.isError()) {
            throw new JianshuiServiceException(ajaxResult.getMsg());
        }

        cn.hutool.json.JSONObject resultJSON = JSONUtil.parseObj(ajaxResult.get("data"));
        String retcode = resultJSON.get("retcode") != null ? resultJSON.get("retcode").toString() : "";
        String retmsg = resultJSON.get("retmsg") != null ? resultJSON.get("retmsg").toString() : "";
        if("6011".equals(retcode)){
            // 修改原有发票状态为已作废
            invoiceTemp.setState(3);
            invoiceMapper.updateInvoice(invoiceTemp);

            // 更新原有订单
            BillInfo originBillInfo = billInfoMapper.selectBySystemOrderNo(companyservice.getCompanyid(), invoiceTemp.getSystemOrderno());
            if (originBillInfo == null) {
                log.error("【销项】【总部控制台】作废发票，无法查找到原有发票{}", JSONObject.toJSONString(invoiceTemp));
            } else {
                originBillInfo.setState(3);
                billInfoMapper.updateBillInfo(originBillInfo);
            }
            return new HXResponse("0000", "作废完成", null, false);
        }else{
            return new HXResponse(retmsg);
        }

    }


    @Override
    public AjaxResult reInvoice(BillInfo billInfo, Companyservice companyservice) {
        return null;
    }

    /**
     * 单个发票查询
     * @param billInfo
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse queryInvoice(QueryBillInfoDTO billInfo, Companyservice companyservice) {

        Invoice invoiceQuery = new Invoice();
        invoiceQuery.setCompanyId(billInfo.getCompanyId());
        if (StringUtils.isNotEmpty(billInfo.getFpqqlsh())) {
            invoiceQuery.setFpqqlsh(billInfo.getFpqqlsh());
        } else if (StringUtils.isNotEmpty(billInfo.getOutTradeOrderno())) {
            invoiceQuery.setSystemOrderno(billInfo.getSystemOrderno());
        } else {
            HXResponse response = new HXResponse("9997", "订单号或流水号不能同时为空");
            return response;
        }

        Invoice invoice = invoiceMapper.selectInvoiceAllIn(invoiceQuery);
        if (invoice == null) {
            Invoice tempInvoice = new Invoice();
            tempInvoice.setInvoiceMsg("发票信息不存在");
            if (billInfo.getSystemOrderno() != null) {
                tempInvoice.setSystemOrderno(billInfo.getSystemOrderno());
            }
            if (billInfo.getOutTradeOrderno() != null) {
                tempInvoice.setOutTradeOrderno(billInfo.getOutTradeOrderno());
            }
            if (billInfo.getFpqqlsh() != null) {
                tempInvoice.setFpqqlsh(billInfo.getFpqqlsh());
            }
            HXResponse response = new HXResponse("9998", "发票信息不存在", tempInvoice);
            return response;
        }else{

        }

        HXResponse response = new HXResponse("0000", "查询成功", invoice);
        return response;
    }

    /**
     * 发票批量查询
     * @param billInfo
     * @param byWhat
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse batchQueryInvoices(BillInfo billInfo, String byWhat, Companyservice companyservice) {

        String fpqqlsh = billInfo.getFpqqlsh();
        String orderNo = billInfo.getOutTradeOrderno();
        List<Object> result = new ArrayList<>();
        List<BillInfo> queryBillInfo = new ArrayList<>();
        if (StringUtils.equals("fpqqlsh", byWhat)) {
            JSONArray fpqqlshs = JSONArray.parseArray(fpqqlsh);
            if (fpqqlshs == null) {
                fpqqlshs = new JSONArray();
                fpqqlshs.add(fpqqlsh);
            }
            fpqqlshs.forEach(i -> {
                BillInfo tempBillInfo = new BillInfo();
                tempBillInfo.setCompanyId(companyservice.getCompanyid());
                tempBillInfo.setFpqqlsh((String) i);
                queryBillInfo.add(tempBillInfo);
            });
        }

        if (StringUtils.equals("orderno", byWhat)) {
            JSONArray fpqqlshs = JSONArray.parseArray(orderNo);
            if (fpqqlshs == null) {
                fpqqlshs = new JSONArray();
                fpqqlshs.add(orderNo);
            }
            fpqqlshs.forEach(i -> {
                BillInfo tempBillInfo = new BillInfo();
                tempBillInfo.setCompanyId(companyservice.getCompanyid());
                tempBillInfo.setOutTradeOrderno((String) i);
                queryBillInfo.add(tempBillInfo);
            });
        }

        queryBillInfo.forEach(i -> {
            QueryBillInfoDTO queryBillInfoDTO = new QueryBillInfoDTO();
            BeanUtils.copyProperties(i, queryBillInfoDTO);
            HXResponse tempResult = this.queryInvoice(queryBillInfoDTO, companyservice);
            result.add(tempResult.getData());
        });

        return new HXResponse("0000", "查询成功", result);
    }

    @Override
    public HXResponse scopeQueryInvoices(JSONObject queryJson, Companyservice companyservice) {
        return null;
    }

    /** 红字信息表上传*/
    @Override
    public HXResponse uploadRedInfo(Redinfo redinfo, Companyservice companyservice) {

        // 前置处理
        redinfo.setCompanyId(companyservice.getCompanyid());
        redinfo.setSystemOrderno(IdUtils.randomSystemOrderno());
        if (StringUtils.isEmpty(redinfo.getOutTradeOrderno())) {
            // 把 outTradeOrderno作为用户的申请单号
            throw new JianshuiParamErrorException(ErrorCode.EMPTY_REDINFO_NO, companyservice, "invoice");
        }
        redinfo.setOutTradeOrderno(redinfo.getOutTradeOrderno());
        redinfo.setFpqqlsh(redinfo.getSystemOrderno());
        redinfo.setRedInfoStatus("0");
        redinfo.setSellerName(companyservice.getSellername());
        redinfo.setSellerTaxnum(companyservice.getSellertax());
        redinfo.setBillInputTime(TimeUtil.dateFormat(new Date(), "yyyyMMddHHmmss"));
        List<Redinfodetail> redinfodetailList = redinfo.getRedinfodetailList();
        BigDecimal taxfreeamt = new BigDecimal(0); // 不含税金额
        BigDecimal tax = new BigDecimal(0); // 税额
        for (Redinfodetail detail : redinfodetailList) {
            taxfreeamt = taxfreeamt.add(detail.getTaxfreeamt());
            tax = tax.add(detail.getTax());
        }
        redinfo.setTax(tax);
        redinfo.setTaxfreeamt(taxfreeamt);
        redinfo.setTaxamt(tax.add(taxfreeamt));
        redinfoMapper.insertRedinfo(redinfo);
        int index = 0;

        String spbm = "";

        for (Redinfodetail detail : redinfodetailList) {
            detail.setBillno(redinfo.getRedInfoNo());
            detail.setRedinfoId(redinfo.getId());
            detail.setIndex(++index);
            detail.setBillno(redinfo.getRedInfoNo());
            taxfreeamt = taxfreeamt.add(detail.getTaxfreeamt());
            tax = tax.add(detail.getTax());

            // 商品编码
            spbm = detail.getSpbm();
        }

        // TODO: 2023/3/9 设备号是 jspbh 并非billNO？  申请方税号reqnsrsbh
        //
        redinfo.setJspbh("661024643068230218103524".substring(0,12));
        redinfo.setReqnsrsbh("9113093067851155XY");
        redinfo.setFjh("123");
        redinfo.setMultTaxRate("0");
        redinfo.setBillInputTime("2022-11-11");
        redinfo.setBmbbh("2323232");
        redinfo.setTaxrate(new BigDecimal("0.03"));
        //

        redinfoMapper.batchRedinfodetail(redinfodetailList);

        // 参数校验及参数处理
        AisinoConsoleInvoiceRedUploadDTO redUploadDTO = BeanUtil.copyProperties(redinfo,AisinoConsoleInvoiceRedUploadDTO.class);
        // 填开日期
        redUploadDTO.setDate(redinfo.getBillInputTime());
        // 信息表类型
        redUploadDTO.setBillType("0");
        // TODO-dxk: 2023/2/27 含税、不含税金额  含税标志，这里需要确定
        // 合计金额计算
        redUploadDTO.setAmount(String.valueOf(taxfreeamt));
        // 含税税率标识
        redUploadDTO.setSLBZ("0");
        // 税种类别
        redUploadDTO.setSzlb("1");
        ValidateUtils.validate(redUploadDTO);



        if(redinfo.getRedinfodetailList() == null || redinfo.getRedinfodetailList().size() == 0){
            return new HXResponse("格式校验失败，请上传明细信息！");
        }


        String paramChild = "";
        List<AisinoConsoleInvoiceRedUploadChildDTO> redUploadChildDTO = BeanUtil.copyToList(redinfo.getRedinfodetailList(),AisinoConsoleInvoiceRedUploadChildDTO.class);
        for (AisinoConsoleInvoiceRedUploadChildDTO childDTO : redUploadChildDTO) {

            // TODO-dxk: 2023/2/27 含税、不含税金额
            childDTO.setHS_BZ(childDTO.getHS_BZ().equals("false")? "N":"Y");

            paramChild = "<GoodsMx>" + JSONUtil.toXmlStr(JSONUtil.parse(childDTO)) + " </GoodsMx>";

            ValidateUtils.validate(childDTO);
        }

        // 组装xml报文
        String param = JSONUtil.toXmlStr(JSONUtil.parse(redUploadDTO));

//        param = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n" +
        param = "" +
                "<FPXT>\n" +
                "    <INPUT>\n" +
                "        <RedInvReqBill>" + param;

        param = param + "<RedInvReqBillMx>";

        param = param + paramChild;

        param = param + "            </RedInvReqBillMx>\n" +
                "        </RedInvReqBill>\n" +
                "    </INPUT>\n" +
                "</FPXT>";


        //发起请求
        AjaxResult ajaxResult = null;
        try{
            ajaxResult = AisinoConsoleUtil.sendRequest(AisinoConsoleConstants.RED_UPLOAD, param, companyservice);
        }catch (Exception e){
            log.error("【销项发票】【总部控制台接口】【发票作废】发票请求异常，请求报文{}，销方信息{}","", JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }

        //返回报文解析
        if (ajaxResult.isError()) {
            throw new JianshuiServiceException(ajaxResult.getMsg());
        }

        // todo-k: 返回报文解析这里还带看下具体的返回形式

        cn.hutool.json.JSONObject resultJSON = JSONUtil.parseObj(ajaxResult.get("data"));
        String retcode = resultJSON.get("retcode") != null ? resultJSON.get("retcode").toString() : "";
        String retmsg = resultJSON.get("retmsg") != null ? resultJSON.get("retmsg").toString() : "";


        if (!StringUtils.equals("0000", retcode)) {
            redinfo.setRedInfoStatus("2");
            redinfo.setRedInfoMessage(retmsg);
            redinfoMapper.updateRedinfo(redinfo);
            return new HXResponse(retmsg);
        }

        // TODO-dxk: 2023/2/27 看下 RedInfoStatus 0 1 2代表什么
        redinfo.setRedInfoStatus("1");
        redinfo.setRedInfoMessage(retmsg);
        redinfoMapper.updateRedinfo(redinfo);
        return new HXResponse(retmsg);
    }

    @Override
    public AjaxResult queryRedInfo(Redinfo redinfo, Companyservice companyservice) {
        return null;
    }

    /** 红字信息表下载 */
    @Override
    public HXResponse downloadRedInfo(DownloadRedInfoDTO downloadRedInfoDTO, Companyservice companyservice) {

        // 查找之前的红票
        Redinfo redinfo = new Redinfo();
        redinfo.setRedInfoNo(downloadRedInfoDTO.getBillInfoNo());
        redinfo.setCompanyId(companyservice.getCompanyid());
        QueryWrapper<Redinfo> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getInvoiceLine())) {
            queryWrapper.eq("invoice_type", downloadRedInfoDTO.getInvoiceLine());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBuyerTaxNo())) {
            queryWrapper.eq("buyer_taxnum", downloadRedInfoDTO.getBuyerTaxNo());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getExtensionNumber())) {
            queryWrapper.eq("fjh", downloadRedInfoDTO.getExtensionNumber());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getTerminalNumber())) {
            queryWrapper.eq("terminal_number", downloadRedInfoDTO.getTerminalNumber());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillTimeBegin())) {
            queryWrapper.ge("bill_input_time", downloadRedInfoDTO.getBillTimeBegin());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillTimeEnd())) {
            queryWrapper.le("bill_input_time", downloadRedInfoDTO.getBillTimeEnd());
        }
        if (StringUtils.isNotEmpty(downloadRedInfoDTO.getBillNo())) {
            queryWrapper.le("out_trade_orderno", downloadRedInfoDTO.getBillNo());
        }
        queryWrapper.orderByDesc("id");
        queryWrapper.last(" limit 1 ");
        Redinfo redInfoResult = redinfoMapper.selectOne(queryWrapper);
        if (redInfoResult == null) {
            HXResponse response = new HXResponse("9999", "未查到指定红字信息");
            return response;
        }

        // 组装报文
        AisinoConsoleInvoiceRedDownloadDTO downloadDTO = BeanUtil.copyProperties(redInfoResult,AisinoConsoleInvoiceRedDownloadDTO.class);
        downloadDTO.setYQZT("N");
        downloadDTO.setXXBFW("0");
        downloadDTO.setPAGENO("1");
        downloadDTO.setPAGESIZE("1000");

        String param = JSONUtil.toXmlStr(JSONUtil.parse(downloadDTO));
        param = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n" +
                "<FPXT>\n" +
                "    <INPUT>\n" + param + "</INPUT>\n" +
                "</FPXT>";

        //发起请求
        AjaxResult ajaxResult = null;
        try{
            ajaxResult = AisinoConsoleUtil.sendRequest(AisinoConsoleConstants.RED_DOWLOAD, param, companyservice);
        }catch (Exception e){
            log.error("【销项发票】【总部控制台接口】【发票作废】发票请求异常，请求报文{}，销方信息{}","", JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }

        //返回报文解析
        if (ajaxResult.isError()) {
            throw new JianshuiServiceException(ajaxResult.getMsg());
        }

        cn.hutool.json.JSONObject resultJSON = JSONUtil.parseObj(ajaxResult.get("data"));
        String retcode = resultJSON.get("retcode") != null ? resultJSON.get("retcode").toString() : "";
        String retmsg = resultJSON.get("retmsg") != null ? resultJSON.get("retmsg").toString() : "";

        // todo-k: 下载的返回报文需要单独处理，更新信息表状态？
        // todo-k: 返回的格式看看怎么处理一把，VO都已经创建

        if (!StringUtils.equals("0000", retcode)) {

            return new HXResponse(retmsg);
        }


        return null;
    }



    @Override
    public HXResponse deprecateQueryInvoice(DeprecateQueryInvoiceDTO invoice, Companyservice companyservice) {
        return null;
    }


    /**
     * 打印机查询
     * @param queryPrinterDTO
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse queryPrinter(QueryPrinterDTO queryPrinterDTO, Companyservice companyservice) {
        List<SkDyj> skDyjList = new ArrayList<>();
        try {
            QueryWrapper<SkDyj> skDyjQueryWrapper = new QueryWrapper<>();
            if(StrUtil.isNotEmpty(companyservice.getSellertax())){
                skDyjQueryWrapper.eq("NSRSBH",companyservice.getSellertax());
            }
            if(StrUtil.isNotEmpty(queryPrinterDTO.getPrinterName())){
                skDyjQueryWrapper.eq("MC",queryPrinterDTO.getPrinterName());
            }
            skDyjList = skDyjMapper.selectList(skDyjQueryWrapper);
        } catch (Exception e) {
            log.error("【销项发票】【大象接口】【打印机查询】发票请求异常，请求报文{}，销方信息{}", "", JSONObject.toJSONString(companyservice));
            e.printStackTrace();
            throw new JianshuiServiceException("系统异常！");
        }
        log.info("【销项发票】【大象发票】打印机查询请求结果{}", skDyjList.toString());
        List<SkDyjVO> skDyjVO = BeanUtil.copyToList(skDyjList,SkDyjVO.class);
        return new HXResponse("0000", "操作完成", skDyjList);
    }

    @Override
    public HXResponse pushData(BillInfo billInfo, Companyservice companyservice) {
        return null;
    }

    /**
     * 发票打印
     * @param printDTO
     * @param companyservice
     * @return
     */
    @Override
    public HXResponse batchPrint(PrintDTO printDTO, Companyservice companyservice) {

        if(BeanUtil.isEmpty(printDTO) ||CollectionUtils.isEmpty(printDTO.getDetails())){
            throw new JianshuiParamErrorException(ErrorCode.EMPTY_PARAMS, companyservice, "invoice");
        }

        List<PrintDetailDTO> details = printDTO.getDetails();

        //返回信息处理
        for (PrintDetailDTO detail : details) {
            Map<String,String> result = new HashMap<>();
            //报文组装
            AisinoConsolePrintInvoiceDTO printInvoiceDTO = BeanUtil.copyProperties(detail,AisinoConsolePrintInvoiceDTO.class);

            if(!detail.getFpqh().equals(detail.getFpzh())){
                result.put("9999","发票打印失败，发票号码="+printInvoiceDTO.getInfoNumber()+"，发票代码="+printInvoiceDTO.getInfoTypeCode()+"，原因=发票号码传参错误");
                continue;
            }
            //发票类型
            Integer invoceTypeTemp = CovertInvoiceType(detail.getInvoiceType());
            if (invoceTypeTemp == -1) {
                result.put("9999","发票打印失败，发票号码="+printInvoiceDTO.getInfoNumber()+"，发票代码="+printInvoiceDTO.getInfoTypeCode()+"，原因=发票类型未匹配");
                continue;
            }
            printInvoiceDTO.setInfoKind(invoceTypeTemp);

            //必填参数校验
            ValidateUtils.validate(printInvoiceDTO,companyservice,null);

            printInvoiceDTO.setPrintKind(0);
            printInvoiceDTO.setShowPrintDlg(0);

            //发起请求
            AjaxResult ajaxResult = null;
            try {
                Map<String,Object> map = BeanToMapUtils.fastJsonBean2Map(printInvoiceDTO);
                ajaxResult = AisinoConsoleUtil.sendRequest(AisinoConsoleConstants.INVOICE_PRINT, JSONUtil.parse(map), companyservice);
            } catch (Exception e) {
                log.error("【销项发票】【总部控制台接口】【发票打印】发票请求异常，请求报文{}，销方信息{}", JSONUtil.parse(printInvoiceDTO).toString(), JSONObject.toJSONString(companyservice));
                result.put("9999","发票打印失败，发票号码="+printInvoiceDTO.getInfoNumber()+"，发票代码="+printInvoiceDTO.getInfoTypeCode()+"，原因=系统原因");
            }

            //返回报文解析
            if (ajaxResult.isError()) {
                result.put("9999","发票打印失败，发票号码="+printInvoiceDTO.getInfoNumber()+"，发票代码="+printInvoiceDTO.getInfoTypeCode()+"，原因="+ajaxResult.getMsg());;
            }

            cn.hutool.json.JSONObject resultJSON = JSONUtil.parseObj(ajaxResult.get("data"));
            String retcode = resultJSON.get("retcode") != null ? resultJSON.get("retcode").toString() : "";
            String retmsg = resultJSON.get("retmsg") != null ? resultJSON.get("retmsg").toString() : "";
            if("5011".equals(retcode)){
                return new HXResponse("发票打印成功，发票号码="+printInvoiceDTO.getInfoNumber()+"，发票代码="+printInvoiceDTO.getInfoTypeCode());
            }else{
                return new HXResponse("发票打印失败，发票号码="+printInvoiceDTO.getInfoNumber()+"，发票代码="+printInvoiceDTO.getInfoTypeCode()+"，原因="+retmsg);
            }
        }

        return new HXResponse("0000", "操作完成");


    }

    @Override
    public AjaxResult syncStockInfo(Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse signInvoice(SignESealDTO signESealDTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse createESeal(CreateESealDTO createESealDTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse registerESeal(RegisterESealDTO createESealDTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public AjaxResult SummaryReport(SummaryReportQueryDTO summaryReportQueryDTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public Object callback(HttpServletRequest request) {
        return null;
    }


    /**
     * 简税转换总部控制台发票类型
     *
     * @param invoiceType
     * @return java.lang.Integer
     * @author dxk
     * @date 2022/6/28 20:17
     */
    public static Integer CovertInvoiceType(String invoiceType) {

        /**
         * 发票种类 invoice_type（ p电子增值税普通发票 c增值税普通发票 s 增值税专用发票 e 收购发票 f 收购发票 r增值税普通发票）
         */
        if (StrUtil.isEmpty(invoiceType)) {
            return -1;
        }
        if ("p".equals(invoiceType) || "c".equals(invoiceType) || "e".equals(invoiceType) || "f".equals(invoiceType) || "r".equals(invoiceType)) {
            return 2;
        } else if ("s".equals(invoiceType)) {
            return 0;
        }

        return -1;
    }

    /**
     * 总部控制台转简税发票类型
     * @author dxk
     * @date 2022/6/29 17:12
     * @param invoiceType
     * @return java.lang.String
     */
    public static String CovertInvoiceTypeReverse(String invoiceType){

        if(invoiceType.equals("2")){
            return "p";
        }else if(invoiceType.equals("0")){
            return "s";
        }
        return "";
    }


    @Override
    public Object addCallback(HttpServletRequest request) {
        return null;
    }

    @Override
    public Object decryptCallback(HttpServletRequest request) {
        return null;
    }

    @Override
    public HXResponse getFileUrl(InvoiceAllFileAcquisitionTWODTO invoiceAllFileAcquisitionTWODTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse getFileAcquisitionOn(InvoiceAllFileAcquisitionOnTWODTO invoiceAllFileAcquisitionOnTWODTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse qrcode(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse query(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse getPrintXML(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse issueFastRedInvoice(InvoiceAllKshcTWODTO invoiceAllKshcDTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse invoiceStatic(JSONObject decryptResult, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse auditRedInfo(InvoiceAllShhzTWODTO invoiceAllShhzTWODTO, Companyservice companyservice) {
        return null;
    }

    @Override
    public HXResponse queryRedInfoDetail(InvoiceAllRedInvoiceDetailTWODTO invoiceAllRedInvoiceDetailDTO, Companyservice companyservice) {
        return null;
    }


}
