package com.brilliance.isc.common.transaction.newcheck.liaall;

import com.brilliance.isc.bo.Act;
import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Oit;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.liaall.service.LiaallService;
import com.brilliance.isc.common.liaall.vo.LiaallVo;
import com.brilliance.isc.common.liaallg.vo.LiaallgVo;
import com.brilliance.isc.common.liaone.service.LiaoneService;
import com.brilliance.isc.common.oit.service.OitService;
import com.brilliance.isc.common.transaction.newcheck.*;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.mda.runtime.mda.util.Dates;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Component
public class LiaallgValidator extends AbstractModuleValidator<LiaallgVo> {

    private static Logger log = LoggerFactory.getLogger(LiaallgValidator.class);

    @Autowired
    private LiaallService liaallService;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private LiaoneService liaoneService;

    @Autowired(required = false)
    private OitService oitService;

    @Validate(path="liaall.liaallg.%s.acc")
    public  ValidResult checkAccN980(LiaallgVo liaallgVo){
        if(Strings.mid(liaallgVo.getAcc(),1,2).compareTo("*E") == 0){
            return ValidResult.build(false,"No account found in database.\nPlease add account to database first.");
        }
        return null;
    }

    @Validate(path="liaall.liaallg.%s.acc")
    public  ValidResult checkAccN1200(LiaallgVo liaallgVo){
        if(MdaUtils.compareTo(liaoneService.getLiaTermKey("AS",liaallgVo.getAcplia()),"") != 0) {
            if( MdaUtils.isEmpty(liaallgVo.getAcc())
                    && ( MdaUtils.compareTo(liaallgVo.getAmt(),0) != 0
                    || MdaUtils.compareTo(liaallgVo.getOldamt(),0) != 0 ) ) {
                return ValidResult.build(false, getMessage("0126", null));
            }
            //萧山模式 杭州业务选出萧山或有时给出提示
            String accbch = "";
            if( Strings.len(liaallgVo.getAcc()) == 17 ) {
                accbch = Strings.mid(liaallgVo.getAcc(),1,4);
            } else {
                if( Strings.len(liaallgVo.getAcc()) == 21 ) {
                    accbch = Strings.mid(liaallgVo.getAcc(),3,4);
                }
            }
            Bch bch = SettleContext.getUserSession().getBch();
            if( MdaUtils.compareTo(accbch, bch.getBranch()) != 0
                    && MdaUtils.compareTo(bch.getBchtyp(),"3") != 0
                    && MdaUtils.compareTo(bch.getBchtyp(),"4") != 0
                    && MdaUtils.compareTo(bch.getBchtyp(),"5") != 0 ) {
                return ValidResult.build(false,"或有账号机构与当前机构不一致!");
            }
        }
        return null;
    }

    @Validate(path = "liaall.liaallg.%s.acc2")
    public ValidResult checkAcc2(LiaallgVo liaallgVo){
        if(Strings.mid(liaallgVo.getAcc2(),1,2).compareTo("*E") == 0 ){
            return ValidResult.build(false, Strings.formatText(" No account found in database.\\nPlease add account to database first."));
        }
        return null;
    }

    @Validate(path="liaall.liaallg.%s.amt")
    public ValidResult checkAmt(LiaallgVo liaallgVo){
        if(liaallgVo.getAmt().add(liaallgVo.getOldamt()).compareTo(BigDecimal.ZERO) < 0 ){
          return ValidResult.build(false,Strings.formatText("A negative balance is not allowed.\nYou may revert a maximum of $1 $2 in this line", liaallgVo.getCur(), Utils.fmtAmount(liaallgVo.getOldamt(),liaallgVo.getCur())));
        }
        if(!Strings.isEmpty(liaallgVo.getRol())
                && (liaallgVo.getAmt().add(liaallgVo.getOldamt()).compareTo(BigDecimal.ZERO) ==  0 )
                && liaallService.liaallParFound("ALLAMT", "")
                && liaallgVo.getOldflg().compareTo("C") != 0){
            LiaallVo liaallVo = (LiaallVo)getParent();
            BigDecimal relamt = liaallService.getnewamtSumToLine(liaallVo,liaallgVo);
            BigDecimal oldamt = liaallService.getOldamtSumToLine(liaallVo,liaallgVo);
            if(oldamt.add(relamt).compareTo(BigDecimal.ZERO) > 0 ){
                return ValidResult.build(false,Strings.formatText("Please assign an amount to $1",liaallgVo.getNam()));
            }
        }
        return null;
    }

    @Validate(path="liaall.liaallg.%s.fec.minamt")
    public  ValidResult checkMinamt(LiaallgVo liaallgVo){
        if(Strings.isEmpty(liaallgVo.getFec().getMinamt())){
            if(liaallgVo.getFec().getSetchgflg().compareTo("MM") == 0 ||liaallgVo.getFec().getSetchgflg().compareTo("MO") == 0){
                return errorMandatory();
            }
        }
        return null;
    }

