package com.brilliance.isc.common.util;

import cn.hutool.core.date.DateUtil;
import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Ptc;
import com.brilliance.isc.bo.Pty;
import com.brilliance.isc.common.bopset.counter.service.CounterBopdecService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
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.jshmod.common.Ctlset;
import com.brilliance.isc.common.jshmod.common.JshObjType;
import com.brilliance.isc.common.jshmod.vo.Jshmod;
import com.brilliance.isc.common.setfeg.vo.SetfegVo;
import com.brilliance.isc.common.setfeg.vo.SetfelVo;
import com.brilliance.isc.common.setglg.vo.SetglgVo;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.mda.dao.PtcMapper;
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.math.RoundingMode;
import java.util.Date;
import java.util.Map;
import java.util.Optional;

public class JshmodUtils {

    /**
     * 获取外汇账户内结售汇的金额
     *
     * @return GHCNYAMT 购汇金额 JHAMT 结汇金额
     */
    public static Pair<BigDecimal, BigDecimal> isFeeAndGetAMT(SetgllVo _setgll) {
        BigDecimal ghcnyamt;
        BigDecimal jhamt;

        String rol = _setgll.getRol();
        String cur = _setgll.getCur();
        String debcdtflg = _setgll.getDebcdtflg();
        SetfegVo setfeg = BopContext.getSetfeg();
        BigDecimal chargesAMT = new BigDecimal("0");
        for (SetfelVo setfel : setfeg.getSetfel()) {
            if (StringUtils.equals(rol, setfel.getRol()) && "X".equals(setfel.getDsp())) {
                chargesAMT = chargesAMT.add(setfel.getAmt());
            }
        }
        BigDecimal fmtamtall = _setgll.getFmtamt();
        SetglgVo setglg = BopContext.getSetglg();
        for (SetgllVo setgll : setglg.getSetgll()) {
            if (!_setgll.equals(setgll)) {
                if (StringUtils.equals(rol, setgll.getRol()) && StringUtils.equals(debcdtflg, setgll.getDebcdtflg())) {
                    fmtamtall = fmtamtall.add(setgll.getFmtamt());
                }
            }
        }
        if ("D".equals(debcdtflg)) {
            if ("CNY".equals(cur)) {
                ghcnyamt = fmtamtall.subtract(chargesAMT);
                jhamt = ghcnyamt.divide(_setgll.getRat(), RoundingMode.HALF_UP);
            } else {
                jhamt = fmtamtall.subtract(chargesAMT);
                ghcnyamt = jhamt.multiply(_setgll.getRat());
            }
        } else {
            if ("CNY".equals(cur)) {
                ghcnyamt = _setgll.getFmtamt();
                jhamt = ghcnyamt.divide(_setgll.getRat(), RoundingMode.HALF_UP);
            } else {
                jhamt = _setgll.getFmtamt();
                ghcnyamt = jhamt.multiply(_setgll.getRat());
            }
        }
        return new ImmutablePair<>(ghcnyamt, jhamt);
    }

    /**
     * 获取结售汇申报要取得各业务品种的角色
     *
     * @return 角色名称
     */
    public static String getTransRol() {
        String transName = SettleContext.getTransName();
        switch (transName.substring(0, 2)) {
            case "BC":
                return "DRE";
            case "BO":
                return "DRR";
            case "BE":
            case "LE":
            case "GE":
                return "BEN";
            case "CC":
                return "PRE";
            case "BP":
                return "FIA";
            case "BT":
            case "LT":
                return "BE1";
            case "CP":
                BizInfoVo bizInfo = BopContext.getBizInfo();
                String paytyp = (String) Utils.getField(bizInfo, "paytyp").orElseGet(String::new);
                return "O".equals(paytyp) ? "ORC" : "PYE";
            case "TR":
                //海外代付
                return "FIP";
            case "MC":
                return "ADE";
            case "BR":
            case "GI":
            case "LI":
            case "FX":
            default:
                return "APL";
        }
    }


