package com.brilliance.isc.common.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Pts;
import com.brilliance.isc.bo.Pty;
import com.brilliance.isc.common.bopset.counter.service.CounterRmbService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.BopContext;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.context.SpringEnvContext;
import com.brilliance.isc.common.rmbbop.common.AbstractRmb;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.vo.model.SetgrpVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class RmbbopUtils {

    public static String getCur() {
        return BopContext.getCbsMap().get("MAX").getCur();
    }

    public static BigDecimal getAmt() {
        return BopContext.getCbsMap().get("MAX").getAmt();
    }

    public static String getZmqflg() {
        Bch bch = Optional.ofNullable(SettleContext.getUserSession().getBch()).orElseGet(Bch::new);
        return bch.getZmqflg();
    }

    public static String getLhanum() {
        Bch wrkbch = Optional.ofNullable(SettleContext.getUserSession().getWrkbch()).orElseGet(Bch::new);
        return wrkbch.getLhanum();
    }

    public static String getLhanam() {
        Bch wrkbch = Optional.ofNullable(SettleContext.getUserSession().getWrkbch()).orElseGet(Bch::new);
        return wrkbch.getLhanam();
    }


    public static String getCountryCodeByRol(String rol) {
        String loccty = BopUtils.getAdrByRol(rol).getLoccty().trim();
        CodetableService codetableService = SpringEnvContext.getBean(CodetableService.class);
        return loccty.length() == 2 ? codetableService.getTblLabel(loccty, "CTYCOD") : loccty;
    }

    public static String getOrgCode(String rol) {
        Pty pty = RmbbopUtils.getPty(rol);
        return StringUtils.isEmpty(pty.getIdcode()) ? pty.getJuscod() : pty.getIdcode();
    }

    public static String getOrgName(String rol) {
        return RmbbopUtils.getPty(rol).getNam1();
    }

    /**
     * 原方法名：Getptyfields_rmb
     *
     * @param rol 角色
     * @return Pty
     */
    public static Pty getPty(String rol) {
        String transName = SettleContext.getTransName().substring(0, 6);
        String ptyRol = "";
        if (StringUtils.equals(transName.substring(3, 6), "FRE")) {
            ptyRol = "OTHCC";
        } else {
            switch (transName) {
                case "BRTSET":
                case "BRTPAY":
                case "BRTUTL":
                case "BRTSUS":
                case "LITOPN":
                case "BRTUDP":
                case "LITAME":
                    ptyRol = StringUtils.equals(rol, "APL") || StringUtils.equals(rol, "BEN") ? rol : "OTHP";
                    break;
                case "BCTSET":
                case "BCTPAY":
                case "BCTSUS":
                case "BCTDAV":
                    ptyRol = "DRE";
                    break;
                case "BOTSET":
                case "BOTPAY":
                case "BOTDAV":
                    ptyRol = "DRR";
                    break;
                case "BTTSET":
                case "BTTSND":
                case "BTTACC":
                    ptyRol = StringUtils.equals(rol, "BEN") ? "BE1" : rol;
                    break;
                case "BETSET":
                case "GETSET":
                    ptyRol = "BEN";
                    break;
                case "DFTSET":
                    ptyRol = "APL";
                    break;
                case "CPTSET":
                    String paytyp = Utils.getFieldValue(BopContext.getBizInfo(), "paytyp");
                    ptyRol = StringUtils.equals(paytyp, "I") || StringUtils.equals(paytyp, "T") ? "PYE" : "ORC";
                    break;
                case "GITSET":
                case "GITOPN":
                case "GITODZ":
                    String hndtyp = Utils.getFieldValue(BopContext.getBizInfo(), "hndtyp");
                    String type = BopUtils.judgeGIType(transName, hndtyp);
                    if (StringUtils.equals(type, "GI")) ptyRol = "APL";
                    else if (StringUtils.equals(type, "GE")) ptyRol = "BEN";
                    break;
                case "TRTOPN":
                    ptyRol = "FIP";
                    break;
                case "CPTADV":
                case "CPTREP":
                case "CPTATI":
                    ptyRol = "PYE";
                    break;
                case "CPTOPN":
                case "CPTATO":
                    ptyRol = "ORC";
                    break;
                case "CCTSET":
                    ptyRol = "PRE";
                    break;
                case "BPTOPN":
                    ptyRol = StringUtils.equals(rol, "APL") ? "APL" : "FIA";
                    break;
                case "LITROG":
                case "LTTOPN":
                case "BETSND":
                case "BETACC":
                default:
                    ptyRol = rol;
            }
        }
        PtyCacheService ptyCacheService = SpringEnvContext.getBean(PtyCacheService.class);
        Pty pty = ptyCacheService.getPtyById(BopUtils.getPtsByRol(ptyRol).getPtyinr());
        return Optional.ofNullable(pty).orElseGet(Pty::new);
    }

    public static String getRmbRef(AbstractRmb abstractRmb) {
        String objtyp = abstractRmb.getObjtyp().toLowerCase();
        String msgtype;
        switch (objtyp) {
            case "tda":
                msgtype = "2101";
                break;
            case "tfa":
                msgtype = "2102";
                break;
            case "tfb":
                msgtype = "2103";
                break;
            case "tdn":
                msgtype = "2106";
                break;
            case "tdm":
                msgtype = "2107";
                break;
            case "tdf":
                msgtype = "2108";
                break;
            case "tdb":
                msgtype = "2111";
                break;
            case "tcr":
                msgtype = "2112";
                break;
            case "tdo":
                msgtype = "2122";
                break;
            case "tdq":
                msgtype = "2123";
                break;
            case "tcp":
                msgtype = "2135";
                break;
            case "tga":
                msgtype = "2180";
                break;
            default:
                msgtype = objtyp;
        }
        String ownref = BopContext.getBizInfo().getOwnref();
        //!光大改为生成业务主键
        String couNam = objtyp + ownref;
        CounterRmbService counterRmbService = SpringEnvContext.getBean(CounterRmbService.class);
        DateTime today = DateUtil.parse(DateUtil.today());
        int counum = counterRmbService.dbRmbCounter(couNam, today);
        while (counum == 0) {
            counum = counterRmbService.dbRmbCounter(couNam, today);
        }
        String couVal = String.format("%4s", counum).replace(' ', '0');
        return msgtype + ownref + couVal;
    }

    public static String getTranRol() {
        String transName = SettleContext.getTransName().substring(0, 6);
        String tranRol = "";
        switch (transName) {
            case "BRTSET":
            case "BRTSUS":
            case "BRTPAY":
            case "GITSET":
            case "BRTUTL":
            case "CPTSET":
            case "DFTSET":
                tranRol = "APL";
                break;
            case "BCTSET":
            case "BCTSUS":
            case "BCTPAY":
                tranRol = "DRE";
                break;
            case "BOTSET":
            case "BOTPAY":
                tranRol = "DRR";
                break;
            case "BETSET":
            case "GETSET":
                tranRol = "BEN";
                break;
            case "CCTSET":
                tranRol = "PRE";
                break;
            case "BPTOPN":
                tranRol = "FIA";
                break;
            case "BTTSET":
            case "BTTPAY":
                tranRol = "BE1";
                break;
            case "CPTOPN":
            case "CPTATO":
                tranRol = "ORC";
                break;
            case "CPTADV":
            case "CPTREP":
            case "CPTATI":
                tranRol = "PYE";
        }
        return tranRol;
    }

    public static Pair<String, BigDecimal> getBasic() {
        String othacc = "";
        BigDecimal othamt;
        // 如果party为CLI应与APL的金额合并处理
        BigDecimal ghCliAmt = new BigDecimal("0.0000");
        BigDecimal maxothamt = new BigDecimal("0.0000");
        // using gridcount results in circular ref,.
        //获得SUMTAB路径
        List<SetgllVo> setgll = BopContext.getSetglg().getSetgll();
        for (SetgllVo eot : setgll) {
            String rolStr = eot.getRol();
            BigDecimal amt = eot.getAmt();
            String actStr = eot.getAct();
            String gllGrp = eot.getGllgrp();
            //选中seperte时，$GllGrp为F
            if (cnyCheckRol(rolStr)) {
                //增加了外币申报
                if (!StringUtils.equals(gllGrp, "F")) {
                    if (amt.abs().compareTo(maxothamt) > 0) {
                        maxothamt = amt.abs();
                        othacc = actStr;
                    }
                    ghCliAmt = ghCliAmt.add(amt.abs());
                }
            }
        }
        othamt = ghCliAmt;
        return new ImmutablePair<>(othacc, othamt);
    }

    private static boolean cnyCheckRol(String rol) {
        String transName = SettleContext.getTransName().substring(0, 6);
        String bus = transName.substring(0, 2);
        String[] rols = null;
        switch (bus) {
            case "LI":
            case "BR":
                rols = new String[]{"APL"};
                break;
            case "BC":
                rols = new String[]{"DRE"};
                break;
            case "LE":
                break;
            case "BO":
                rols = new String[]{"DRR", "LO1", "FIA"};
                break;
            case "BE":
                rols = new String[]{"BEN", "COL", "FIA", "ADV"};
                break;
            case "CC":
                rols = new String[]{"CLI", "PRE"};
                break;
            case "GI":
            case "NI":
                rols = new String[]{"APL", "BEN"};
                break;
            case "GE":
            case "NE":
                rols = new String[]{"BEN"};
                break;
            case "BP":
                rols = new String[]{"FIA", "LO1"};
                break;
        }
        switch (transName) {
            case "CPTOPN":
            case "CPTATO":
                rols = new String[]{"ORC", "ORI"};
                break;
            case "CPTADV":
            case "CPTREP":
            case "CPTATI":
                rols = new String[]{"PYE"};
        }
        return rols != null && Arrays.asList(rols).contains(rol);
    }

    public static Pair<String, String> getOutSwift(String rol) {
        String extkey = "";
        String nam = "";
        // using gridcount results in circular ref,.
        // 获得SUMTAB路径
        List<SetgllVo> setgll = BopContext.getSetglg().getSetgll();
        PtsptaToolComponent ptsptaToolComponent = SpringEnvContext.getBean(PtsptaToolComponent.class);
        for (SetgllVo eot : setgll) {
            SetgrpVo setgrp = eot.getSetgrp();
            PtsptaVo ptsptaVo = Utils.getFieldValue(setgrp, rol.toLowerCase());
            if (ptsptaToolComponent.ptsIsRolSet(ptsptaVo)) {
                Pts pts = ptsptaVo.getPts();
                extkey = StringUtils.isEmpty(pts.getExtkey()) ? extkey : pts.getExtkey();
                nam = StringUtils.isEmpty(pts.getNam()) ? nam : pts.getNam();
            }
        }
        return new ImmutablePair<>(extkey, nam);
    }

    /**
     * 原方法名：GETTXCCY_rmb
     *
     * @return BigDecimal
     */
    public static BigDecimal getTxccy() {
        String transName = SettleContext.getTransName().substring(0, 6);;
        String bus = transName.substring(0, 2);
        BigDecimal ghAplAmt = new BigDecimal("0.00");
        List<SetgllVo> setgll = BopContext.getSetglg().getSetgll();
        switch (bus) {
            case "BR":
            case "BC":
            case "GI":
            case "NI":
            case "BO":
            case "BE":
            case "CC":
            case "CP":
            case "GE":
            case "NE":
            case "BT":
            case "BP":
                for (SetgllVo eot : setgll) {
                    String rolStr = eot.getRol();
                    String dspStr = eot.getDsp();
                    String actStr = eot.getAct();
                    BigDecimal amt = eot.getAmt();
                    String deb = eot.getDebcdtflg();
                    String gllGrp = eot.getGllgrp();
                    //国内费用如果选择了seperate,在收支申报信息中不体现
                    //选中seperte时，$GllGrp为F
                    String subActStr = actStr.length() >= 10 ? actStr.substring(6, 10) : "";
                    if (!StringUtils.equals(gllGrp, "F")) {
                        switch (bus) {
                            case "BO":
                            case "BE":
                            case "CC":
                            case "GE":
                            case "NE":
                                if (txtCheckRol(rolStr) && StringUtils.equals(subActStr, "2120") && txtCheckDSP(dspStr)) {
                                    ghAplAmt = ghAplAmt.add(amt.abs());
                                }
                                break;
                            case "BT":
                            case "BP":
                                if (txtCheckRol(rolStr) && txtCheckDSP(dspStr)) {
                                    ghAplAmt = ghAplAmt.add(amt.abs());
                                }
                                break;
                            case "CP":
                                switch (transName) {
                                    case "CPTOPN":
                                    case "CPTATO":
                                        if (txtCheckRol(rolStr) && StringUtils.equals(subActStr, "2120") && StringUtils.equals(deb, "C")) {
                                            ghAplAmt = ghAplAmt.add(amt.abs());
                                        }
                                        break;
                                    case "CPTADV":
                                    case "CPTATI":
                                    case "CPTREP":
                                        if (StringUtils.equals(subActStr, "2120") || StringUtils.equals(subActStr, "2149")) {
                                            if (txtCheckRol(rolStr) && StringUtils.equals(deb, "D")) {
                                                ghAplAmt = ghAplAmt.add(amt.abs());
                                            }
                                            break;
                                        }
//                                    case "CPTREP":
//                                        if (txtCheckRol(rolStr) && StringUtils.equals(subActStr, "2149") && StringUtils.equals(deb, "D")) {
//                                            ghAplAmt = ghAplAmt.add(amt.abs());
//                                        }
//                                        break;
                                }
                                break;
                        }
                    }
                }
                break;
        }
        return ghAplAmt;
    }

    private static boolean txtCheckRol(String rol) {
        String transName = SettleContext.getTransName().substring(0, 6);
        String bus = transName.substring(0, 2);
        String[] rols = null;
        switch (bus) {
            case "BO":
            case "CC":
                rols = new String[]{"COL"};
                break;
            case "BE":
                rols = new String[]{"ISS", "AVB", "OTH", "ADV"};
                break;
            case "BT":
                rols = new String[]{"BE1"};
                break;
            case "CP":
                if (StringUtils.equals(transName, "CPTADV") || StringUtils.equals(transName, "CPTATI")) {
                    rols = new String[]{"SND", "ORC"};
                }
                if (StringUtils.equals(transName, "CPTOPN") || StringUtils.equals(transName, "CPTATO")) {
                    rols = new String[]{"PYE"};
                }
                if (StringUtils.equals(transName, "CPTREP")) {
                    rols = new String[]{"ORC"};
                }
                break;
            case "BP":
                rols = new String[]{"BU1", "BU2"};
                break;
            case "GE":
            case "NE":
                BizInfoVo bizInfo = BopContext.getBizInfo();
                String payrol = Utils.getFieldValue(bizInfo, "payrol");
                rols = new String[]{payrol};
        }
        return rols != null && Arrays.asList(rols).contains(rol);
    }

    private static boolean txtCheckDSP(String dsp) {
        String transName = SettleContext.getTransName().substring(0, 6);
        String bus = transName.substring(0, 2);
        String[] dsps = null;
        switch (bus) {
            case "PC":
            case "BO":
            case "BE":
            case "GE":
            case "NE":
                dsps = new String[]{"LOD", "TPD", "SPD"};
                break;
            case "BT":
                dsps = new String[]{"LOC", "TPC", "SPC"};
                break;
            case "CC":
                dsps = new String[]{"LOD", "TPD", "SPD", "NOD"};
                break;
            case "BP":
                dsps = new String[]{"LOD", "TPD", "SPD", "BF"};
                break;
        }
        return dsps != null && Arrays.asList(dsps).contains(dsp);
    }

    public static BigDecimal getActuccy() {
        //获得实际付款金额
        List<SetgllVo> setgll = BopContext.getSetglg().getSetgll();
        // using gridcount results in circular ref,.
        //获得SUMTAB路径
        BigDecimal amt = new BigDecimal("0.00");
        for (SetgllVo eot : setgll) {
            String rolStr = eot.getRol();
            if (actCheckRol(rolStr)) {
                amt = amt.add(eot.getAmt());
            }
        }
        return amt.abs();
    }

    private static boolean actCheckRol(String rol) {
        String transName = SettleContext.getTransName().substring(0, 6);
        String bus = transName.substring(0, 2);
        String[] rols = null;
        switch (bus) {
            case "LI":
                rols = new String[]{"PRB"};
                break;
            case "BR":
            case "GI":
            case "NI":
                BizInfoVo bizInfo = BopContext.getBizInfo();
                String docprbrol = Utils.getFieldValue(bizInfo, "docprbrol");
                rols = new String[]{docprbrol};
                break;
            case "BC":
                rols = new String[]{"RMI"};
                break;
            case "BO":
                rols = new String[]{"DRR"};
                break;
        }
        return rols != null && Arrays.asList(rols).contains(rol);

    }

}
