package com.brilliance.isc.common.component;

import com.brilliance.isc.bo.*;
import com.brilliance.isc.common.cache.adr.AdrCacheService;
import com.brilliance.isc.common.cache.pta.PtaCacheService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.setmod.vo.PtsFeeDetailVo;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.constant.PartyNames;
import com.brilliance.isc.mda.dao.PtsMapper;
import com.brilliance.isc.mda.dao.PtsptaMapper;
import com.brilliance.isc.vo.collection.BcdBizInfoVo;
import com.brilliance.isc.vo.collection.BodBizInfoVo;
import com.brilliance.isc.vo.collection.CcdBizInfoVo;
import com.brilliance.isc.vo.derivative.JsdBizInfoVo;
import com.brilliance.isc.vo.domlc.BddBizInfoVo;
import com.brilliance.isc.vo.domlc.BfdBizInfoVo;
import com.brilliance.isc.vo.domlc.DedBizInfoVo;
import com.brilliance.isc.vo.domlc.DidBizInfoVo;
import com.brilliance.isc.vo.finance.BpdBizInfoVo;
import com.brilliance.isc.vo.finance.TrdBizInfoVo;
import com.brilliance.isc.vo.lc.BedBizInfoVo;
import com.brilliance.isc.vo.lc.BrdBizInfoVo;
import com.brilliance.isc.vo.lc.LedBizInfoVo;
import com.brilliance.isc.vo.lc.LidBizInfoVo;
import com.brilliance.isc.vo.lg.GcdBizInfoVo;
import com.brilliance.isc.vo.lg.GidBizInfoVo;
import com.brilliance.isc.vo.lg.NcdBizInfoVo;
import com.brilliance.isc.vo.lg.NidBizInfoVo;
import com.brilliance.isc.vo.remit.CpdBizInfoVo;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

@Component("PtsptaToolComponent")
public class PtsptaToolComponent {

    @Autowired
    private PtyCacheService ptyCacheService;

    @Autowired
    private PtsMapper ptsMapper;

    @Autowired
    private PtaCacheService ptaCacheService;

    @Autowired
    private AdrCacheService adrCacheService;

    @Autowired
    private SysmodService sysmodService;

    @Autowired
    private PtsptaMapper ptsptaMapper;

    public PtsptaVo getPtsptaFromPts(PtsFeeDetailVo ptsFeeDetail) {
        PtsptaVo ptsptaVo = new PtsptaVo();
        String ptsinr = ptsFeeDetail.getPtsinr();
        if (!StringUtils.isEmpty(ptsinr)) {
            Pts pts = new Pts();
            pts.setInr(ptsinr);
            pts = ptsMapper.selectByPrimaryKey(pts);
            if (pts != null) {
                ptsptaVo.setNam(pts.getNam());
                ptsptaVo.setExtkey(pts.getExtkey());
                ptsptaVo.setDftdsp(pts.getDftdsp());
                ptsptaVo.setDftcur(pts.getDftcur());
                ptsptaVo.setDftact(pts.getDftact());
                ptsptaVo.setDftfeecur(pts.getDftfeecur());
                ptsptaVo.setDftactptainr(pts.getDftactptainr());
                ptsptaVo.setDftselrol(pts.getDftsetrol());
                ptsptaVo.setGlggrpflg(pts.getGlggrpflg());
                ptsptaVo.setAdrblk(pts.getAdrblk());
                ptsptaVo.setPts(pts);
            }
        }
        ptsptaVo.setPtainr(ptsFeeDetail.getPtainr());
        fillPtsptaAllProperties(ptsptaVo);
        return ptsptaVo;
    }

    public PtsptaVo getPtsptaFromPtyINR(String ptyinr) {
        PtsptaVo ptsptaVo = new PtsptaVo();
        if (StringUtils.isEmpty(ptyinr)) {
            ptsptaVo.reset();
        } else {
            ptsptaVo.setPtyinr(ptyinr);
            fillPtsptaAllProperties(ptsptaVo);
        }
        return ptsptaVo;
    }

    public PtsptaVo getPtsptaFromPtaINR(String ptainr) {
        PtsptaVo ptsptaVo = new PtsptaVo();
        ptsptaVo.setPtainr(ptainr);
        fillPtsptaAllProperties(ptsptaVo);
        return ptsptaVo;
    }

