package com.brilliance.isc.common.fecism.calcfee.impl;

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.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.fecism.calcfee.AbstractFeeCalculator;
import com.brilliance.isc.common.fecism.service.FecismService;
import com.brilliance.isc.common.fecism.vo.CalcFeeRequest;
import com.brilliance.isc.common.fecism.vo.CalcFeeResponse;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

//计算规则是% 百分率
@Component("%_FeeCalculator")
public class PercentFeeCalculator extends AbstractFeeCalculator {

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private FecismService fecismService;

    @Autowired
    private XrtmodService xrtmodService;

    @Override
    public CalcFeeResponse calculate(CalcFeeRequest request) {
        CalcFeeResponse response = new CalcFeeResponse();
        buildInfdetstm(response, request.getRelcur(), request.getRelAmt());
        if (request != null) {
            buildInfdetstmDat2dft(response, request.getDat2dft());
        }
        //费用计算细节
        String inftxt = buildInftxt(request);
        //inftxt += CR + Strings.getText("Calculation based on $1 i.e. $2 $3", codetableService.getTblLabel(request.getCalcbs(), "FECAMT"), request.getRelcur(), Utils.fmtAmount(request.getRelAmt(), request.getRelcur()));
        inftxt += CR + Strings.getText("计算基准为$1,金额 $2 $3", codetableService.getTblLabel(request.getCalcbs(), "CALCBS"), request.getRelcur(), Utils.fmtAmount(request.getRelAmt(), request.getRelcur()));
        if ("1".equals(request.getCalrul())) {
            inftxt += CR + Strings.getText("计费规则是千分率");
        } else {
            inftxt += CR + Strings.getText("计费规则是百分率");
        }
        //计算费用份数 和 收费日期
        Date date1 = request.getDat1();
        Date date2 = request.getDat2();
        int unt = request.getUnt();
        //否则根据份数算日期
        String pertyp = request.getPertyp();
        if (!MdaUtils.isEmpty(pertyp) && !"n".equals(request.getPertyp())) {
            if (date2 == null || "u".equals(request.getModflg()) || request.getGraceDays() != 0) {
                //根据份数算日期 (非修改手续费情况)
                if (date1 != null) {
                    date2 = Utils.calcDate(date1, unt, pertyp, "");
                }
            } else {
                //根据日期算份数
                if (date1 != null && date2 != null) {
                    unt = Utils.calcUnt(date1, date2, pertyp);
                    //如果日期相同，默认份数给1
                    if (unt == 0 && MdaUtils.compareTo(date1, date2) == 0) {
                        unt = 1;
                    }
                    //重新根据unt算日期
                    date2 = Utils.calcDate(date1, unt, pertyp, "");
                }
            }
        }
        if (request.getGraceDays() != 0 && date2 != null) {
            date2 = DateUtils.addDays(date2, request.getGraceDays());
        }
        inftxt += CR + Strings.getText("本次收取$1单元$2", unt, codetableService.getTblLabel(request.getFeecod(), "FEETXT"));
        Date endDate = date2;
        if (request.getDat2dft() != null && MdaUtils.compareTo(endDate, request.getDat2dft()) > 0) {
            endDate = request.getDat2dft();
        }
        inftxt += CR + Strings.getText("计费周期$1到$2", Utils.fmtDate(date1, "yyyy-MM-dd"), Utils.fmtDate(endDate, "yyyy-MM-dd"));
        if (unt < request.getPermin()) {
            unt = request.getPermin();
            //inftxt += CR + Strings.getText("Minimum units applied: $1 $2", unt, codetableService.getTblLabel(pertyp, "FECPER"));
            inftxt += CR + Strings.getText("使用最小单元$1", unt);
        }
        //计算费用
        String feecur = request.getFeecur();
        String relcur = request.getRelcur();
        BigDecimal relamt = request.getRelAmt();
        BigDecimal ratuse = request.getRatcal();
        BigDecimal fecamt = new BigDecimal("0");
        BigDecimal basis = new BigDecimal("100");
        if ("1".equals(request.getCalrul())) {
            basis = new BigDecimal("1000");
        }
        BigDecimal lftunt = new BigDecimal(unt);
        int oldper = 0;
        BigDecimal tirunt = BigDecimal.ZERO;
        if (MdaUtils.compareTo(Decimals.add(lftunt, oldper), request.getPerbegtr5()) >= 0 && request.getPerbegtr5() != 0) {
            tirunt = Decimals.add(Decimals.sub(Decimals.add(lftunt, oldper), request.getPerbegtr5()), 1);
            tirunt = getMinimum(tirunt, lftunt);
            BigDecimal feeamt = Decimals.div(Decimals.mul(relamt, request.getPerrattr5()), basis);
            feeamt = xrtmodService.amtRnd(feeamt, relcur);
            feeamt = Decimals.mul(feeamt, tirunt);
            fecamt = Decimals.add(fecamt, feeamt);
            inftxt += CR + Strings.getText("从第$1段开始使用利率$2,份数为$3,计算费用金额为$4",request.getPerbegtr5(), request.getPerrattr5(), tirunt, feeamt);
            lftunt = Decimals.sub(lftunt, tirunt);
        }
        if (MdaUtils.compareTo(Decimals.add(lftunt, oldper), request.getPerbegtr4()) >= 0 && request.getPerbegtr4() != 0) {
            tirunt = Decimals.add(Decimals.sub(Decimals.add(lftunt, oldper), request.getPerbegtr4()), 1);
            tirunt = getMinimum(tirunt, lftunt);
            BigDecimal feeamt = Decimals.div(Decimals.mul(relamt, request.getPerrattr4()), basis);
            feeamt = xrtmodService.amtRnd(feeamt, relcur);
            feeamt = Decimals.mul(feeamt, tirunt);
            fecamt = Decimals.add(fecamt, feeamt);
            inftxt += CR + Strings.getText("从第$1段开始使用费率$2,单元为$3,计算费用金额为$4",request.getPerbegtr4(), request.getPerrattr4(), tirunt, feeamt);
            lftunt = Decimals.sub(lftunt, tirunt);
        }
        if (MdaUtils.compareTo(Decimals.add(lftunt, oldper), request.getPerbegtr3()) >= 0 && request.getPerbegtr3() != 0) {
            tirunt = Decimals.add(Decimals.sub(Decimals.add(lftunt, oldper), request.getPerbegtr3()), 1);
            tirunt = getMinimum(tirunt, lftunt);
            BigDecimal feeamt = Decimals.div(Decimals.mul(relamt, request.getPerrattr3()), basis);
            feeamt = xrtmodService.amtRnd(feeamt, relcur);
            feeamt = Decimals.mul(feeamt, tirunt);
            fecamt = Decimals.add(fecamt, feeamt);
            inftxt += CR + Strings.getText("从第$1段开始使用费率$2,单元为$3,计算费用金额为$4",request.getPerbegtr3(), request.getPerrattr3(), tirunt, feeamt);
            lftunt = Decimals.sub(lftunt, tirunt);
        }
        if (MdaUtils.compareTo(Decimals.add(lftunt, oldper), request.getPerbegtr2()) >= 0 && request.getPerbegtr2() != 0) {
            tirunt = Decimals.add(Decimals.sub(Decimals.add(lftunt, oldper), request.getPerbegtr2()), 1);
            tirunt = getMinimum(tirunt, lftunt);
            BigDecimal feeamt = Decimals.div(Decimals.mul(relamt, request.getPerrattr2()), basis);
            feeamt = xrtmodService.amtRnd(feeamt, relcur);
            feeamt = Decimals.mul(feeamt, tirunt);
            fecamt = Decimals.add(fecamt, feeamt);
            inftxt += CR + Strings.getText("从第$1段开始使用费率$2,单元为$3,计算费用金额为$4",request.getPerbegtr2(), request.getPerrattr2(), tirunt, feeamt);
            lftunt = Decimals.sub(lftunt, tirunt);
            if (lftunt.compareTo(BigDecimal.ZERO) > 0) {
                feeamt = Decimals.div(Decimals.mul(relamt, ratuse), basis);
                feeamt = xrtmodService.amtRnd(feeamt, relcur);
                feeamt = Decimals.mul(feeamt, lftunt);
                inftxt += CR + Strings.getText("从第1段开始使用费率$1,单元为$2,计算费用金额为$3",ratuse, lftunt, feeamt);
            }
        }
        BigDecimal feeamt = Decimals.div(Decimals.mul(relamt, ratuse), basis);
        feeamt = xrtmodService.amtRnd(feeamt, relcur);
        Argument<String> roundInftxtArg = new Argument<>("", "");
        feeamt = roundAmt(roundInftxtArg, feeamt, request.getRoundFlag());
        if (StringUtils.isNotEmpty(roundInftxtArg.value)) {
            inftxt += CR + roundInftxtArg.value;
        }
        fecamt = Decimals.add(fecamt, feeamt);
        if (MdaUtils.compareTo(relcur, feecur) != 0) {
            //费用牌价取中间价
            Argument<String> inftxtArg = new Argument<>("", "");
            fecamt = fecismService.fecIsmAmtConv(inftxtArg, relcur, fecamt, feecur, Dates.today());
            if (StringUtils.isNotEmpty(inftxtArg.value)) {
                inftxt += CR + inftxtArg.value;
            }
            roundInftxtArg = new Argument<>("", "");
            fecamt = roundAmt(roundInftxtArg, fecamt, request.getRoundFlag());
            if (StringUtils.isNotEmpty(roundInftxtArg.value)) {
                inftxt += CR + roundInftxtArg.value;
            }
        }
        fecamt = Decimals.mul(fecamt, lftunt);
        inftxt += CR + Strings.getText("计算后应收 $1 $2", feecur, Utils.fmtAmount(fecamt, feecur));
        BigDecimal ogiamt = xrtmodService.amtRndUnt(fecamt, feecur);
        BigDecimal amt = xrtmodService.amtRndUnt(Decimals.sub(fecamt, request.getDctamt()), feecur);
        response.setUnt(unt);
        response.setInftxt(inftxt);
        response.setOgiamt(ogiamt);
        response.setCur(feecur);
        response.setAmt(amt);
        response.setDat1(date1);
        response.setDat2(date2);
        compareMaxmin(response, request);
        return response;
    }
}
