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


import com.brilliance.isc.bo.Fcd;
import com.brilliance.isc.bo.Pty;
import com.brilliance.isc.common.api.liaccv.service.LiaccvApiService;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.component.ActmodComponent;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.liaccv.vo.LiaccvAcctVo;
import com.brilliance.isc.common.liaccv.vo.LiaccvVo;
import com.brilliance.isc.common.liaccv.vo.LiaccvgVo;
import com.brilliance.isc.common.transaction.newcheck.AbstractModuleValidator;
import com.brilliance.isc.common.transaction.newcheck.ValidResult;
import com.brilliance.isc.common.transaction.newcheck.Validate;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.mda.dao.FcdMapper;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Component
public class LiaccvgValidator extends AbstractModuleValidator<LiaccvgVo> {

    @Autowired
    private ActmodComponent actmodComponent;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private FcdMapper fcdMapper;

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private LiaccvApiService liaccvApiService;

    @Autowired
    private PtyCacheService ptyCacheService;

    @Validate(path="liaccv.liaccvg.%s.acc")
    public ValidResult checkAccN1000(LiaccvgVo liaccvgVo){
        if( ! MdaUtils.isEmpty(liaccvgVo.getAmt()) && MdaUtils.isEmpty(liaccvgVo.getAcc()) ) {
            return ValidResult.build(false, "This field is mandatory");
        }
        String trmCod = "";
        if( MdaUtils.compareTo(SettleContext.getUserSession().getAtp().getBus(),"LI") == 0
                || MdaUtils.compareTo(SettleContext.getUserSession().getAtp().getBus(),"BR") == 0 ) {
            trmCod = "CC-TT0";
        } else {
            trmCod = "CC-TT2";
        }
        String err = "";
        if( ! MdaUtils.isEmpty(liaccvgVo.getAcc()) ) {
            if( Strings.len(liaccvgVo.getAcc()) == 13 && SettleContext.getTransName().endsWith("ENG")) {
                return null;
            } else {
                Argument<String> errBox = new Argument<String>();
                if( MdaUtils.compareTo(Strings.mid(liaccvgVo.getAcc(),7,4),"2120") != 0
                        && MdaUtils.compareTo(Strings.mid(liaccvgVo.getAcc(),7,4),"2149") != 0
                        && !SettleContext.getTransName().endsWith("CAN")
                        && !actmodComponent.checkAccount(liaccvgVo.getAcc(),trmCod,SettleContext.getUserSession().getBch().getBranch(),liaccvgVo.getCur(),"N",errBox) ) {
                    return ValidResult.build(false, errBox.value);
                }
            }
        }
        return null;
    }

    @Validate(path="liaccv.liaccvg.%s.acc")
    public ValidResult checkAccN1100(LiaccvgVo liaccvgVo){
        String transName = SettleContext.getTransName();
        //检核ADD进来的保证金信息中的客户号与当前申请人客户号是否一致
        if ("GITPOP|GITOPN|GITPAM|GITAME|NITPOP|NITOPN|NITPAM|NITAME|HITPOP|HITOPN|HITPAM|HITAME|".indexOf(transName) == -1) {
            return null;
        }
        if(!MdaUtils.isEmpty(liaccvgVo.getAcc())) {
            LiaccvVo liaccvVo = (LiaccvVo) getParent();
            PtsptaVo ptsptaVo = ptsptaToolComponent.getMainPtspta(transName, liaccvVo.getRec(), liaccvVo.getPtsList());
            String aplptyinr = "";
            if (ptsptaVo != null) {
                aplptyinr = ptsptaVo.getPtyinr();
                if (StringUtils.isEmpty(aplptyinr)) {
                    aplptyinr = ptsptaVo.getPts().getPtyinr();
                }
            }
            if (StringUtils.isNotEmpty(aplptyinr)) {
                Fcd fcd = null;
                if (StringUtils.isNotEmpty(liaccvgVo.getFcdinr())) {
                    fcd = fcdMapper.getFcdByInr(liaccvgVo.getFcdinr());
                } else if (StringUtils.isNotEmpty(liaccvgVo.getOwnref())) {
                    fcd = fcdMapper.getFcdByOwnref(liaccvgVo.getOwnref());
                }
                if (fcd != null && !aplptyinr.equals(fcd.getAplptyinr())) {
                    String errtxt = "保证金信息中的客户号与当前申请人客户号不一致，请重新Add!";
                    return ValidResult.build(false, errtxt);
                }
            }
        }
        return null;
    }

