package com.dxhy.common.utils;

import cn.hutool.core.date.DateUtil;
import com.dxhy.api.model.invoice.InvoiceDetailInfo;
import com.dxhy.api.model.invoice.TDxRecordInvoice;
import com.dxhy.api.model.tdys.*;
import com.dxhy.api.model.tdys.dqyRespDto.*;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.util.AmountFormatUtil;
import com.dxhy.common.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author Allen
 * @version 1.0.0
 * @ClassName CommonUtil.java
 * @Description TODO
 * @createTime 2022年11月24日 15:34:00
 */
@Slf4j
public class CommonUtil {

    /**
     * yyyy-MM-dd HH:mm:ss
     */
    private static final String timeRegex = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";

    /**
     * yyyy-MM-dd
     */
    private static final String timeRegex1 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
            "((0[48]|[2468][048]|[3579][26])00))-02-29)$";

    /**
     * yyyy/MM/dd
     */
    private static final String timeRegex2 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\/(((0[13578]|1[02])\\/(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)\\/(0[1-9]|[12][0-9]|30))|(02\\/(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
            "((0[48]|[2468][048]|[3579][26])00))\\/02\\/29)$";

    /**
     * yyyy/MM/dd HH:mm:ss
     */
    private static final String timeRegex3 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})\\/(((0[13578]|1[02])\\/(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)\\/(0[1-9]|[12][0-9]|30))|(02\\/(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
            "((0[48]|[2468][048]|[3579][26])00))\\/02\\/29))\\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";

    /**
     * yyyyMMdd
     */
    private static final String timeRegex4 = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
            "((0[48]|[2468][048]|[3579][26])00))0229)$";

    /**
     * yyyyMMddHHmmss
     */
    private static final String timeRegex5 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229))" +
            "([0-1][0-9]|2[0-3])([0-5][0-9])([0-5][0-9])$";

    /**
     * yyyyMMddHHmmssSSS
     */
    private static final String timeRegex6 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
            "((0[48]|[2468][048]|[3579][26])00))0229))([0-1][0-9]|2[0-3])([0-5][0-9])([0-5][0-9])([0-9]{3})$";

    /**
     * yyyyMMdd HH:mm:ss
     */
    private static final String timeRegex7 = "((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|" +
            "((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|" +
            "((0[48]|[2468][048]|[3579][26])00))0229))\\s([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";

    /**
     * 文件名中间分隔符
     */
    private static final String fileSplit = "_";

    /**
     * 文件名后缀
     */
    private static final String fileNameSurfix = ".xml";

    private static final String fileNameSurfixPdf = ".pdf";

    private static final String fileNameSurfixOfd = ".ofd";


    /**
     * 日期转换
     * @param date
     * @return
     */
    /**
     * 日期转换
     *
     * @param date
     * @return
     */
    public static Date dateConvert(String date) {
        String format = "yyyy-MM-dd HH:mm:ss";
        try {
            if (StringUtils.isNotBlank(date)) {
                if (Pattern.matches(timeRegex, date)) {
                    format = "yyyy-MM-dd HH:mm:ss";
                } else if (Pattern.matches(timeRegex1, date)) {
                    format = "yyyy-MM-dd";
                } else if (Pattern.matches(timeRegex2, date)) {
                    format = "yyyy/MM/dd";
                } else if (Pattern.matches(timeRegex3, date)) {
                    format = "yyyy/MM/dd HH:mm:ss";
                } else if (Pattern.matches(timeRegex4, date)) {
                    format = "yyyyMMdd";
                } else if (Pattern.matches(timeRegex5, date)) {
                    format = "yyyyMMddHHmmss";
                } else if (Pattern.matches(timeRegex6, date)) {
                    format = "yyyyMMddHHmmssSSS";
                } else if (Pattern.matches(timeRegex7, date)) {
                    format = "yyyyMMdd HH:mm:ss";
                }
                return new SimpleDateFormat(format).parse(date);
            }
        } catch (ParseException e) {
            log.error("日期{}转换异常：{}", date, e);
            log.info("业务处理异常：{}", e);
        }
        return null;
    }


    /**
     * @Description 验证是否为数字
     * @Author wangruwei
     * @Date 2023/3/3 10:38
     **/
    public static boolean checkStrNum(String value) {
        String str = String.valueOf(value);
        String regex = "^(-?[0-9]\\d*\\.?\\d*)|(-?0\\.\\d*[1-9])|(-?[0])|(-?[0]\\.\\d*)$";
        return str.matches(regex);
    }

    /**
     * String转list
     *
     * @param pzxz
     * @return
     */
    public static List<String> StringToList(String pzxz) {
        if (StringUtils.isNotBlank(pzxz)) {
            String[] split = pzxz.split(",");
            List<String> list = new ArrayList<>(split.length);
            Collections.addAll(list, split);
            return list;
        } else {
            return new ArrayList<String>();
        }
    }

    public static String getFtpFilePath(String pathPrefix, String gmfsbh, String ftpFileName) {
        String[] toDay = DateUtil.today().split("-");
        return pathPrefix + "/sdxml/" + gmfsbh + "/" + toDay[0] + "/" + toDay[1] + "/" + toDay[2] + "/" + ftpFileName;
    }

    public static String getTempFilePath(String localPathDefault, String fileName) {
        // 本地文件存储路径
        StringBuilder tempFile = new StringBuilder();
        tempFile.append(localPathDefault);
        tempFile.append(fileName);
        return tempFile.toString();
    }

    public static String getFileName(String uuid) {
        //文件名
        StringBuilder ftpFileName = new StringBuilder();
        ftpFileName.append(uuid);
        //ftpFileName.append(fileSplit);
        //ftpFileName.append((new Date()).getTime());
        ftpFileName.append(fileNameSurfix);
        return ftpFileName.toString();
    }

    public static String getFileNamePdf(String uuid) {
        //文件名
        StringBuilder ftpFileName = new StringBuilder();
        ftpFileName.append(uuid);
        //ftpFileName.append(fileSplit);
        //ftpFileName.append((new Date()).getTime());
        ftpFileName.append(fileNameSurfixPdf);
        return ftpFileName.toString();
    }

    public static String getFileNameOfd(String uuid) {
        //文件名
        StringBuilder ftpFileName = new StringBuilder();
        ftpFileName.append(uuid);
        //ftpFileName.append(fileSplit);
        //ftpFileName.append((new Date()).getTime());
        ftpFileName.append(fileNameSurfixOfd);
        return ftpFileName.toString();
    }

    /**
     * @description list分页
     * @author Allen
     * @date 2023/10/19 16:27
     */
    public static List listLimit(List data, int pageSize, int pageNo) {
        int startIndex = pageSize * (pageNo - 1);
        int endIndex = pageSize * pageNo;
        if (endIndex > data.size()) {
            endIndex = data.size();
        }
        return data.subList(startIndex, endIndex);
    }

    public static String jecl(Object je) {
        if (ObjectUtils.isNotEmpty(je)) {
            if (je instanceof BigDecimal) {
                BigDecimal decimalJe = (BigDecimal) je;
                return AmountFormatUtil.fmtMicrometer2(decimalJe.toString());
            } else if (je instanceof String) {
                return AmountFormatUtil.fmtMicrometer2((String) je);
            }
        }
        return "";
    }


    public static String jeclNullToHyphen(Object je) {
        if (ObjectUtils.isNotEmpty(je)) {
            if (je instanceof BigDecimal) {
                BigDecimal decimalJe = (BigDecimal) je;
                return AmountFormatUtil.fmtMicrometer2(decimalJe.toString());
            } else if (je instanceof String) {
                return AmountFormatUtil.fmtMicrometer2((String) je);
            }
        }
        return "--";
    }

    /**
     * @param invoiceStatus 发票状态 0-正常  1-失控 2-作废  3-红冲 4-异常 7部分冲红 8全额红冲 80-红字发票待确认
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     */
    public static String fpztzhz(String invoiceStatus) {
        String fpztmc = "";
        if (StringUtils.isBlank(invoiceStatus)) {
            return fpztmc;
        }
        switch (invoiceStatus) {
            case "0":
                fpztmc = "正常";
                break;
            case "1":
                fpztmc = "失控";
                break;
            case "2":
                fpztmc = "作废";
                break;
            case "3":
                fpztmc = "红冲";
                break;
            case "4":
                fpztmc = "异常";
                break;
            case "7":
                fpztmc = "部分冲红";
                break;
            case "8":
                fpztmc = "全额红冲";
                break;
            case "80":
                fpztmc = "红字发票待确认";
                break;
            default:
                fpztmc = null;
                break;
        }
        return fpztmc;
    }

    /**
     * @param glzt 管理状态  0正常1异常 2疑似非正常
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     */
    public static String glztzhz(String glzt) {
        String glztmc = "";
        if (StringUtils.isBlank(glzt)) {
            return glztmc;
        }
        switch (glzt) {
            case "0":
                glztmc = "正常";
                break;
            case "1":
                glztmc = "异常";
                break;
            case "2":
                glztmc = "疑似非正常";
                break;
            default:
                glztmc = null;
                break;
        }
        return glztmc;
    }

    /**
     * @param rzlx 认证类型1-抵扣 2-退税 3-代办退税 4-不抵扣
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     */
    public static String rzlxzhz(String rzlx) {
        String rzlxmc = "";
        if (StringUtils.isBlank(rzlx)) {
            return rzlxmc;
        }
        switch (rzlx) {
            case "1":
                rzlx = "抵扣";
                break;
            case "2":
                rzlx = "退税";
                break;
            case "3":
                rzlx = "代办退税";
                break;
            case "4":
                rzlx = "不抵扣";
                break;
            default:
                rzlx = null;
                break;
        }
        return rzlx;
    }


    /**
     * @param cpyycbs 9：正常
     *                1：成品油单价异
     *                常
     *                2：成品油超库存
     *                异常
     *                8：正常，需全额
     *                红冲
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     */
    public static String cpyycbszhz(String cpyycbs) {
        String cpyycbsmc = "";
        if (StringUtils.isBlank(cpyycbs)) {
            return cpyycbsmc;
        }
        switch (cpyycbs) {
            case "9":
                cpyycbsmc = "正常";
                break;
            case "1":
                cpyycbsmc = "成品油单价异常";
                break;
            case "2":
                cpyycbsmc = "成品油库存异常";
                break;
            case "8":
                cpyycbsmc = "正常，需全额冲红";
                break;
            default:
                cpyycbsmc = null;
                break;
        }
        return cpyycbsmc;
    }

    /**
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     * 01：增值税专用
     * 发票可用于代办
     * 退税标签（仅用
     * 于代办退税）
     */
    public static String cktsldmzhz(String cktsldm) {
        String cktsldmmc = "";
        if (StringUtils.isBlank(cktsldm)) {
            return cktsldmmc;
        }
        switch (cktsldm) {
            case "01":
                cktsldmmc = "增值税专用发票可用于代办退税标签（仅用于代办退税）";
                break;
            default:
                cktsldmmc = null;
                break;
        }
        return cktsldmmc;
    }


    /**
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     * 0：未使用
     * 1：全部项目加计
     * 2：全部项目不加
     * 计
     * 3：部分项目加计
     */
    public static String zzsyhytzhz(String zzsyhyt) {
        String zzsyhytmc = "";
        if (StringUtils.isBlank(zzsyhyt)) {
            return zzsyhytmc;
        }
        switch (zzsyhyt) {
            case "0":
                zzsyhytmc = "未使用";
                break;
            case "1":
                zzsyhytmc = "全部项目加计";
                break;
            case "2":
                zzsyhytmc = "全部项目不加计";
                break;
            case "3":
                zzsyhytmc = "部分项目加计";
                break;
            default:
                zzsyhytmc = null;
                break;
        }
        return zzsyhytmc;
    }


    /**
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     * 00：未勾选库存
     * 01：已勾选库存
     */
    public static String xfsytzhz(String xfsyt) {
        String xfsytmc = "";
        if (StringUtils.isBlank(xfsyt)) {
            return xfsytmc;
        }
        switch (xfsyt) {
            case "00":
                xfsytmc = "未勾选库存";
                break;
            case "01":
                xfsytmc = "已勾选库存";
                break;
            default:
                xfsytmc = null;
                break;
        }
        return xfsytmc;
    }

    /**
     * @description
     * @author Allen
     * @date 2024/5/14 16:24
     * 0：无风险
     * 1：低风险
     * 2：中风险
     * 3：高风险
     */
    public static String jdcycbszhz(String jdcycbs) {
        String jdcycbsmc = "";
        if (StringUtils.isBlank(jdcycbs)) {
            return jdcycbsmc;
        }
        switch (jdcycbs) {
            case "0":
                jdcycbsmc = "无风险";
                break;
            case "1":
                jdcycbsmc = "低风险";
                break;
            case "2":
                jdcycbsmc = "中风险";
                break;
            case "3":
                jdcycbsmc = "高风险";
                break;
            default:
                jdcycbsmc = null;
                break;
        }
        return jdcycbsmc;
    }

    public static boolean isSdfp(String invoiceType) {

        if (FplxEnum.QDPP.getFplxDm().equals(invoiceType)
                || FplxEnum.QDZZP.getFplxDm().equals(invoiceType)
                || FplxEnum.SDFP_JDCTYXSFP.getFplxDm().equals(invoiceType)
                || FplxEnum.ESCDZ.getFplxDm().equals(invoiceType)
                || FplxEnum.ZZDZ.getFplxDm().equals(invoiceType)
                || FplxEnum.ZZPP.getFplxDm().equals(invoiceType)
                || FplxEnum.ZZJDC.getFplxDm().equals(invoiceType)
                || FplxEnum.ZZESC.getFplxDm().equals(invoiceType)
                || FplxEnum.HKDZFP.getFplxDm().equals(invoiceType)
                || FplxEnum.TLKP.getFplxDm().equals(invoiceType)
        ) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return
     * @description 增加xmlflag类型
     * @author Allen
     * @date 2024/5/20 16:07
     */
    public static String addXmlFlag(String xmlFlag, String flag) {
        if (xmlFlag.contains(flag)) {
            return xmlFlag;
        } else {
            List<String> list = new LinkedList(Arrays.asList(xmlFlag.split("")));
            list.add(flag);
            List<String> collect = list.stream().sorted().collect(Collectors.toList());
            return String.join("", collect).replace("0", "");
        }
    }

    /**
     * @return
     * @description 删除xmlflag类型
     * @author Allen
     * @date 2024/5/20 16:07
     */
    public static String removeXmlFlag(String xmlFlag, String flag) {
        if (!xmlFlag.contains(flag)) {
            return xmlFlag;
        } else {
            return xmlFlag.replace(flag, "");
        }
    }

    /**
     * @param recordInvoice 组装的 底账信息
     * @param detailList    组装的 明细信息
     * @Description 转化大企业返回的特定要素为统一结构
     * @Return java.util.Map<java.lang.String       ,       java.lang.String>
     * @Author wangruwei
     * @Date 2024/6/3 11:29
     **/
    public static TdysZxxMxDto formatTdysJxtyJsonByDqy(TDxRecordInvoice recordInvoice, List<InvoiceDetailInfo> detailList) {
        String tdysDm = recordInvoice.getLqTdyslxDm();
        String tdysZxx = CollectionUtils.isEmpty(recordInvoice.getInvoiceExt()) ? "" : JsonUtils.getInstance().toJsonString(recordInvoice.getInvoiceExt());
        String tdysMxList = CollectionUtils.isEmpty(recordInvoice.getDetailExt()) ? "" : JsonUtils.getInstance().toJsonString(recordInvoice.getDetailExt());
        TdysZxxMxDto result = new TdysZxxMxDto();
        if ("03".equals(tdysDm)) {
            //建筑服务发票时返回
            if (StringUtils.isNotBlank(tdysZxx)) {
                DqyTdysJzfw dqyTdysJzfw = JsonUtils.getInstance().parseObject(tdysZxx, DqyTdysJzfw.class);
                TdysJzfwtdys tdysJzfwtdys = new TdysJzfwtdys();
                tdysJzfwtdys.setTdzzsxmbh(dqyTdysJzfw.getTaxProjectNumber());
                tdysJzfwtdys.setKdsbz(dqyTdysJzfw.getCrossCityType());
                result.setZxx(JsonUtils.getInstance().toJsonString(tdysJzfwtdys));
            }
            if (StringUtils.isNotBlank(tdysMxList)) {
                List<DqyTdysJzfwItem> dqyTdysJzfwItems = JsonUtils.getInstance().jsonToList(tdysMxList, DqyTdysJzfwItem.class);
                if (!CollectionUtils.isEmpty(dqyTdysJzfwItems)) {
                    List<TdysJzfwtdysItem> list = new LinkedList();
                    //获取明细里的数据复制，一一对应
                    for (int i = 0; i < dqyTdysJzfwItems.size(); i++) {
                        TdysJzfwtdysItem item = new TdysJzfwtdysItem();
                        item.setXh((i + 1) + "");
                        item.setJzfwfsd(dqyTdysJzfwItems.get(i).getBuildServiceLocation());
                        item.setJzxmmc(dqyTdysJzfwItems.get(i).getBuildProjectName());
                        item.setXmmc(detailList.get(i).getGoodsName());
                        item.setJe(detailList.get(i).getDetailAmount());
                        item.setSl1(CommonUtil.processTaxRate(detailList.get(i).getTaxRate()));
                        item.setSe(detailList.get(i).getTaxAmount());

                        list.add(item);
                    }
                    result.setMx(JsonUtils.getInstance().toJsonString(list));
                }
            }
        } else if ("04".equals(tdysDm)) {
            //货物运输服务发票时返回-只有明细
            if (StringUtils.isNotBlank(tdysMxList)) {
                List<DqyTdysHwysfw> respItems = JsonUtils.getInstance().jsonToList(tdysMxList, DqyTdysHwysfw.class);
                if (!CollectionUtils.isEmpty(respItems)) {
                    List<TdysHwysfwtdysItem> list = new LinkedList();
                    for (int i = 0; i < respItems.size(); i++) {
                        //统一item
                        TdysHwysfwtdysItem tyItem = new TdysHwysfwtdysItem();
                        tyItem.setXh((i + 1) + "");
                        tyItem.setYsgjzl(respItems.get(i).getVehicleType());
                        tyItem.setYsgjph(respItems.get(i).getLicensePlate());
                        tyItem.setQyd(respItems.get(i).getDepartureStation());
                        tyItem.setDdd(respItems.get(i).getDestination());
                        tyItem.setYshwmc(respItems.get(i).getCargoName());

                        list.add(tyItem);
                    }
                    result.setMx(JsonUtils.getInstance().toJsonString(list));
                }
            }
        } else if ("05".equals(tdysDm) || "06".equals(tdysDm)) {
            // 不动产销售服务发票、不动产经营租赁服务（电子税局特定要素类型-05、06
            if ("05".equals(tdysDm)) {
                //不动产销售服务发票
                if (StringUtils.isNotBlank(tdysMxList)) {
                    //组建大企业返回实体
                    DqyTdysBdcXsFw dqyZxxDto = new DqyTdysBdcXsFw();
                    if (StringUtils.isNotBlank(tdysZxx)) {
                        dqyZxxDto = JsonUtils.getInstance().parseObject(tdysZxx, DqyTdysBdcXsFw.class);
                    }
                    //大企业返回明细
                    List<DqyTdysBdcXsFwItem> dqyRespItems = JsonUtils.getInstance().jsonToList(tdysMxList, DqyTdysBdcXsFwItem.class);
                    //设定统一实体
                    List<TdysBdcxsfwtdysItem> list = new LinkedList();
                    for (int i = 0; i < dqyRespItems.size(); i++) {
                        TdysBdcxsfwtdysItem tyItem = new TdysBdcxsfwtdysItem();
                        tyItem.setXh((i + 1) + "");
                        tyItem.setCqzsbh(dqyRespItems.get(i).getPropertyNumber());
                        tyItem.setBdcdwdm(dqyZxxDto.getRealEstateUnitCode());
                        tyItem.setWqhtbabh(dqyZxxDto.getContractRecordId());
                        tyItem.setBdczldz(dqyZxxDto.getRealEstateAddress());
                        tyItem.setKdsbz(dqyZxxDto.getCrossCityType());
                        tyItem.setTdzzsxmbh(dqyZxxDto.getTaxProjectNumber());
                        tyItem.setHdjsjg(dqyZxxDto.getApprovedTaxPrice());
                        tyItem.setSjcjhsje(dqyZxxDto.getActualTransactionTaxAmount());

                        list.add(tyItem);
                    }
                    result.setMx(JsonUtils.getInstance().toJsonString(list));
                }
            }
            if ("06".equals(tdysDm)) {
                //不动产经营租赁服务
                //组建大企业返回实体
//                DqyTdysBdcXsFw dqyZxxDto = new DqyTdysBdcXsFw();
//                if (StringUtils.isNotBlank(tdysZxx)) {
//                    dqyZxxDto = JsonUtils.getInstance().parseObject(tdysZxx, DqyTdysBdcXsFw.class);
//                }
                //大企业返回明细
                if (StringUtils.isNotBlank(tdysMxList)) {
                    List<DqyTdysBdcXsFwItem> dqyRespItems = JsonUtils.getInstance().jsonToList(tdysMxList, DqyTdysBdcXsFwItem.class);
                    //设定统一实体
                    List<TdysBdcjyzltdysItem> list = new LinkedList();
                    for (int i = 0; i < dqyRespItems.size(); i++) {
                        TdysBdcjyzltdysItem tyItem = new TdysBdcjyzltdysItem();
                        tyItem.setXh((i + 1) + "");
                        tyItem.setCqzsbh(dqyRespItems.get(i).getPropertyNumber());
                        tyItem.setBdczldz(dqyRespItems.get(i).getRealEstateAddress());
                        tyItem.setZlqq(dqyRespItems.get(i).getLeasePeriodStart());
                        tyItem.setZlqz(dqyRespItems.get(i).getLeasePeriodEnd());
                        tyItem.setKdsbz(dqyRespItems.get(i).getCrossCityType());

                        list.add(tyItem);
                    }

                    result.setMx(JsonUtils.getInstance().toJsonString(list));
                }

            }
        } else if ("07".equals(tdysDm)) {
            //代收车船税（电子税局特定要素类型-07）
            //只有主信息
            if (StringUtils.isNotBlank(tdysZxx)) {
                DqyTdysDsccs dqyZxxDto = JsonUtils.getInstance().parseObject(tdysZxx, DqyTdysDsccs.class);

                //设定统一实体
                TdysDsccstdys tyZxx = new TdysDsccstdys();
                tyZxx.setBxdh(dqyZxxDto.getPolicyNo());
                tyZxx.setCphcbdjh(dqyZxxDto.getShipNumber());
                tyZxx.setSkssq(dqyZxxDto.getTaxPeriod());
                tyZxx.setCjh(dqyZxxDto.getVehicleNo());
                tyZxx.setDsccsje(dqyZxxDto.getShipTaxAmount());
                tyZxx.setZnj(dqyZxxDto.getLateFeeAmount());
                tyZxx.setJehj(dqyZxxDto.getTotalAmount());

                result.setZxx(JsonUtils.getInstance().toJsonString(tyZxx));
            }
        } else if ("09".equals(tdysDm)) {
            //旅客运输服务发票（电子税局特定要素类型-09）
            //只有明细
            if (StringUtils.isNotBlank(tdysMxList)) {
                List<DqyTdysLkysfw> respItems = JsonUtils.getInstance().jsonToList(tdysMxList, DqyTdysLkysfw.class);
                if (!CollectionUtils.isEmpty(respItems)) {
                    List<TdysLkysfwtdysItem> list = new LinkedList();
                    for (int i = 0; i < respItems.size(); i++) {
                        //统一item
                        TdysLkysfwtdysItem tyItem = new TdysLkysfwtdysItem();
                        tyItem.setXh((i + 1) + "");
                        tyItem.setCxr(respItems.get(i).getFullName());
                        tyItem.setCxrzjlxDm(respItems.get(i).getCertificateType());
                        tyItem.setSfzjhm(respItems.get(i).getCertificateNo());
                        tyItem.setChuxrq(respItems.get(i).getDepartureTime());
                        tyItem.setCfd(respItems.get(i).getDepartureStation());
                        tyItem.setDdd(respItems.get(i).getDestination());
                        tyItem.setZwdj(respItems.get(i).getGrade());
                        tyItem.setJtgjlxDm(respItems.get(i).getVehicleType());

                        list.add(tyItem);
                    }
                    result.setMx(JsonUtils.getInstance().toJsonString(list));
                }
            }
        } else if ("10".equals(tdysDm) || "11".equals(tdysDm)) {
            //医疗服务(住院)发票、医疗服务(门诊)发票（电子税局特定要素类型-10、11）
            if ("10".equals(tdysDm)) {
                //特定要素类型代码为10：医疗服务（住院）发票时返回
                if (StringUtils.isNotBlank(tdysZxx)) {
                    DqyTdysZyFp dqyZxxDto = JsonUtils.getInstance().parseObject(tdysZxx, DqyTdysZyFp.class);

                    //设定统一实体
                    TdysYlfwzytdys tyZxx = new TdysYlfwzytdys();
                    //tyZxx.setYlywlsh();
                    //tyZxx.setHzxm();
                    //tyZxx.setHzsfzjlxDm();
                    //tyZxx.setHzsfzjhm();
                    //tyZxx.setBlh();
                    //tyZxx.setZyh();
                    //tyZxx.setZykb();
                    //tyZxx.setZysjq();
                    //tyZxx.setZysjz();
                    //tyZxx.setYlyjje();
                    //tyZxx.setYlbjje();
                    //tyZxx.setYltfje();
                    //tyZxx.setYljglxDm();
                    //tyZxx.setQtyljglx();
                    //tyZxx.setYblxDm();
                    //tyZxx.setQtyblx();
                    tyZxx.setYbbh(dqyZxxDto.getInsuranceCardNumber());
                    //tyZxx.setXbDm();
                    tyZxx.setYbtcjjzfje(dqyZxxDto.getBasicMedicalPayment());
                    //tyZxx.setQtzfje();
                    tyZxx.setGrzhzfje(dqyZxxDto.getInsuranceAccountPayment());
                    tyZxx.setGrxjzfje(dqyZxxDto.getCashPayment());
                    tyZxx.setGrzfje(dqyZxxDto.getPersonalPayment());
                    //tyZxx.setGrzfje1();
                    //tyZxx.setJkr();
                    //tyZxx.setSkdw();
                    //tyZxx.setSszdyyssl();
                    //tyZxx.setSszdyysjson();

                    result.setZxx(JsonUtils.getInstance().toJsonString(tyZxx));
                }
                if (StringUtils.isNotBlank(tdysMxList)) {
                    log.info("大企业特定要素:{}的特定要素明细字段对应不上，不做处理也不存", tdysDm);
                }
            }
            if ("11".equals(tdysDm)) {
                //特定要素类型代码为11：医疗服务（门诊）发票时返回
                if (StringUtils.isNotBlank(tdysZxx)) {
                    DqyTdysZyFp dqyZxxDto = JsonUtils.getInstance().parseObject(tdysZxx, DqyTdysZyFp.class);

                    //设定统一实体
                    TdysYlfwmztdys tyZxx = new TdysYlfwmztdys();
                    //tyZxx.setYlywlsh();
                    //tyZxx.setHzxm();
                    //tyZxx.setHzsfzjlxDm();
                    //tyZxx.setHzsfzjhm();
                    //tyZxx.setMzh();
                    //tyZxx.setMzjzsj();
                    //tyZxx.setYljglxDm();
                    //tyZxx.setQtyljglx();
                    //tyZxx.setYblxDm();
                    //tyZxx.setQtyblx();
                    tyZxx.setYbbh(dqyZxxDto.getInsuranceCardNumber());
                    //tyZxx.setXbDm();
                    tyZxx.setYbtcjjzfje(dqyZxxDto.getBasicMedicalPayment());
                    //tyZxx.setQtzfje();
                    tyZxx.setGrzhzfje(dqyZxxDto.getInsuranceAccountPayment());
                    tyZxx.setGrxjzfje(dqyZxxDto.getCashPayment());
                    tyZxx.setGrzfje(dqyZxxDto.getPersonalPayment());
                    //tyZxx.setGrzfje1();
                    //tyZxx.setSszdyyssl();
                    //tyZxx.setSszdyysjson();

                    result.setZxx(JsonUtils.getInstance().toJsonString(tyZxx));
                }
                if (StringUtils.isNotBlank(tdysMxList)) {
                    log.info("大企业特定要素:{}的特定要素明细字段对应不上，不做处理也不存", tdysDm);
                }
            }
        } else {
            log.info("大企业尚未提供此特定要素报文，直接存对应json");
            result.setZxx(tdysZxx);
            result.setMx(tdysMxList);
        }
        return result;
    }

    /**
     * @Description 拼接所有字符串，是空的换成""
     * @Author wangruwei
     * @Date 2024/6/27 16:21
     **/
    public static String appendAll(String... params) {
        int length = params.length;
        String allStr = "";
        for (int i = 0; i < length; i++) {
            if (ObjectUtils.isEmpty(params[i])) {
                continue;
            }
            allStr += params[i].toString();
        }
        return allStr;
    }

    /**
     * @return 返回小数格式的税率，例如0.13、0.06、0.015、0.00
     * @description 税率格式化
     * @author Allen
     * @date 2024/7/1 14:09
     * @param    taxRateStr 需要格式化的税率，例如13、0.13、0.06、6%、0.015、1.5%、0.00
     */
    public static String processTaxRate(String taxRateStr) {
        try {
            if (StringUtils.isNotBlank(taxRateStr)) {
                // 移除字符串中的所有非数字以及“.”的字符
                String normalizedRate = taxRateStr.replaceAll("[^\\d.]", "");
                if (StringUtils.isNotBlank(normalizedRate)) {
                    // 如果原字符串包含“%”，或者normalizedRate只包含整数或大于1.00，则除以100，保留三位小数四舍五入
                    if (taxRateStr.contains("%") || normalizedRate.matches("\\d+") || Double.valueOf(normalizedRate) > 1.00) {
                        BigDecimal bigDecimal = new BigDecimal(normalizedRate);
                        normalizedRate = String.valueOf(bigDecimal.divide(new BigDecimal(100)).setScale(3, BigDecimal.ROUND_HALF_UP).toString());
                    }
                    //保留两位小数，小数位不足补0
                    DecimalFormat decimalFormat = new DecimalFormat("0.00#");
                    return decimalFormat.format(Double.valueOf(normalizedRate));
                }
            }
        } catch (Exception e) {
            log.info("税率格式化异常,传入的税率：{}，异常信息：{}", taxRateStr, e);
        }
        return taxRateStr;
    }
    /**
    * @Description 获取正确格式代码号码
    * @param invoiceCode
    * @param invoiceNo
    * @Return java.lang.String
    * @Author wangruwei
    * @Date 2024/10/16 16:51
    **/
    public static String getUuid(String invoiceCode, String invoiceNo) {
        return (StringUtils.isEmpty(invoiceCode)?"":invoiceCode) + invoiceNo;
    }

    /**
    * @Description 大企业的铁路客票 退/售 转换
     * 大企业返回  1：售 2：退
     * 转换为对应  0：售 1：退
    * @param businessType
    * @Return java.lang.String
    * @Author wangruwei
    * @Date 2024/12/31 9:18
    **/
    public static String changeTlkpYwlx(String businessType){
        String tlkpYwlx ;
        switch (businessType) {
            case "1":
                tlkpYwlx = "0";
                break;
            case "2":
                tlkpYwlx = "1";
                break;
            default:
                tlkpYwlx = businessType;
                break;
        }
        return tlkpYwlx;
    }

    public static void main(String[] args) {
        System.out.println(processTaxRate(""));
        System.out.println(processTaxRate("1"));
        System.out.println(processTaxRate(null));
        System.out.println(processTaxRate(null).length());
    }
}