    @Validate(path="liaall.liaallg.%s.fec.ratcal")
    public  ValidResult checkRatcal(LiaallgVo liaallgVo){
        if(Strings.isEmpty(liaallgVo.getFec().getRatcal())){
            if(liaallgVo.getFec().getSetchgflg().compareTo("RM") == 0 ||liaallgVo.getFec().getSetchgflg().compareTo("BM") == 0){
                return errorMandatory();
            }
        }
        return null;
    }


    @Validate(path="liaall.liaallg.%s.fec.setperflg")
    public  ValidResult checkSetperflg(LiaallgVo liaallgVo){
        if(liaallgVo.getFec().getCalrul().compareTo("C") == 0 && Strings.isEmpty(liaallgVo.getFec().getSetperflg())){
            return errorMandatory();
        }
        return null;
    }

    @Validate(path="liaall.liaallg.%s.matdat", enable = "N")
    public  ValidResult checkMatdatN1000(LiaallgVo liaallgVo){
        if(!liaallService.liaallCBTPFXIsBalance(liaallgVo.getCbtpfx()) && Strings.isEmpty(liaallgVo.getMatdat()) && (Strings.notEmpty(liaallgVo.getAmt()) || Strings.notEmpty(liaallgVo.getOldamt()))){
            return errorMandatory();
        }
        return null;
    }

    @Validate(path="liaall.liaallg.%s.rol")
    public  ValidResult checkRol(LiaallgVo liaallgVo){
        if(Strings.isEmpty(liaallgVo.getLiaptyinr()) && liaallgVo.getAmt().compareTo(BigDecimal.ZERO) != 0){
            return ValidResult.build(false,Strings.formatText("$1不是数据库中的参与方，因此无法存储预订金额",liaallgVo.getRol()));
        }
        return null;
    }



    /**
     *   source:fecp1.0000.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.mincur")
    public ValidResult checkFecMincur(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getMincur()) ) {
            if(!xrtmodService.isCurrencyValid(liaallgVo.getFec().getMincur())) {
                return ValidResult.build(false, "The selected currency is invalid");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0001.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.permaxtr2")
    public ValidResult checkFecPermaxtr2(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getPermaxtr2()) ) {
            if( MdaUtils.compareTo(liaallgVo.getFec().getPermintr2(), liaallgVo.getFec().getPermaxtr2())>0 ) {
                return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0002.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.permaxtr3")
    public ValidResult checkFecPermaxtr3(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getPermaxtr3())) {
            if(MdaUtils.compareTo(liaallgVo.getFec().getPermintr3(), liaallgVo.getFec().getPermaxtr3()) > 0) {
                return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0003.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.permaxtr4")
    public ValidResult checkFecPermaxtr4(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getPermaxtr4()) ) {
            if(MdaUtils.compareTo(liaallgVo.getFec().getPermintr4(), liaallgVo.getFec().getPermaxtr4()) > 0) {
                return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0004.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.permaxtr5")
    public ValidResult checkFecPermaxtr5(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getPermaxtr5()) ) {
            if( MdaUtils.compareTo(liaallgVo.getFec().getPermintr5(), liaallgVo.getFec().getPermaxtr5())>0 ) {
                return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0005.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.permaxtr6")
    public ValidResult checkFecPermaxtr6(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getPermaxtr6()) ) {
            if( MdaUtils.compareTo(liaallgVo.getFec().getPermintr6(), liaallgVo.getFec().getPermaxtr6())>0 ) {
                return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0006.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.permaxtr7")
    public ValidResult checkFecPermaxtr7(LiaallgVo liaallgVo){
                    if(!MdaUtils.isEmpty(liaallgVo.getFec().getPermaxtr7()) ) {
                        if( MdaUtils.compareTo(liaallgVo.getFec().getPermintr7(), liaallgVo.getFec().getPermaxtr7()) > 0 ) {
                            return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0007.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.ratcur")
    public ValidResult checkFecRatcur(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getRatcur())) {
            if(!xrtmodService.isCurrencyValid(liaallgVo.getFec().getRatcur())) {
                return ValidResult.build(false, "The selected currency is invalid");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0008.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.maxamt")
    public ValidResult checkFecMaxamt(LiaallgVo liaallgVo){
        if(MdaUtils.compareTo(liaallgVo.getFec().getMinfcc(), "S") == 0
                && MdaUtils.compareTo(liaallgVo.getFec().getMaxfcc(),"S") == 0) {
            if( ! MdaUtils.isEmpty(liaallgVo.getFec().getMaxamt()) ) {
                if( MdaUtils.compareTo(liaallgVo.getFec().getMaxamt(), liaallgVo.getFec().getMinamt()) < 0 ) {
                    return ValidResult.build(false, "Maximum amount cannot be less than the minimum amount.");
                }
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0009.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.maxcur")
    public ValidResult checkFecMaxcur(LiaallgVo liaallgVo){
        if(!MdaUtils.isEmpty(liaallgVo.getFec().getMaxcur())) {
            if(!xrtmodService.isCurrencyValid(liaallgVo.getFec().getMaxcur())) {
                return ValidResult.build(false, "The selected currency is invalid");
            }
        }
        return null;
    }

    /**
     *   source:fecp1.0012.script
     */
    @Validate(path = "liaall.liaallg.%s.fec.pertyp")
    public ValidResult checkFecPertyp(LiaallgVo liaallgVo){
        if((MdaUtils.compareTo(liaallgVo.getFec().getCalrul(),"1") == 0
                || MdaUtils.compareTo(liaallgVo.getFec().getCalrul(),"4") == 0
                || MdaUtils.compareTo(liaallgVo.getFec().getCalrul(),"%") == 0)
                && MdaUtils.compareTo(liaallgVo.getFec().getRatfcc(),"S") == 0) {
            if( MdaUtils.isEmpty(liaallgVo.getFec().getPertyp()) ) {
                return ValidResult.build(false, "You must select a period type for per mille fees");
            }
        }
        return null;
    }

