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.setmod.vo.CommCbsLine;
import com.brilliance.isc.common.setmod.vo.CommCbsLineGrid;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

@Component("comm_FeeCalculator")
public class CommFeeCalculator extends AbstractFeeCalculator {

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private FecismService fecismService;

    @Override
    protected CalcFeeResponse calculate(CalcFeeRequest request) {
        List<CommCbsLine> lines = request.getCommCbsLines();
        CalcFeeResponse response = new CalcFeeResponse();
        //费用计算细节
        String inftxt = buildInftxt(request);
        if ("1".equals(request.getCalrul())) {
            inftxt += CR + Strings.getText("计费规则是千分率");
        } else {
            inftxt += CR + Strings.getText("计费规则是百分率");
        }
        int unt = request.getUnt();
        String feetxtinf = request.getFeetxtinf();
        if (StringUtils.isEmpty(feetxtinf)) {
            feetxtinf = codetableService.getTblLabel(request.getFeecod(), "FEETXT");
        }
        inftxt += CR + Strings.getText("本次收取$1", feetxtinf);
        Date date1 = request.getDat1();
        Date date2 = null;
        if (request.getDat2() == null || "u".equals(request.getModflg()) || request.getGraceDays() != 0) {
            date2 = Utils.calcDate(date1, unt, request.getPertyp(), "");
        } else {
            unt = Utils.calcUnt(date1, request.getDat2(), request.getPertyp());
            //重新根据unt算日期
            date2 = Utils.calcDate(date1, unt, request.getPertyp(), "");
        }
        if (request.getGraceDays() != 0) {
            date2 = Dates.add(date2, request.getGraceDays());
        }
        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"));
        BigDecimal fecamt = BigDecimal.ZERO;
        BigDecimal ratuse = request.getRatcal();
        BigDecimal basis = new BigDecimal("100");
        if ("1".equals(request.getCalrul())) {
            basis = new BigDecimal("1000");
        }
        //一次性收取
        boolean allColFlag = false;
        if (request.getDat2dft() != null && MdaUtils.compareTo(date2, request.getDat2dft()) >= 0) {
            allColFlag = true;
        }
        List<CommCbsLineGrid> gridList = new ArrayList<>();
        for (CommCbsLine line : lines) {
            //后收
            if (unt == 0) {
                continue;
            }
            if (MdaUtils.compareTo(date1, line.getFeeDate()) < 0 && !allColFlag) {
                continue;
            }
            //发生额计算明细表格
            CommCbsLineGrid commCbsLineGrid = new CommCbsLineGrid();
            commCbsLineGrid.setCur(line.getCur());
            commCbsLineGrid.setAmt(line.getAmt());
            commCbsLineGrid.setValueDate(line.getValueDate());
            commCbsLineGrid.setNote(line.getNote());
            inftxt += CR;
            inftxt += CR + line.getNote();
            BigDecimal feeamt = BigDecimal.ZERO;
            Date fromDate = line.getFeeDate();
            Date toDate = null;
            int relUnt = 0;
            if ("OPEN".equalsIgnoreCase(line.getFlag())) {
                relUnt = unt;
                //开立的收费日期等于起始日期
                fromDate = request.getDat1();
            } else {
                if (allColFlag) {
                    //一次性全收
                    relUnt = Utils.calcUnt(line.getFeeDate(), request.getDat2dft(), request.getPertyp());
                } else {
                    relUnt = Utils.calcUnt(line.getFeeDate(), date2, request.getPertyp());
                }
            }
            if (relUnt == 0) {
                continue;
            }
            toDate = Utils.calcDate(fromDate, relUnt, request.getPertyp(), "");
            if (request.getDat2dft() != null && MdaUtils.compareTo(toDate, request.getDat2dft()) > 0) {
                toDate = request.getDat2dft();
            }
            inftxt += CR + Strings.getText("收取$1单元，计费周期$2到$3", relUnt, Utils.fmtDate(fromDate, "yyyy-MM-dd"), Utils.fmtDate(toDate, "yyyy-MM-dd"));
            feeamt = Decimals.div(Decimals.mul(line.getAmt(), ratuse), basis);
            feeamt = xrtmodService.amtRnd(feeamt, line.getCur());
            Argument<String> roundInftxtArg = new Argument<>("", "");
            feeamt = roundAmt(roundInftxtArg, feeamt, request.getRoundFlag());
            if (StringUtils.isNotEmpty(roundInftxtArg.value)) {
                inftxt += CR + roundInftxtArg.value;
            }
            feeamt = Decimals.mul(feeamt, relUnt);
            inftxt += CR + Strings.getText("计算后应收 $1 $2", line.getCur(), Utils.fmtAmount(feeamt, line.getCur()));
            commCbsLineGrid.setFeecur(line.getCur());
            commCbsLineGrid.setFeeamt(feeamt);
            commCbsLineGrid.setDat1(fromDate);
            commCbsLineGrid.setDat2(toDate);
            gridList.add(commCbsLineGrid);
            fecamt = Decimals.add(fecamt, feeamt);
        }
        String feecur = request.getFeecur();
        String relcur = request.getRelcur();
        inftxt += CR;
        inftxt += CR + Strings.getText("计算之和应收 $1 $2", request.getRelcur(), Utils.fmtAmount(xrtmodService.amtRnd(fecamt, request.getRelcur()), request.getRelcur()));
        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;
            }
            Argument<String> roundInftxtArg = new Argument<>("", "");
            fecamt = roundAmt(roundInftxtArg, fecamt, request.getRoundFlag());
            if (StringUtils.isNotEmpty(roundInftxtArg.value)) {
                inftxt += CR + roundInftxtArg.value;
            }
        }
        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);
        response.setCommCbsLineGrids(gridList);
        compareMaxmin(response, request);
        return response;
    }
}
