package com.brilliance.isc.common.api;

import com.brilliance.mda.runtime.mda.CodetableItem;
import com.brilliance.mda.runtime.mda.impl.Argument;
import com.brilliance.mda.runtime.mda.util.Dates;
import com.brilliance.mda.runtime.mda.util.Decimals;
import com.brilliance.mda.runtime.mda.util.Numerics;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.brilliance.isc.bo.Ptyrat;
import com.brilliance.isc.bo.model.Trtcre;
import com.brilliance.isc.common.api.trtcre.service.TrtcreApiService;
import com.brilliance.isc.common.api.trtcre.vo.TrtcreQueryVo;
import com.brilliance.isc.common.api.trtcre.vo.TrtcreRequest;
import com.brilliance.isc.common.api.trtcre.vo.TrtcreResponse;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.converter.DtoMapper;
import com.brilliance.isc.common.glemod.service.GlemodService;
import com.brilliance.isc.common.setfeg.service.SetfegService;
import com.brilliance.isc.common.trtcre.service.TrtcreService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.mda.dao.PtyratMapper;
import com.brilliance.isc.utils.BeanUtils;
import com.brilliance.isc.vo.component.trtcre.TrtcreVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Service
public class TrtcreApiServiceImpl implements TrtcreApiService {

    @Autowired
    private TrtcreService trtcreService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private GlemodService glemodService;

    @Autowired
    private PtyratMapper ptyratMapper;

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private SetfegService setfegService;

    public static final String CR = "<br/>";

    @Override
    public TrtcreResponse assertTrtcre(TrtcreRequest request) {
        request.reset();
        TrtcreVo trtcreVo = request.getTrtcre();
        BeanUtils.copyProperties(request.getRec(), trtcreVo.getRec());
        trtcreVo.setCbsMap(request.getCbsMap());
        trtcreVo.setPtsptaList(request.getPtsList());
        trtcreVo.setLiaccvg(request.getLiaccvg());
        Trtcre trtcre = DtoMapper.INSTANCE.transfer(request.getTrtcre());
        trtcreService.assertTrtcre(trtcre);
        trtcreVo = DtoMapper.INSTANCE.transfer(trtcre);
        return TrtcreResponse.builder()
                .trtcre(trtcreVo)
                .build();
    }