    @Warning(path = "liaall.liaallg.%s.matdat")
    public WarningResult checkMatdatN2000(LiaallgVo liaallgVo) {
        if (liaallgVo.getMatdat() != null) {
            if (Dates.diff(liaallgVo.getMatdat(), Dates.today()) < 0) {
                return WarningResult.build("MATDATPASWRN", getMessage("0135", Utils.fmtDate(liaallgVo.getMatdat())));
            }
        }
        return WarningResult.buildEmpty("MATDATPASWRN");
    }

    @Validate(path = "liaall.liaallg.%s.acc")
    public ValidResult checkAccForOit(LiaallgVo liaallgVo) {
        Act act  = liaallgVo.getAcplia().getActrec();
        if (act != null && StringUtils.isNotEmpty(act.getInr())) {
            Map<String, List<Oit>> maps = oitService.filterOit(act.getInr(), "ACT");
            if (maps != null && maps.containsKey("ERROR")) {
                List<Oit> errorOits = maps.get("ERROR");
                String message = getMessage("0217", null);
                for (int i=0; i<errorOits.size(); i++) {
                    if (i == 0) {
                        message += errorOits.get(i).getInftxt();
                    } else {
                        message += "\r\n" + errorOits.get(i).getInftxt();
                    }
                }
                return ValidResult.build(false, message);
            }
        }
        return null;
    }

    @Warning(path = "liaall.liaallg.%s.acc")
    public WarningResult warningAccForOit(LiaallgVo liaallgVo) {
        Act act  = liaallgVo.getAcplia().getActrec();
        if (act != null && StringUtils.isNotEmpty(act.getInr())) {
            Map<String, List<Oit>> maps = oitService.filterOit(act.getInr(), "ACT");
            if (maps != null && !maps.containsKey("ERROR") && maps.containsKey("WARN")) {
                List<Oit> warnOits = maps.get("WARN");
                String title = getMessage("0220", act.getExtkey());
                String message = getMessage("0218", title);
                for (int i=0; i<warnOits.size(); i++) {
                    if (i == 0) {
                        message += warnOits.get(i).getInftxt();
                    } else {
                        message += "\r\n" + warnOits.get(i).getInftxt();
                    }
                }
                return WarningResult.build("liaallgAccountWarning", message);
            }
        }
        return WarningResult.buildEmpty("liaallgAccountWarning");
    }

    @Warning(path = "liaall.liaallg.%s.acc", level = "3")
    public WarningResult infoAccForOit(LiaallgVo liaallgVo) {
        Act act  = liaallgVo.getAcplia().getActrec();
        if (act != null && StringUtils.isNotEmpty(act.getInr())) {
            Map<String, List<Oit>> maps = oitService.filterOit(act.getInr(), "ACT");
            if (maps != null && !maps.containsKey("ERROR") && maps.containsKey("INFO")) {
                List<Oit> warnOits = maps.get("INFO");
                String title = getMessage("0220", act.getExtkey());
                String message = getMessage("0219", title);
                for (int i=0; i<warnOits.size(); i++) {
                    if (i == 0) {
                        message += warnOits.get(i).getInftxt();
                    } else {
                        message += "\r\n" + warnOits.get(i).getInftxt();
                    }
                }
                return WarningResult.build("liaallgAccountInfo", message);
            }
        }
        return WarningResult.buildEmpty("liaallgAccountInfo");
    }



}