    /**
     * 根据ptsinr ptainr ptyinr 补充PtsptaVo
     *
     * @param ptsptaVo
     */
    public void fillPtsptaAllProperties(PtsptaVo ptsptaVo) {
        //1.获取pta 通过ptainr 或者 ptyinr
        ptsptaVo.reset();
        if (ptsptaVo.getPts() != null && StringUtils.isNotEmpty(ptsptaVo.getPts().getPtainr())) {
            clearPtspta(ptsptaVo);
            //覆盖父节点的ptainr
            ptsptaVo.setPtainr(ptsptaVo.getPts().getPtainr());
        }
        String ptainr = ptsptaVo.getPtainr();
        String ptyinr = ptsptaVo.getPtyinr();
        Pta pta = ptaCacheService.getPtaByInr(ptainr);
        if (pta == null) {
            if (StringUtils.isNotEmpty(ptyinr)) {
                pta = ptaCacheService.selectByPtyInrAndUsg(ptyinr, "MAA");
            }
        }
        if (pta != null) {
            ptsptaVo.setPta(pta);
            ptsptaVo.getPts().setPtyinr(pta.getPtyinr());
            ptsptaVo.setPtyinr(pta.getPtyinr());
            ptsptaVo.getPts().setPtainr(pta.getInr());
            //根据pta的值 补充ptspta
            Adr adr = adrCacheService.getAdrByInr(pta.getObjinr());
            ptsptaVo.setAdr(adr);
            ptsptaVo.setExtkey(adr.getExtkey());
            Pty pty = ptyCacheService.getPtyById(pta.getPtyinr());
            if (pty != null) {
                ptsptaVo.setPtytyp(pty.getPtytyp());
                ptsptaVo.setPtyextkey(pty.getExtkey());
            }
            Map<String, String> maps = ptsModGetAdrBlk501(ptsptaVo);
            if (maps != null) {
                //英文名称地址
                String name = maps.get("ennam");
                String address = maps.get("enadr");
                Pts pts = ptsptaVo.getPts();
                pts.setExtkey(adr.getExtkey());
                if (StringUtils.isEmpty(pts.getEnnam())) {
                    pts.setEnnam(name);
                }
                // 如果英文简称没有，则设置为英文名称
                if (StringUtils.isEmpty(pts.getNam())) {
                    pts.setNam(name);
                }

                if (StringUtils.isEmpty(pts.getEnadr())) {
                    pts.setEnadr(address);
                }
                if (StringUtils.isEmpty(ptsptaVo.getAdrblk())) {
                    String adrblk = StringUtils.convertBlock(pts.getEnnam() + "\n" + pts.getEnadr(), 4, 35);
                    pts.setAdrblk(adrblk);
                    ptsptaVo.setAdrblk(adrblk);
                } else {
                    if (StringUtils.isNotEmpty(pts.getObjinr()) && pts.getObjinr().length() == 8) {
                        //迁移老数据
                        //判断adrblk是否包含中文 如果包含中文 则取ennam + /n + enadr
                        boolean includeChineseChar = false;
                        char[] chars = ptsptaVo.getAdrblk().toCharArray();
                        for (char c : chars) {
                            if (c > 127 || c < 0) {
                                includeChineseChar = true;
                                break;
                            }
                        }
                        if (includeChineseChar) {
                            String adrblk = StringUtils.convertBlock(pts.getEnnam() + "\n" + pts.getEnadr(), 4, 35);
                            pts.setAdrblk(adrblk);
                            ptsptaVo.setAdrblk(adrblk);
                        }
                    }
                }
                if (StringUtils.isEmpty(ptsptaVo.getDbfadrblk())) {
                    ptsptaVo.setDbfadrblk(ptsptaVo.getAdrblk());
                }
            }
            Map<String, String> cnMaps = ptsModGetAdrBlkForCN(ptsptaVo);
            if (cnMaps != null) {
                //中文名称地址
                String name = cnMaps.get("cnnam");
                String address = cnMaps.get("cnadr");
                Pts pts = ptsptaVo.getPts();
                if (StringUtils.isEmpty(pts.getCnnam())) {
                    pts.setCnnam(name);
                }
                // 如果中文简称没有，则设置为中文名称
                if (StringUtils.isEmpty(pts.getNam())) {
                    pts.setNam(name);
                }

                if (StringUtils.isEmpty(pts.getCnadr())) {
                    pts.setCnadr(address);
                }
            }
        }
    }