    @Validate(path="liaccv.liaccvg.%s.acc")
    public ValidResult checkAccExtkey(LiaccvgVo liaccvgVo) {
        String transName = SettleContext.getTransName();
        //保证金调整业务需要校验新加的条目账号是不是属于该客户
        if (StringUtils.isNotEmpty(liaccvgVo.getAcc()) && "Y".equalsIgnoreCase(liaccvgVo.getCcdflgbut())) {
            LiaccvVo liaccvVo = (LiaccvVo) getParent();
            PtsptaVo ptsptaVo = ptsptaToolComponent.getMainPtspta(transName, liaccvVo.getRec(), liaccvVo.getPtsList());
            Pty pty = ptyCacheService.getPtyById(ptsptaVo.getPtyinr());
            String rolExtkey = "";
            if (pty != null) {
                rolExtkey = pty.getExtkey();
            }
            if (ptsptaVo != null && "GITENG|NITENG".indexOf(transName) > -1) {
                if (liaccvgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0 && liaccvgVo.getAmt().compareTo(BigDecimal.ZERO) != 0) {
                    //表示新加入的条目 需要校验账号是不是属于该客户
                    LiaccvAcctVo liaccvAcctVo = liaccvApiService.getLiaccvAccountInfo(liaccvgVo.getAcc());
                    if (liaccvAcctVo != null) {
                        if (StringUtils.isNotEmpty(liaccvAcctVo.getErrorMsg())) {
                            return ValidResult.build(false, liaccvAcctVo.getErrorMsg());
                        } else if (!rolExtkey.equals(liaccvAcctVo.getKehhao())) {
                            return ValidResult.build(false, "此账号不属于该客户，请重新选择");
                        }
                    }
                }
            }
        }
        return null;
    }

    @Validate(path="liaccv.liaccvg.%s.amt")
    public ValidResult checkAmtN1000(LiaccvgVo liaccvgVo){
        if(liaccvgVo.getAmt().negate().compareTo(liaccvgVo.getOldamt()) > 0 ){
            return ValidResult.build(false, Strings.formatText("You may use the old amount of $1 $2 maximum ",liaccvgVo.getCur(), Utils.fmtAmount(liaccvgVo.getOldamt(),liaccvgVo.getCur())));
        }
        return null;
    }

    @Validate(path="liaccv.liaccvg.%s.amt")
    public ValidResult checkAmtN1001(LiaccvgVo liaccvgVo){
        LiaccvVo liaccvVo = (LiaccvVo) getParent();
        if( ! MdaUtils.isEmpty(liaccvgVo.getAmt())
                && ! MdaUtils.isEmpty(liaccvVo.getChgcurflg())
                && MdaUtils.compareTo(liaccvgVo.getCur(),liaccvgVo.getConcur()) != 0
                && ! MdaUtils.isEmpty(liaccvgVo.getOldamt()) ) {
            String refcur = "";
            String refcur1 = "";
            String refcur2 = "";
            BigDecimal refamt = new BigDecimal("0.00");
            BigDecimal rate = new BigDecimal("0.000000");
            BigDecimal sqrrat = new BigDecimal("0.000000");
            Argument<String> refcur1Box = new Argument<String>("",refcur1);
            Argument<String> refcur2Box = new Argument<String>("",refcur2);
            Argument<String> refcurBox = new Argument<String>("",refcur);
            Argument<Boolean> ininflgBox = new Argument<Boolean>();
            xrtmodService.xrtCheckInIn( liaccvgVo.getConcur(), liaccvgVo.getCur(), refcur1Box, refcur2Box, refcurBox, ininflgBox );

            refcur1 = refcur1Box.value;
            refcur2 = refcur2Box.value;
            refcur = refcurBox.value;
            Boolean ininflg = ininflgBox.value;

            if( MdaUtils.compareTo(Strings.mid(SettleContext.getUserSession().getAtp().getCod(),1,2),"JS") == 0
                    || MdaUtils.compareTo(Strings.mid(SettleContext.getUserSession().getAtp().getCod(),1,2),"WI") == 0 ) {
                Argument<BigDecimal> rateBox = new Argument<BigDecimal>("",rate);
                Argument<BigDecimal> sqrratBox = new Argument<BigDecimal>("",sqrrat);
                xrtmodService.getRateXrt( liaccvgVo.getConcur(), xrtmodService.sysiso(), ininflg, "M", Dates.dateAddW(Dates.today(),-1,xrtmodService.calendar()), rateBox, sqrratBox );

                rate = rateBox.value;
                sqrrat = sqrratBox.value;

            } else {
                Argument<BigDecimal> rateBox1 = new Argument<BigDecimal>("",rate);
                Argument<BigDecimal> sqrratBox1 = new Argument<BigDecimal>("",sqrrat);
                xrtmodService.getRateXrt( liaccvgVo.getConcur(), xrtmodService.sysiso(), ininflg, "B", Dates.today(), rateBox1, sqrratBox1 );

                rate = rateBox1.value;
                sqrrat = sqrratBox1.value;

            }
            if( MdaUtils.compareTo(liaccvgVo.getRat(),0) > 0 ) {
                if( MdaUtils.compareTo(rate,1)>0 ) {
                    rate = liaccvgVo.getRat();
                } else {
                    rate = Decimals.div(1,liaccvgVo.getRat());
                }
            }
            Argument<String> refcurBox1 = new Argument<String>("",refcur);
            Argument<BigDecimal> refamtBox = new Argument<BigDecimal>("",refamt);
            BigDecimal amt = xrtmodService.amtConvRates( liaccvgVo.getAcccovamt(), rate, new BigDecimal(Double.toString(1.00)), liaccvgVo.getConcur(), liaccvgVo.getCur(), refcurBox1, refamtBox );

            refcur = refcurBox1.value;
            refamt = refamtBox.value;

            if( MdaUtils.compareTo(amt,liaccvgVo.getAmt()) != 0 ) {
                return ValidResult.build(false,Strings.formatText("外币与本币数经过折算差$1",Decimals.sub(amt,liaccvgVo.getAmt())));
            }
        }
        return null;
    }