    @Override
    public TrtcreQueryVo calcAmt(TrtcreQueryVo trtcreQueryVo) {
        String modifyType = trtcreQueryVo.getModifyType();
        BigDecimal oriamt = trtcreQueryVo.getOriamt();
        String oricur = trtcreQueryVo.getOricur();
        String txncur = trtcreQueryVo.getTxncur();
        BigDecimal txnamt = trtcreQueryVo.getTxnamt();
        BigDecimal finpct = trtcreQueryVo.getPctfin();
        BigDecimal pctoriamt = trtcreQueryVo.getPctoriamt();
        if ("cur".equalsIgnoreCase(modifyType)) {
            BigDecimal rate = new BigDecimal("1");
            if (txncur.equals(oricur)) {
                trtcreQueryVo.setExtrat(new BigDecimal("1"));
            } else {
                //获取实时牌价
                TrtcreQueryVo trtcreQueryVo1 = queryExtrat(trtcreQueryVo);
                trtcreQueryVo.setExtrat(trtcreQueryVo1.getExtrat());
                trtcreQueryVo.setRattxt(trtcreQueryVo1.getRattxt());
                if (!"CNY".equals(oricur)) {
                    rate = new BigDecimal("1.00").divide(trtcreQueryVo.getExtrat(), 12, BigDecimal.ROUND_HALF_UP);
                } else {
                    rate = trtcreQueryVo.getExtrat();
                }
            }
            //根据融资比例计算百分比融资金额
            pctoriamt = xrtmodService.amtRnd(oriamt.multiply(finpct).divide(new BigDecimal(100)), oricur);
            trtcreQueryVo.setPctoriamt(pctoriamt);
            //根据百分比融资金额计算融资金额金额
            BigDecimal amt = xrtmodService.amtcnv(pctoriamt, rate, oricur, txncur);
            trtcreQueryVo.setTxnamt(amt);
        } else if ("amt".equalsIgnoreCase(modifyType)) {
            BigDecimal rate = trtcreQueryVo.getExtrat();
            if ("CNY".equals(oricur)) {
                rate = new BigDecimal("1.00").divide(trtcreQueryVo.getExtrat(), 12, BigDecimal.ROUND_HALF_UP);
            }
            pctoriamt = xrtmodService.amtcnv(txnamt, rate, txncur, oricur);
            trtcreQueryVo.setPctoriamt(pctoriamt);
            finpct = pctoriamt.divide(oriamt, 8, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            trtcreQueryVo.setPctfin(finpct);
        } else if ("pct".equalsIgnoreCase(modifyType) || "rat".equalsIgnoreCase(modifyType)) {
            //根据融资比例计算金额
            BigDecimal rate = trtcreQueryVo.getExtrat();
            if (!"CNY".equals(oricur)) {
                rate = new BigDecimal("1.00").divide(trtcreQueryVo.getExtrat(), 12, BigDecimal.ROUND_HALF_UP);
            }
            //根据融资比例计算百分比融资金额
            pctoriamt = xrtmodService.amtRnd(oriamt.multiply(finpct).divide(new BigDecimal(100)), oricur);
            trtcreQueryVo.setPctoriamt(pctoriamt);
            //根据百分比融资金额计算融资金额金额
            BigDecimal amt = xrtmodService.amtcnv(pctoriamt, rate, oricur, txncur);
            trtcreQueryVo.setTxnamt(amt);
        } else if ("pctamt".equalsIgnoreCase(modifyType)) {
            finpct = pctoriamt.divide(oriamt, 8, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
            trtcreQueryVo.setPctfin(finpct);
            //根据融资比例计算金额
            BigDecimal rate = trtcreQueryVo.getExtrat();
            if (!"CNY".equals(oricur)) {
                rate = new BigDecimal("1.00").divide(trtcreQueryVo.getExtrat(), 12, BigDecimal.ROUND_HALF_UP);
            }
            //根据百分比融资金额计算融资金额金额
            BigDecimal amt = xrtmodService.amtcnv(pctoriamt, rate, oricur, txncur);
            trtcreQueryVo.setTxnamt(amt);
        }
        return trtcreQueryVo;
    }

    @Override
    public TrtcreQueryVo getActSet(TrtcreQueryVo trtcreQueryVo) {
        String ptyinr = trtcreQueryVo.getPtyinr();
        String cur = trtcreQueryVo.getTxncur();
        BigDecimal amt = trtcreQueryVo.getTxnamt();
        Set<String> act1Set = new HashSet<>();
        Set<String> intactSet = new HashSet<>();
        Set<CodetableItem> actSet = new HashSet<>();
        if (StringUtils.isNotEmpty(ptyinr) && StringUtils.isNotEmpty(cur)) {
            String actVal = glemodService.getAvailAcc("LO", cur, ptyinr, amt);
            if (StringUtils.isNotEmpty(actVal)) {
                Arrays.stream(actVal.split("[\\r\\n]{1,2}")).forEach(account -> {
                    act1Set.add(account);
                    intactSet.add(account);
                });
            }
            if (StringUtils.isNotEmpty(trtcreQueryVo.getActpro())) {
                setfegService.getFeeSet().setActpro(trtcreQueryVo.getActpro());
                actVal = glemodService.getAvailAcc("LFC", cur, ptyinr, BigDecimal.ZERO);
                if (StringUtils.isNotEmpty(actVal)) {
                    String label = codetableService.getTblLabel(trtcreQueryVo.getActpro(), "ACTPRO");
                    Arrays.stream(actVal.split("[\\r\\n]{1,2}")).forEach(account -> {
                        if ("3400".equals(trtcreQueryVo.getActpro())) {
                            //只添加 NRA 账号
                            if (account.contains("NRA")) {
                                CodetableItem item = new CodetableItem(trtcreQueryVo.getActpro() + "-" + label, account);
                                actSet.add(item);
                            }
                        } else {
                            CodetableItem item = new CodetableItem(trtcreQueryVo.getActpro() + "-" + label, account);
                            actSet.add(item);
                        }
                    });
                }
            }
        }
        trtcreQueryVo.setAct1Set(act1Set);
        trtcreQueryVo.setIntactSet(act1Set);
        trtcreQueryVo.setActSet(actSet);
        return trtcreQueryVo;
    }

    @Override
    public TrtcreQueryVo queryExtrat(TrtcreQueryVo trtcreQueryVo) {
        //获取实时牌价
        String rattxt = "";
        String oricur = trtcreQueryVo.getOricur();
        String txncur = trtcreQueryVo.getTxncur();
        String ptyinr = trtcreQueryVo.getPtyinr();
        String rattyp = "";
        Argument<BigDecimal> rateBox = new Argument<>();
        Argument<BigDecimal> sqrRatBox = new Argument<>();
        BigDecimal rate = BigDecimal.ZERO;
        String fromcur = "";
        String tocur = "";
        if ("CNY".equals(oricur)) {
            //使用买方利率
            rattyp = "B";
            fromcur = txncur;
            tocur = oricur;
            rattxt += Strings.getText("获取$1对$2的实时牌价", fromcur, tocur);
            xrtmodService.getrat(fromcur, tocur, rattyp, Dates.today(), rateBox, sqrRatBox);
            rate = rateBox.value;
            rattxt += CR + Strings.getText("使用买方牌价$1", Numerics.round(rate, 6));
        } else {
            //使用卖方汇率
            rattyp = "S";
            fromcur = oricur;
            tocur = txncur;
            rattxt += Strings.getText("获取$1对$2的实时牌价", fromcur, tocur);
            xrtmodService.getrat(fromcur, tocur, rattyp, Dates.today(), rateBox, sqrRatBox);
            rate = rateBox.value;
            rattxt += CR + Strings.getText("使用卖方牌价$1", Numerics.round(rate, 6));
        }
        //客户优惠利率
        Ptyrat ptyrat = ptyratMapper.getPtyratByPtyinrAndCur(ptyinr, fromcur);
        if (ptyrat != null) {
            if ("B".equals(rattyp)) {
                if ("1".equals(ptyrat.getBuytyp())) {
                    //日圆从小数点后6位开始优惠
                    if ("JPY".equals(fromcur)) {
                        rate = Decimals.add(rate, Decimals.div(ptyrat.getBuyrat(), 1000000));
                    } else {
                        rate = Decimals.add(rate, Decimals.div(ptyrat.getBuyrat(), 10000));
                    }
                    String label = codetableService.getTblLabel(ptyrat.getBuytyp(), "BUYTYP");
                    rattxt += CR + Strings.getText("$1 $2", label, ptyrat.getBuyrat());
                } else if ("2".equals(ptyrat.getBuytyp())) {
                    xrtmodService.getrat(fromcur, tocur, "M", Dates.today(), rateBox, sqrRatBox);
                    rate = Decimals.add(rate, Decimals.div(Decimals.mul((Decimals.sub(rateBox.value, rate)), ptyrat.getBuyrat()), 100));
                    String label = codetableService.getTblLabel(ptyrat.getBuytyp(), "BUYTYP");
                    rattxt += CR + Strings.getText("$1 $2", label, ptyrat.getBuyrat());
                }
            } else if ("S".equals(rattyp)) {
                if ("1".equals(ptyrat.getSeltyp())) {
                    //日圆从小数点后6位开始优惠
                    if ("JPY".equals(fromcur)) {
                        rate = Decimals.sub(rate, Decimals.div(ptyrat.getSelrat(), 1000000));
                    } else {
                        rate = Decimals.sub(rate, Decimals.div(ptyrat.getSelrat(), 10000));
                    }
                    String label = codetableService.getTblLabel(ptyrat.getSeltyp(), "SELTYP");
                    rattxt += CR + Strings.getText("$1 $2", label, ptyrat.getSelrat());
                } else if ("2".equals(ptyrat.getSeltyp())) {
                    xrtmodService.getrat(fromcur, tocur, "M", Dates.today(), rateBox, sqrRatBox);
                    rate = Decimals.sub(rate, Decimals.div(Decimals.mul((Decimals.sub(rate, rateBox.value)), ptyrat.getSelrat()), 100));
                    String label = codetableService.getTblLabel(ptyrat.getSeltyp(), "SELTYP");
                    rattxt += CR + Strings.getText("$1 $2", label, ptyrat.getSelrat());
                }
            }
        }
        rattxt += CR + Strings.getText("最终获取实时牌价$1", Numerics.round(rate, 6));
        trtcreQueryVo.setRattxt(rattxt);
        trtcreQueryVo.setExtrat(rate);
        return trtcreQueryVo;
    }
}