    /**
     * 将xxxgrp里面的ptspta属性补充完整
     * 适用于来报解析
     *
     * @param xxxgrp
     */
    public void fillXxxgrpPtsptaAllPropertiesForIncomingMsg(Object xxxgrp) {
        Field[] fields = xxxgrp.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (PtsptaVo.class.equals(field.getType())) {
                PtsptaVo ptspta = Utils.getFieldValue(xxxgrp, field.getName());
                if (ptsIsRolSet(ptspta)) {
                    fillPtsptaAllProperties(ptspta);
                    ptspta.setRol(field.getName().toUpperCase());
                    ptspta.getPts().setRol(field.getName().toUpperCase());
                }
            }
        }
    }

    public PtsptaVo getPtsFromListByRol(List<PtsptaVo> ptsptaVoList, String rol) {
        if (ptsptaVoList != null) {
            List<PtsptaVo> ptsptaVos = ptsptaVoList.stream().filter(ptsptaVo -> {
                return rol.equalsIgnoreCase(ptsptaVo.getRol());
            }).collect(Collectors.toList());
            if (ptsptaVos.size() > 0) {
                return ptsptaVos.get(0);
            }
        }
        return null;
    }

    public boolean ptsIsRolSet(List<PtsptaVo> ptsList, String ptsrol) {
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsList, ptsrol);
        return ptsIsRolSet(ptsptaVo);
    }

    public String getPtaInrByRol(List<PtsptaVo> ptsList, String rol) {
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsList, rol);
        return ptsptaVo.getPtainr();
    }

    public boolean ptsIsRolSet(PtsptaVo ptsptaVo) {
        if (ptsptaVo == null) {
            return false;
        }
        if (ptsptaVo.getPts() == null) {
            return false;
        }
        //Ptainr有，则马上返回true
        if (!MdaUtils.isEmpty(ptsptaVo.getPts().getPtainr())) {
            return true;
        }
        if (!MdaUtils.isEmpty(ptsptaVo.getTmpflg()) && MdaUtils.isEmpty(ptsptaVo.getPts().getAdrblk())) {
            return true;
        }
        //国内证相关的，设置了行号，也表示设置了角色
        if (sysmodService.isDomesticLC()) {
            //有联行行号类型一定是'B'
            if (!MdaUtils.isEmpty(ptsptaVo.getPts().getBankno()) /**&& "B".equals(ptsptaVo.getPtytyp())*/) {
                return true;
            }
        }
        return false;
    }

    public void ptsptaSetConForContract(Object rec, List<PtsptaVo> ptsList) {
        for (PtsptaVo ptsptaVo : ptsList) {
            if (null == ptsptaVo || StringUtils.isEmpty(ptsptaVo.getRol())) {
                continue;
            }
            String rol = ptsptaVo.getRol().toLowerCase();
            Utils.setFieldValue(rec, rol + "ptainr", ptsptaVo.getPtainr());
            Utils.setFieldValue(rec, rol + "ptyinr", ptsptaVo.getPtyinr());
            if (StringUtils.isNotEmpty(ptsptaVo.getNam()) && ptsptaVo.getNam().length() > 40) {
                String subStr = ptsptaVo.getNam().substring(0, 40);
                Utils.setFieldValue(rec, rol + "nam", subStr);
            } else {
                Utils.setFieldValue(rec, rol + "nam", ptsptaVo.getNam());
            }
            if (!(rec instanceof Bpd)) {
                Utils.setFieldValue(rec, rol + "ref", ptsptaVo.getRef());
            }
            Utils.setFieldValue(rec, rol + "adrblk", ptsptaVo.getAdrblk());
        }
    }

    public Map<String, PtsptaVo> getPtsptaList(String objinr, String objtyp) {
        Map<String, PtsptaVo> maps = new HashMap<>();
        List<Pts> ptsList = ptsMapper.getPtsByObjInrTyp(objinr, objtyp);
        if (ptsList != null && ptsList.size() > 0) {
            ptsList.forEach(pts -> {
                PtsptaVo ptspta = new PtsptaVo();
                ptspta.setPts(pts);
                ptspta.setPtyinr(pts.getPtyinr());
                maps.put(pts.getRol(), fillPtspta(ptspta));
            });
        }
        return maps;
    }

    public PtsptaVo fillPtspta(PtsptaVo ptspta) {
        ptspta.setRol(ptspta.getPts().getRol());
        ptspta.setPtsinr(ptspta.getPts().getInr());
        ptspta.setNam(ptspta.getPts().getNam());
        ptspta.setPtyinr(ptspta.getPts().getPtyinr());
        ptspta.setPtainr(ptspta.getPts().getPtainr());
        ptspta.setExtkey(ptspta.getPts().getExtkey());
        ptspta.setDftdsp(ptspta.getPts().getDftdsp());
        ptspta.setDftcur(ptspta.getPts().getDftcur());
        ptspta.setDftact(ptspta.getPts().getDftact());
        ptspta.setDftfeecur(ptspta.getPts().getDftfeecur());
        ptspta.setDftactptainr(ptspta.getPts().getDftactptainr());
        ptspta.setDftselrol(ptspta.getPts().getDftsetrol());
        ptspta.setGlggrpflg(ptspta.getPts().getGlggrpflg());
        Pty pty = ptyCacheService.getPtyById(ptspta.getPtyinr());
        if (pty != null) {
            ptspta.setPtytyp(pty.getPtytyp());
        }
        ptspta.setPtyextkey(ptspta.getPtyextkey());
        ptspta.setAdrblk(ptspta.getPts().getAdrblk());
//        ptspta.setRolsetflg(ptspta.getRolsetflg());
        ptspta.setRef(ptspta.getPts().getRef());
        return ptspta;
    }

    /**
     * 代码出处 Sysmod.getClientPath
     *
     * @param transName
     * @param bizInfoVo
     * @param ptsptas
     * @return
     */
    public PtsptaVo getMainPtspta(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        if (StringUtils.isEmpty(transName)) {
            return null;
        }
        String bus = transName.substring(0, 2);
        String role = "";
        String hndtyp = "";
        switch (bus) {
            case "LI":
            case "BR":
                role = "APL";
                break;
            case "GI":
                hndtyp = Utils.getFieldValue(bizInfoVo, "hndtyp");
                if ("OT".equalsIgnoreCase(hndtyp)) {
                    //转开 apl非我行客户 不应该查到保证金 角色不给值 返回为空
                    //role = "APL";
                } else {
                    role = "APL";
                    if (ptsIsRolSet(ptsptas, "CTR")) {
                        role = "CTR";
                    }
                }
                break;
            case "NI":
            case "HI":
                hndtyp = Utils.getFieldValue(bizInfoVo, "hndtyp");
                if (StringUtils.isNotEmpty(hndtyp) && hndtyp.startsWith("O")) {
                    role = "APL";
                } else {
                    role = "BEN";
                }
                break;
            case "LE":
            case "BE":
            case "LT":
                role = "BEN";
                break;
            case "DI":
            case "BD":
            case "GC":
            case "NC":
            case "HC":
                role = "APL";
                break;
            case "DE":
            case "BF":
            case "DT":
                role = "BEN";
                break;
            case "BC":
                role = "DRE";
                break;
            case "BO":
                role = "DRR";
                break;
            case "BP":
                if (transName.startsWith("BP")) {
                    role = "FIA";
                }
                break;
            case "TR":
                role = "FIP";
                break;
            case "DF":
                if (transName.startsWith("DF")) {
                    role = "APL";
                } else if (transName.startsWith("BC")) {
                    role = "DRE";
                } else {
                    role = "APL";
                }
                break;
            case "CP":
                String paytyp = Utils.getFieldValue(bizInfoVo, "paytyp");
                if (StringUtils.isNotEmpty(paytyp)
                        && paytyp.startsWith("O")) {
                    role = "ORC";
                } else {
                    role = "PYE";
                }
                break;
            case "MC":
                role = "ADE";
                break;
            case "CC":
                role = "PRE";
                break;
            case "JS":
            case "WI":
                role = "APL";
                break;
            default:
                // hoping that in future product modules the client will always be CLI
                role = "CLI";
        }
        if (StringUtils.isEmpty(role)) {
            return null;
        }
        return getPtsFromListByRol(ptsptas, role);
    }

    public String getCustomerName(String transName, Object rec, List<PtsptaVo> ptsptas) {
        String hndtyp = Utils.getFieldValue(rec, "hndtyp");
        String giduil = Utils.getFieldValue(rec, "giduil");
        String bustyp = transName.substring(0, 2);
        String custName = "";
        switch (bustyp) {
            case "CP":
                CpdBizInfoVo cpdBizInfoVo = new CpdBizInfoVo();
                String paytyp = Utils.getFieldValue(rec, "paytyp");
                cpdBizInfoVo.setPaytyp(paytyp);
                custName = this.getCpdRecNam(transName, cpdBizInfoVo, ptsptas);
                break;
            case "JS":
                JsdBizInfoVo jsdBizInfoVo = new JsdBizInfoVo();
                custName = this.getJsdRecNam(transName, jsdBizInfoVo, ptsptas);
                break;
            case "BC":
                BcdBizInfoVo bcdBizInfoVo = new BcdBizInfoVo();
                custName = this.getBcdRecNam(transName, bcdBizInfoVo, ptsptas);
                break;
            case "BO":
                BodBizInfoVo bodBizInfoVo = new BodBizInfoVo();
                custName = this.getBcdRecNam(transName, bodBizInfoVo, ptsptas);
                break;
            case "CC":
                CcdBizInfoVo ccdBizInfoVo = new CcdBizInfoVo();
                custName = this.getBcdRecNam(transName, ccdBizInfoVo, ptsptas);
                break;
            case "DI":
                DidBizInfoVo didBizInfoVo = new DidBizInfoVo();
                custName = this.getDidRecNam(transName, didBizInfoVo, ptsptas);
                break;
            case "DE":
                DedBizInfoVo dedBizInfoVo = new DedBizInfoVo();
                custName = this.getDidRecNam(transName, dedBizInfoVo, ptsptas);
                break;
            case "BD":
                BddBizInfoVo bddBizInfoVo = new BddBizInfoVo();
                custName = this.getDidRecNam(transName, bddBizInfoVo, ptsptas);
                break;
            case "BF":
                BfdBizInfoVo bfdBizInfoVo = new BfdBizInfoVo();
                custName = this.getDidRecNam(transName, bfdBizInfoVo, ptsptas);
                break;
            case "LI":
                LidBizInfoVo lidBizInfoVo = new LidBizInfoVo();
                custName = this.getLidRecNam(transName, lidBizInfoVo, ptsptas);
                break;
            case "LE":
                LedBizInfoVo ledBizInfoVo = new LedBizInfoVo();
                custName = this.getLidRecNam(transName, ledBizInfoVo, ptsptas);
                break;
            case "BR":
                BrdBizInfoVo brdBizInfoVo = new BrdBizInfoVo();
                custName = this.getLidRecNam(transName, brdBizInfoVo, ptsptas);
                break;
            case "BE":
                BedBizInfoVo bedBizInfoVo = new BedBizInfoVo();
                custName = this.getLidRecNam(transName, bedBizInfoVo, ptsptas);
                break;
            case "NI":
            case "NE":
            case "HI":
                NidBizInfoVo nidBizInfoVo = new NidBizInfoVo();
                nidBizInfoVo.setHndtyp(hndtyp);
                nidBizInfoVo.setGiduil(giduil);
                custName = this.getGidRecNam(transName, nidBizInfoVo, ptsptas);
                break;
            case "GI":
            case "GE":
                GidBizInfoVo gidBizInfoVo = new GidBizInfoVo();
                gidBizInfoVo.setHndtyp(hndtyp);
                gidBizInfoVo.setGiduil(giduil);
                custName = this.getGidRecNam(transName, gidBizInfoVo, ptsptas);
                break;
            case "GC":
            case "GF":
                GcdBizInfoVo gcdBizInfoVo = new GcdBizInfoVo();
                gcdBizInfoVo.setHndtyp(hndtyp);
                gcdBizInfoVo.setGiduil(giduil);
                custName = this.getGidRecNam(transName, gcdBizInfoVo, ptsptas);
                break;
            case "NC":
            case "NF":
                NcdBizInfoVo ncdBizInfoVo = new NcdBizInfoVo();
                ncdBizInfoVo.setHndtyp(hndtyp);
                ncdBizInfoVo.setGiduil(giduil);
                custName = this.getGidRecNam(transName, ncdBizInfoVo, ptsptas);
                break;
            case "TR":
                TrdBizInfoVo trdBizInfoVo = new TrdBizInfoVo();
                custName = this.getFinanceRecNam(transName, trdBizInfoVo, ptsptas);
                break;
            case "BP":
                BpdBizInfoVo bpdBizInfoVo = new BpdBizInfoVo();
                custName = this.getFinanceRecNam(transName, bpdBizInfoVo, ptsptas);
                break;
            case "MC":
                PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, "ADE");
                if (ptsptaVo != null && ptsptaVo.getPts() != null) {
                    custName = ptsptaVo.getPts().getCnnam();
                }
                break;
        }
        return custName;
    }

    public String getGidRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String bus = transName.substring(0, 2).toUpperCase();
        String hndtyp = Utils.getFieldValue(bizInfoVo, "hndtyp");
        String giduil = Utils.getFieldValue(bizInfoVo, "giduil");
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
        switch (bus) {
            case "GE":
            case "NE":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.BEN);
                break;
            case "GI":
            case "NI":
            case "HI":
                if ("OT".equalsIgnoreCase(hndtyp)) {
                    ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.BEN);
                }/*else if("OC".equals(hndtyp)){
                    ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.BEC);
                }*/
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
//            if("CN".equalsIgnoreCase(giduil)){
            return ptsptaVo.getPts().getCnnam();