    @Validate(path = "liaccv.liaccvg.%s.ccvid")
    public ValidResult checkCcvid(LiaccvgVo liaccvgVo){
        int cnt = 0;
        LiaccvVo liaccvVo = (LiaccvVo) getParent();
        for(int i = 0; i < liaccvVo.getLiaccvg().size();i++) {
            if( MdaUtils.compareTo(liaccvVo.getLiaccvg().get(i).getCcvid(), liaccvgVo.getCcvid()) == 0 && MdaUtils.compareTo(liaccvVo.getLiaccvg().get(i).getRole(),liaccvgVo.getRole()) == 0 && MdaUtils.compareTo(liaccvVo.getLiaccvg().get(i).getAmt(),0) != 0 ) {
                cnt = cnt + 1;
            }
        }
        if(cnt > 1) {
            return ValidResult.build(false,Strings.formatText("Id $1 can only be used for one line. Please use different ids ",liaccvgVo.getCcvid()));
        }
        return null;
    }

    @Validate(path = "liaccv.liaccvg.%s.amt")
    public ValidResult checkChkavb(LiaccvgVo liaccvgVo){
        if( MdaUtils.compareTo(liaccvgVo.getAmt(),liaccvgVo.getFcdavbamt()) > 0
                && ( ! MdaUtils.isEmpty(liaccvgVo.getFcdinr()) ) ) {
            return ValidResult.build(false,Strings.formatText("You may only use the available amount $1 $2 of the forward contract",liaccvgVo.getCur(),Utils.fmtAmount(liaccvgVo.getFcdavbamt(),liaccvgVo.getCur())));
        }
        return null;
    }

    @Validate(path = "liaccv.liaccvg.%s.ownref")
    public ValidResult checkFcdinr(LiaccvgVo liaccvgVo){
        if( ! MdaUtils.isEmpty(liaccvgVo.getFcdinr()) ) {
            int cnt = 0;
            LiaccvVo liaccvVo = (LiaccvVo) getParent();
            for(int i=0; i<liaccvVo.getLiaccvg().size(); i++) {
                if( MdaUtils.compareTo(liaccvVo.getLiaccvg().get(i).getFcdinr(),liaccvgVo.getFcdinr()) == 0 ) {
                    cnt = cnt + 1;
                }
            }
            if( cnt > 1 ) {
                return ValidResult.build(false,"You may use each forward contract in one line only");
            }
        }
        return null;
    }

    @Validate(path="liaccv.liaccvg.%s.ownref")
    public ValidResult checkFcdOwnRef(LiaccvgVo liaccvgVo) {
        if (liaccvgVo.getAmt().compareTo(BigDecimal.ZERO) != 0
            && liaccvgVo.getOldamt().compareTo(BigDecimal.ZERO) == 0
            && StringUtils.isNotEmpty(liaccvgVo.getFcdinr())) {
            Fcd fcd = fcdMapper.getFcdByInr(liaccvgVo.getFcdinr());
            if (fcd != null && (!"U".equalsIgnoreCase(fcd.getUseflg()) || !"Y".equalsIgnoreCase(fcd.getRelflg()))) {
                return ValidResult.build(false, getMessage("0209", null));
            }
        }
        return null;
    }

}