    /**
     * 原方法名：Getptyfields2
     *
     * @param rol 角色
     * @return Pty
     */
    public static Pty getPty2(String rol) {
        String transName = SettleContext.getTransName();
        String ptyRol;
        if (StringUtils.equals(transName.substring(3, 6), "FRE")) {
            ptyRol = "OTHCC";
        } else {
            switch (transName.substring(0, 2)) {
                case "BR":
                case "LI":
                case "GI":
                case "NI":
                    ptyRol = "APL";
                    break;
                case "BC":
                case "CC":
                    ptyRol = "DRE";
                    break;
                case "BO":
                    ptyRol = "DRR";
                    break;
                case "BE":
                case "GE":
                case "NE":
                    ptyRol = "BEN";
                    break;
                case "BT":
                    ptyRol = "BE1";
                    break;
                case "CP":
                    BizInfoVo bizInfo = BopContext.getBizInfo();
                    String paytyp = (String) Utils.getField(bizInfo, "paytyp").orElseGet(String::new);
                    ptyRol = "I".equals(paytyp) || "T".equals(paytyp) ? "PYE" : "ORC";
                    break;
                case "TR":
                    ptyRol = "FIP";
                    break;
                case "BP":
                    ptyRol = "FIA";
                    break;
                case "MC":
                    ptyRol = "ADE";
                    break;
                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 Ptc getPtc() {
        String ptyinr = BopUtils.getPtsByRol(getTransRol()).getPtyinr();
        PtcMapper ptcMapper = SpringEnvContext.getBean(PtcMapper.class);
        Ptc ptc = ptcMapper.selectByPtyinrAndTyp(ptyinr, "JSH");
        return Optional.ofNullable(ptc).orElseGet(Ptc::new);
    }

    public static String getJshSetTyp(Jshmod jshmod) {
        //设置需要输出的申报格式
        String szflg = jshmod.getSzflg();
        String basflg = jshmod.getBasflg();
        String vrfflg = jshmod.getVrfflg();
        if ("1".equals(szflg)) {
            if (StringUtils.isNotEmpty(basflg) && StringUtils.isEmpty(vrfflg)) {
                return "JSH1";
            }
            if (StringUtils.isNotEmpty(basflg) && StringUtils.isNotEmpty(vrfflg)) {
                return "JSH2";
            }
        } else if ("2".equals(szflg)) {
            if (StringUtils.isNotEmpty(basflg) && StringUtils.isEmpty(vrfflg)) {
                return "JSH3";
            }
            if (StringUtils.isNotEmpty(basflg) && StringUtils.isNotEmpty(vrfflg)) {
                return "JSH4";
            }
        }
        return "";
    }

    public static void setDectyp(Jshmod jshmod) {
        String transName = SettleContext.getTransName();
        String jshSetTyp = JshmodUtils.getJshSetTyp(jshmod);
        Ctlset ctlmod = jshmod.getCtlmod();
        JshObjType jshObjType = ctlmod.getJshObjectMap().get(jshSetTyp);
        if (!transName.startsWith(jshObjType.getSubtyp())) {
            ctlmod.setDectyp("V"); //!V数据提取交易
        } else {
            switch (StringUtils.substring(transName, 3, 6)) {
                case "ADD": //!A增加
                    ctlmod.setDectyp("A");
                    break;
                case "AME": //!M修改
                    ctlmod.setDectyp("M");
                    break;
                case "DEL": //!D删除
                    ctlmod.setDectyp("D");
                    break;
                case "SND": //!S发送
                    ctlmod.setDectyp("S");
                    break;
                case "INF": //!I查询
                    ctlmod.setDectyp("I");
                    break;
                case "COR": //!U接收
                    ctlmod.setDectyp("U");
                    break;
                case "PNT": //!P打印
                    ctlmod.setDectyp("P");
            }
        }

    }

    private static String convertDecimalToBase33(int decimalNumber) {
        final String base33Chars = "0123456789ABCDEFGHJKLMNPQRSTUVWXY";
        StringBuilder base33Number = new StringBuilder();

        while (decimalNumber > 0) {
            int remainder = decimalNumber % 33;
            base33Number.insert(0, base33Chars.charAt(remainder));
            decimalNumber /= 33;
        }

        if (base33Number.length() > 4) {
            base33Number = new StringBuilder(base33Number.substring(base33Number.length() - 4));
        }

        while (base33Number.length() < 4) {
            base33Number.insert(0, '0');
        }
        return base33Number.toString();

    }

    /**
     * 生成业务编号
     */
    public static void getReference(Jshmod jshmod) {
        String ref;
        //!产生业务编号
        Date reldat = DateUtil.parse(DateUtil.today());
        String typ = getJshSetTyp(jshmod);
        Map<String, JshObjType> jshObjectMap = jshmod.getCtlmod().getJshObjectMap();
        String subtyp = jshObjectMap.get(typ).getSubtyp();
        Bch wrkbch = Optional.ofNullable(SettleContext.getUserSession().getWrkbch()).orElseGet(Bch::new);
        String wgbm = wrkbch.getDecnum();

        String couNam = wgbm + subtyp + "C";
        CounterBopdecService counterBopdecService = SpringEnvContext.getBean(CounterBopdecService.class);
        int counum = counterBopdecService.dbBopdecCounter(couNam, reldat);
        //1.3规范允许结售汇流水号第二位和第三位为字母
        String couVal = convertDecimalToBase33(counum);
        if ("DBJ".equals(subtyp)) {
            ref = wgbm + DateUtil.format(reldat, "yyMMdd") + couVal.substring(1) + "W";
            jshmod.getDbjgrp().getBas().setRptno(ref);
            jshmod.getDbjgrp().getVrf().setRptno(ref);
        } else if ("DBW".equals(subtyp)) {
            ref = wgbm + DateUtil.format(reldat, "yyMMdd") + couVal.substring(1) + "Y";
            jshmod.getDbwgrp().getBas().setRptno(ref);
            jshmod.getDbwgrp().getVrf().setRptno(ref);
        }

    }

}