//            }else{
//                return ptsptaVo.getPts().getEnnam();
//            }
        }
        return "";
    }

    public String getFinanceRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String bus = transName.substring(0, 2).toUpperCase();
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.FIP);
        switch (bus) {
            case "TR":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.FIP);
                break;
            case "BP":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.FIA);
                break;
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
            return ptsptaVo.getPts().getCnnam();
        }
        return "";
    }

    public String getDidRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String bus = transName.substring(0, 2).toUpperCase();
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
        switch (bus) {
            case "DI":
            case "BD":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
                break;
            case "DE":
            case "BF":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.BEN);
                break;
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
            return ptsptaVo.getPts().getCnnam();
        }
        return "";
    }

    public String getLidRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String bus = transName.substring(0, 2).toUpperCase();
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
        switch (bus) {
            case "LI":
            case "BR":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
                break;
            case "LE":
            case "BE":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.BEN);
                break;
            case "LT":
            case "BT":
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.BE1);
                break;
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
            return ptsptaVo.getPts().getCnnam();
        }
        return "";
    }

    public String getBcdRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String bus = transName.substring(0, 2).toUpperCase();
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.DRE);
        switch (bus) {
            case "BC":
                //进口代收
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.DRE);
                break;
            case "BO":
                //出口托收
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.DRR);
                break;
            case "CC":
                //光票托收
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.PRE);
                break;
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
            return ptsptaVo.getPts().getCnnam();
        }
        return "";
    }

    public String getJsdRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String bus = transName.substring(0, 2).toUpperCase();
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
        switch (bus) {
            case "JS":
                //衍生品
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.APL);
                break;
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
            return ptsptaVo.getPts().getCnnam();
        }
        return "";
    }

    public String getCpdRecNam(String transName, BizInfoVo bizInfoVo, List<PtsptaVo> ptsptas) {
        String paytyp = Utils.getFieldValue(bizInfoVo, "paytyp");
        PtsptaVo ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.ORC);
        switch (paytyp) {
            case "O":
                //汇出汇款
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.ORC);
                break;
            case "I":
                //汇入汇款
                ptsptaVo = getPtsFromListByRol(ptsptas, PartyNames.PYE);
                break;
        }
        if (ptsptaVo != null && ptsIsRolSet(ptsptaVo)) {
            return ptsptaVo.getPts().getCnnam();
        }
        return "";
    }

    /**
     * 根据业务主键、业务主表类型获取可用的角色
     *
     * @param objInr  业务主键
     * @param objType 业务类型
     * @return
     */
    public List<String> getAvailablePtsRolNameFromDB(String objInr, String objType) {
        return ptsMapper.getPtsRolByObjInrTyp(objInr, objType);
    }

    /**
     * 反射获取objgrp下获取可用的Pts角色
     *
     * @param objgrp      业务Grp
     * @param isPtsRolSet 是否要求Ptspta被设置
     * @return Grp下符合要求的角色名称字符串
     */
    public List<String> getAvailablePtsRolNameFromGroup(Object objgrp, boolean isPtsRolSet) {
        return getPtsptaFromGroup(objgrp, isPtsRolSet).stream()
                .map(ptsptaVo -> ptsptaVo.getPts().getRol().toUpperCase())
                .collect(Collectors.toList());
    }

    /**
     * 反射获取objgrp下获取可用的Pts角色
     *
     * @param objgrp      业务Grp
     * @param isPtsRolSet 是否要求Ptspta被设置
     * @return Grp下符合要求的角色
     */
    public List<PtsptaVo> getPtsptaFromGroup(Object objgrp, boolean isPtsRolSet) {
        return Arrays.stream(objgrp.getClass().getDeclaredFields()).map(field -> {
            if (PtsptaVo.class.isAssignableFrom(field.getType())) {
                field.setAccessible(true);
                try {
                    PtsptaVo ptsptaVo = (PtsptaVo) field.get(objgrp);
                    if (isPtsRolSet) {
                        if (!ptsIsRolSet(ptsptaVo)) {
                            return null;
                        }
                    }
                    if (ptsptaVo != null) {
                        //为ptspta设置角色
                        ptsptaVo.setRol(field.getName().toUpperCase());
                    }
                    return ptsptaVo;
                } catch (IllegalAccessException e) {
                }
            }
            return null;
        }).filter(ptsptaVo -> ptsptaVo != null).collect(Collectors.toList());
    }

    public String ptsGetCompressedAddress(PtsptaVo ptsptaVo) {
        String adrblk = ptsptaVo.getPts().getAdrblk();
        List<String> lines = Arrays.asList(adrblk.split("\\r?\\n")); // 将字符串按行分割成列表
        lines.removeAll(Collections.singleton("")); // 删除空白行
        return String.join(System.lineSeparator(), lines); // 将非空行以系统默认的换行符连接成字符串并返回
    }

    /**
     * 英文名址框拼接规则
     *
     * @param ptsptaVo
     * @return description: ennam: 英文名称全称
     * enadr: 英文地址全名
     * ennamadr: 英文名址，取英文名称，英文地址与loczip,loctxt进行拼接
     */
    public Map ptsModGetAdrBlk501(PtsptaVo ptsptaVo) {
        Map<String, String> map = new HashMap<>();
        if (ptsptaVo == null || ptsptaVo.getAdr() == null) {
            return map;
        }
        String temp = "";
        ptsptaVo.getAdr().setNam1(StringUtils.trim(ptsptaVo.getAdr().getNam1()));
        ptsptaVo.getAdr().setNam2(StringUtils.trim(ptsptaVo.getAdr().getNam2()));
        ptsptaVo.getAdr().setStr1(StringUtils.trim(ptsptaVo.getAdr().getStr1()));
        ptsptaVo.getAdr().setStr2(StringUtils.trim(ptsptaVo.getAdr().getStr2()));
        ptsptaVo.getAdr().setLoczip(StringUtils.trim(ptsptaVo.getAdr().getLoczip()));
        ptsptaVo.getAdr().setLoctxt(StringUtils.trim(ptsptaVo.getAdr().getLoctxt()));
        // 根据adr.nam1,nam2设置英文名称全称
        // 根据adr.str1,str2,loczip,loctxt设置英文地址全名
        String enadr = "";
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getStr1())) {
            enadr = addLine(enadr, ptsptaVo.getAdr().getStr1());
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getStr2())) {
            enadr = addLine(enadr, ptsptaVo.getAdr().getStr2());
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getLoczip()) || StringUtils.isNotEmpty(ptsptaVo.getAdr().getLoctxt())) {
            String adr3 = "";
            if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getLoczip()) && StringUtils.isNotEmpty(ptsptaVo.getAdr().getLoctxt())) {
                adr3 = ptsptaVo.getAdr().getLoczip() + ptsptaVo.getAdr().getLoctxt();
            } else if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getLoczip())) {
                adr3 = ptsptaVo.getAdr().getLoczip();
            } else if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getLoctxt())) {
                adr3 = ptsptaVo.getAdr().getLoctxt();
            }
            enadr = addLine(enadr, adr3);
        }
        map.put("enadr", enadr);
        String ennam = "";
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getNam1())) {
            ennam = addLine(ennam, ptsptaVo.getAdr().getNam1());
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getNam2())) {
            ennam = addLine(ennam, ptsptaVo.getAdr().getNam2());
        }
        map.put("ennam", ennam);
        String adrblk = "";
        if (StringUtils.isNotEmpty(map.get("ennam"))) {
            adrblk += map.get("ennam");
        }
        if (StringUtils.isNotEmpty(map.get("enadr"))) {
            if (StringUtils.isEmpty(adrblk)) {
                adrblk += map.get("enadr");
            } else {
                adrblk += "\n" + map.get("enadr");
            }
        }
        map.put("ennamadr", StringUtils.convertBlock(adrblk, 4, 35));
        return map;
    }

    public Map ptsModGetAdrBlk501ForPtap12(PtsptaVo ptsptaVo) {
        Map<String, String> map = new HashMap<>();
        if (ptsptaVo == null || ptsptaVo.getAdr() == null) {
            return map;
        }
        String temp = "";
        ptsptaVo.getAdr().setNam1(StringUtils.trim(ptsptaVo.getAdr().getNam1()));
        ptsptaVo.getAdr().setNam2(StringUtils.trim(ptsptaVo.getAdr().getNam2()));
        ptsptaVo.getAdr().setStr1(StringUtils.trim(ptsptaVo.getAdr().getStr1()));
        ptsptaVo.getAdr().setStr2(StringUtils.trim(ptsptaVo.getAdr().getStr2()));
        ptsptaVo.getAdr().setLoczip(StringUtils.trim(ptsptaVo.getAdr().getLoczip()));
        ptsptaVo.getAdr().setLoctxt(StringUtils.trim(ptsptaVo.getAdr().getLoctxt()));
        // 根据adr.nam1,nam2设置英文名称全称
        // 根据adr.str1,str2,loczip,loctxt设置英文地址全名
        String enadr = "";
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getStr1())) {
            enadr = addLine(enadr, ptsptaVo.getAdr().getStr1());
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getStr2())) {
            enadr = addLine(enadr, ptsptaVo.getAdr().getStr2());
        }
        map.put("enadr", enadr);
        String ennam = "";
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getNam1())) {
            ennam = addLine(ennam, ptsptaVo.getAdr().getNam1());
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getNam2())) {
            ennam = addLine(ennam, ptsptaVo.getAdr().getNam2());
        }
        map.put("ennam", ennam);
        String adrblk = "";
        if (StringUtils.isNotEmpty(map.get("ennam"))) {
            adrblk += map.get("ennam");
        }
        if (StringUtils.isNotEmpty(map.get("enadr"))) {
            if (StringUtils.isEmpty(adrblk)) {
                adrblk += map.get("enadr");
            } else {
                adrblk += "\n" + map.get("enadr");
            }
        }
        map.put("ennamadr", StringUtils.convertBlock(adrblk, 4, 35));
        return map;
    }

    /**
     * 中文名址框拼接规则
     *
     * @param ptsptaVo
     * @return description: ennam: 中文名称全称
     * enadr: 中文地址全名
     * ennamadr: 中文名址，取中文名称，中文地址进行拼接
     */
    public Map ptsModGetAdrBlkForCN(PtsptaVo ptsptaVo) {
        ptsptaVo.setPtanam1(StringUtils.trim(ptsptaVo.getPtanam1()));
        ptsptaVo.setNam(StringUtils.trim(ptsptaVo.getNam()));
        ptsptaVo.getAdr().setAdr1(StringUtils.trim(ptsptaVo.getAdr().getAdr1()));
        ptsptaVo.getAdr().setAdr2(StringUtils.trim(ptsptaVo.getAdr().getAdr2()));
        ptsptaVo.getAdr().setAdr3(StringUtils.trim(ptsptaVo.getAdr().getAdr3()));
        ptsptaVo.getAdr().setAdr4(StringUtils.trim(ptsptaVo.getAdr().getAdr4()));
        Map<String, String> map = new HashMap<>();
        if (ptsptaVo == null || ptsptaVo.getAdr() == null) {
            return null;
        }
        String temp = "";
        if (StringUtils.isNotEmpty(ptsptaVo.getPtanam1())) {
            temp += ptsptaVo.getPtanam1();
        }
        if (StringUtils.isEmpty(temp) && !"F".equalsIgnoreCase(ptsptaVo.getPtytyp())) {
            temp += ptsptaVo.getNam();
        }
        // 设置中文名称
        map.put("cnnam", temp);
        temp = "";
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getAdr1())) {
            temp += ptsptaVo.getAdr().getAdr1();
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getAdr2())) {
            if (StringUtils.isNotEmpty(temp))
                temp += "\n";
            temp += ptsptaVo.getAdr().getAdr2();
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getAdr3())) {
            if (StringUtils.isNotEmpty(temp))
                temp += "\n";
            temp += ptsptaVo.getAdr().getAdr3();
        }
        if (StringUtils.isNotEmpty(ptsptaVo.getAdr().getAdr4())) {
            if (StringUtils.isNotEmpty(temp))
                temp += "\n";
            temp += ptsptaVo.getAdr().getAdr4();
        }
        // 设置中文地址
        map.put("cnadr", temp);
        // 进行名址拼接
        String adrblk = "";
        if (StringUtils.isNotEmpty(map.get("cnnam"))) {
            adrblk += map.get("cnnam");
        }
        if (StringUtils.isNotEmpty(map.get("cnadr"))) {
            if (StringUtils.isEmpty(adrblk)) {
                adrblk += map.get("cnadr");
            } else {
                adrblk += "\n" + map.get("cnadr");
            }
        }
        map.put("cnnamadr", adrblk);
        return map;
    }

    /**
     * 字符串相加
     */
    private String addLine(String str1, String str2) {
        if (StringUtils.isEmpty(str1)) {
            str1 += str2;
        } else {
            str1 += "\n" + str2;
        }
        return str1;
    }

    /**
     * 根据ptainr，给pts赋值
     *
     * @param ptainr
     * @param rol
     * @param language
     * @param ptsptaVo
     */
    public void fillPtsByPtainr(String ptainr, String rol, String language, PtsptaVo ptsptaVo) {
        Map<String, String> ptsptaInfo = ptsptaMapper.getPtsptaInfo(ptainr);
        PtsptaVo tmp = new PtsptaVo();
        Adr adr = new Adr();
        adr.setNam1(ptsptaInfo.get("adrnam1"));
        adr.setNam2(ptsptaInfo.get("adrnam2"));
        adr.setStr1(ptsptaInfo.get("adrstr1"));
        adr.setStr2(ptsptaInfo.get("adrstr2"));
        adr.setAdr1(ptsptaInfo.get("adr1"));
        adr.setAdr2(ptsptaInfo.get("adr2"));
        adr.setAdr3(ptsptaInfo.get("adr3"));
        adr.setAdr4(ptsptaInfo.get("adr4"));
        adr.setLoczip(ptsptaInfo.get("loczip"));
        adr.setLoctxt(ptsptaInfo.get("loctxt"));
        tmp.setAdr(adr);
        tmp.setPtytyp(ptsptaInfo.get("ptytyp"));
        tmp.setPtanam1(ptsptaInfo.get("nam1"));
        tmp.setNam(ptsptaInfo.get("nam"));
        Map<String, String> enMap = ptsModGetAdrBlk501(tmp);
        Map<String, String> cnMap = ptsModGetAdrBlkForCN(tmp);
        ptsptaInfo.put("cnnam", cnMap.get("cnnam"));
        ptsptaInfo.put("cnadr", cnMap.get("cnadr"));
        ptsptaInfo.put("ennam", enMap.get("ennam"));
        ptsptaInfo.put("enadr", enMap.get("enadr"));
        ptsptaInfo.put("cnnamadr", cnMap.get("cnnamadr"));
        ptsptaInfo.put("ennamadr", enMap.get("ennamadr"));

        ptsptaVo.getPts().setPtyinr(ptsptaInfo.get("ptyinr"));
        ptsptaVo.getPts().setPtainr(ptsptaInfo.get("ptainr"));
        ptsptaVo.getPts().setEnnam(ptsptaInfo.get("ennam"));
        ptsptaVo.getPts().setEnadr(ptsptaInfo.get("enadr"));
        ptsptaVo.getPts().setCnnam(ptsptaInfo.get("cnnam"));
        ptsptaVo.getPts().setCnadr(ptsptaInfo.get("cnadr"));
        ptsptaVo.getPts().setAdrblk(ptsptaInfo.get("ennamadr"));
        if ("CN".equals(language)) {
            ptsptaVo.getPts().setNam(ptsptaInfo.get("cnnam"));
        } else {
            ptsptaVo.getPts().setNam(ptsptaInfo.get("ennam"));
        }

        ptsptaVo.getPts().setPtynam1(ptsptaInfo.get("cnnam"));
        ptsptaVo.getPts().setRol(rol.toUpperCase());

    }

    /**
     * 根据objinr和objtyp补录缺失的role
     * @param ptsptaList
     * @param objinr
     * @param objtyp
     */
    public void addPtspta(List<PtsptaVo> ptsptaList, String objinr, String objtyp) {
        if (StringUtils.isNotEmpty(objinr) && StringUtils.isNotEmpty(objtyp)) {
            Map<String, PtsptaVo> maps = this.getPtsptaList(objinr, objtyp);
            List<PtsptaVo> losePtaptaList = new ArrayList<>();
            for (String role : maps.keySet()) {
                boolean present = ptsptaList.stream().filter(ptspta -> role.equals(ptspta.getRol())).findAny().isPresent();
                if (!present) {
                    losePtaptaList.add(maps.get(role));
                }
            }
            ptsptaList.addAll(losePtaptaList);
        }
    }

    /**
     * 清掉ptspta层的值，通过ptainr重复赋值
     * @param ptsptaVo
     */
    private void clearPtspta(PtsptaVo ptsptaVo) {
        ptsptaVo.setExtkey("");
        ptsptaVo.setPtytyp("");
        ptsptaVo.setPtyextkey("");
        ptsptaVo.setAdrblk("");
        ptsptaVo.setDbfadrblk("");
    }
}
