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

import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Cty;
import com.brilliance.isc.bo.Oit;
import com.brilliance.isc.bo.model.Trdgrp;
import com.brilliance.isc.bo.model.Trtp;
import com.brilliance.isc.common.context.SettleContext;
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.isc.mda.dao.CtyMapper;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.brilliance.mda.runtime.mda.Constants.PanStaAdd;
import static com.brilliance.mda.runtime.mda.Constants.PanStaEdit;

@Component
public class TrtpValidator extends AbstractModuleValidator<Trtp> {

    @Autowired
    private OitService oitService;

    @Autowired
    private CtyMapper ctyMapper;

    @Autowired
    private WbpcreValidator wbpcreValidator;

    @Override
    @PostConstruct
    public void register() {
        super.register();
    }

    @Override
    public Map<String, String> validate(Trtp vo) {
        Map<String, String> maps = new HashMap<>();
        maps.putAll(super.validate(vo));
        maps.putAll(wbpcreValidator.validate(vo.getWbdp()));
        return maps;
    }

    /**
     *   source:trtp.0011.script
     */
    @Validate(path = "trdgrp.rec.stttendat")
    public ValidResult checkTrdgrpRecStttendatN900(Trtp trtpVo){
        Trdgrp trdgrpVo = (Trdgrp)getParent();;
        if(MdaUtils.isEmpty(trdgrpVo.getRec().getStttendat())) {
            return errorMandatory();
        } else {
            if(trdgrpVo.getRec().getMatdat() != null && Dates.diff(trdgrpVo.getRec().getStttendat(), trdgrpVo.getRec().getMatdat()) > 0) {
                return ValidResult.build(false, "The Start Date cannot be after Due Date");
            }
        }
        return null;
    }

    /**
     *   source:trtp.0018.script
     */
    @Validate(path = "trdgrp.cbs.max.amt")
    public ValidResult checkTrdgrpCbsMaxAmtN900(Trtp trtpVo){
        Trdgrp trdgrpVo = (Trdgrp)getParent();;
        if(MdaUtils.isEmpty(trdgrpVo.getCbs().getMax().getAmt())) {
            return errorMandatory();
        } else {
            if(!MdaUtils.isEmpty(trdgrpVo.getRelpntamt()) && MdaUtils.compareTo(trdgrpVo.getCbs().getMax().getAmt(), trdgrpVo.getRelpntamt()) > 0) {
                return ValidResult.build(false, Strings.getText("You cannot finance more than $1 $2.", trdgrpVo.getCbs().getMax().getCur(), Utils.fmtAmount(trdgrpVo.getRelpntamt(), trdgrpVo.getCbs().getMax().getCur())));
            } else {
                if(MdaUtils.compareTo(trdgrpVo.getCbs().getMax().getAmt(), 0) < 0) {
                    return ValidResult.build(false, "Advanced Amount must be positive");
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0020.script
     */
    @Validate(path = "trdgrp.rec.stacty")
    public ValidResult checkTrdgrpRecStactyN1000(Trtp trtpVo){
        if (MdaUtils.compareTo(trtpVo.getPansta(),PanStaAdd) == 0 || MdaUtils.compareTo(trtpVo.getPansta(),PanStaEdit) == 0) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            String stacty = trdgrpVo.getRec().getStacty();
            Cty cty = ctyMapper.selectByCod(stacty);
            if (cty != null) {
                Map<String, List<Oit>> maps = oitService.filterOit(cty.getInr(), "CTY");
                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 = "trdgrp.rec.stacty")
    public WarningResult warningResultTrdgrpRecStacty(Trtp trtpVo){
        if (MdaUtils.compareTo(trtpVo.getPansta(),PanStaAdd) == 0 || MdaUtils.compareTo(trtpVo.getPansta(),PanStaEdit) == 0) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            String stacty = trdgrpVo.getRec().getStacty();
            Cty cty = ctyMapper.selectByCod(stacty);
            if (cty != null) {
                Map<String, List<Oit>> maps = oitService.filterOit(cty.getInr(), "CTY");
                if (maps != null && !maps.containsKey("ERROR") && maps.containsKey("WARN")) {
                    List<Oit> warnOits = maps.get("WARN");
                    String title = getMessage("0221", stacty);
                    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("TrdgrpStactyWarning", message);
                }
            }
        }
        return WarningResult.buildEmpty("TrdgrpStactyWarning");
    }

    @Warning(path = "trdgrp.rec.stacty", level = "3")
    public WarningResult infoResultTrdgrpRecStacty(Trtp trtpVo){
        if (MdaUtils.compareTo(trtpVo.getPansta(),PanStaAdd) == 0 || MdaUtils.compareTo(trtpVo.getPansta(),PanStaEdit) == 0) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            String stacty = trdgrpVo.getRec().getStacty();
            Cty cty = ctyMapper.selectByCod(stacty);
            if (cty != null) {
                Map<String, List<Oit>> maps = oitService.filterOit(cty.getInr(), "CTY");
                if (maps != null && !maps.containsKey("ERROR") && maps.containsKey("INFO")) {
                    List<Oit> warnOits = maps.get("INFO");
                    String title = getMessage("0221", stacty);
                    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("TrdgrpStactyInfo", message);
                }
            }
        }
        return WarningResult.buildEmpty("TrdgrpStactyInfo");
    }

    /**
     *   source:trtp.0024.script
     */
    @Validate(path = "trdgrp.ose.pts.extkey")
    public ValidResult checkTrdgrpOsePtsExtkeyN1000(Trtp trtpVo){
        String framename = SettleContext.getDirectTransName();
        switch(framename) {
            case "TRTOPN":
            case  "TRTADD":
            case  "BCTSET":
            case  "BRTSET":
                Trdgrp trdgrpVo = (Trdgrp) getParent();
                if(MdaUtils.isEmpty(trdgrpVo.getOse().getPts().getExtkey()) && MdaUtils.compareTo(trdgrpVo.getRec().getOseflg(),"X") == 0 ) {
                    return errorMandatory();
                }
                break;
        }
        return null;
    }

    /**
     *   source:trtp.0027.script
     */
    @Validate(path = "trdgrp.rec.oseday")
    public ValidResult checkTrdgrpRecOsedayN1000(Trtp trtpVo){
        Trdgrp trdgrpVo = (Trdgrp) getParent();
        String frm = SettleContext.getTransName();
        if(!MdaUtils.isEmpty(trdgrpVo.getRec().getOseflg()) && MdaUtils.compareTo(Strings.mid(frm,1,3),"INF") != 0) {
            if(MdaUtils.isEmpty(trdgrpVo.getRec().getOseday())) {
                return errorMandatory();
            }
        }
        return null;
    }

    /**
     *   source:trtp.0029.script
     */
    @Validate(path = "trdgrp.rec.stagod")
    public ValidResult checkTrdgrpRecStagodN1000(Trtp trtpVo){
        //!检验规则：
        //!==========================================================
        //!涉及范围：进口信用证押汇，进口代收押汇，汇出汇款押汇情况下，
        //!商品分类"Goods Code"栏位为必输项。
        //!==========================================================
        String trnnam = SettleContext.getDirectTransName();
        String crefinflg = trtpVo.getCrefinflg();
        Trdgrp trdgrpVo = (Trdgrp) getParent();
        if((MdaUtils.compareTo(trnnam,"BRTSET") == 0 || MdaUtils.compareTo(trnnam,"BCTSET") == 0 || MdaUtils.compareTo(trnnam,"CPTOPN") == 0 || MdaUtils.compareTo(trnnam,"CPTATO") == 0) && ! MdaUtils.isEmpty(crefinflg)) {
            if( MdaUtils.isEmpty(trdgrpVo.getRec().getStagod()) ) {
                return errorMandatory();
            }
        } else {
            if(MdaUtils.compareTo(trnnam,"TRTOPN") == 0 || MdaUtils.compareTo(trnnam,"TRTADD") == 0) {
                if( MdaUtils.isEmpty(trdgrpVo.getRec().getStagod()) ) {
                    return errorMandatory();
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0034.script
     */
    @Validate(path = "trdgrp.rec.recaccount")
    public ValidResult checkTrdgrpRecRecaccountN1000(Trtp trtpVo){
        String finflg = trtpVo.getCrefinflg();
        if(MdaUtils.compareTo(SettleContext.getDirectTransName(),"TRTOPN") == 0 || ( ( MdaUtils.compareTo(SettleContext.getDirectTransName(),"BRTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BCTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BDTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTOPN") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTATO") == 0 ) && !MdaUtils.isEmpty(finflg))) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            if( MdaUtils.compareTo(trdgrpVo.getRec().getFlowflag(),"1") == 0 ) {
                if(MdaUtils.isEmpty(trdgrpVo.getRec().getRecaccount())) {
                    return errorMandatory();
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0035.script
     */
    @Validate(path = "trdgrp.rec.recname")
    public ValidResult checkRecnameN1000(Trtp trtpVo){
        String finflg = trtpVo.getCrefinflg();
        if( MdaUtils.compareTo(SettleContext.getDirectTransName(),"TRTOPN") == 0 || ((MdaUtils.compareTo(SettleContext.getDirectTransName(),"BRTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BCTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BDTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTOPN") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTATO") == 0 ) && !MdaUtils.isEmpty(finflg))) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            if(MdaUtils.compareTo(trdgrpVo.getRec().getFlowflag(),"1") == 0 ) {
                if( MdaUtils.isEmpty(trtpVo.getRecname()) ) {
                   return errorMandatory();
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0036.script
     */
    @Validate(path = "trdgrp.rec.reccountrycode")
    public ValidResult checkTrdgrpRecReccountrycodeN1000(Trtp trtpVo){
        String finflg = trtpVo.getCrefinflg();
        if(MdaUtils.compareTo(SettleContext.getDirectTransName(),"TRTOPN") == 0 || ((MdaUtils.compareTo(SettleContext.getDirectTransName(),"BRTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BCTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BDTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTOPN") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTATO") == 0 ) && !MdaUtils.isEmpty(finflg))) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            if(MdaUtils.compareTo(trdgrpVo.getRec().getFlowflag(),"1") == 0 ) {
                if( MdaUtils.isEmpty(trdgrpVo.getRec().getReccountrycode()) ) {
                    return errorMandatory();
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0037.script
     */
    @Validate(path = "trdgrp.rec.recdistrictcode")
    public ValidResult checkTrdgrpRecRecdistrictcodeN1000(Trtp trtpVo){
        String finflg = trtpVo.getCrefinflg();
        if(MdaUtils.compareTo(SettleContext.getDirectTransName(),"TRTOPN") == 0 || ((MdaUtils.compareTo(SettleContext.getDirectTransName(),"BRTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BCTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BDTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTOPN") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTATO") == 0 ) && !MdaUtils.isEmpty(finflg))) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            if(MdaUtils.compareTo(trdgrpVo.getRec().getReccountrycode(),"CHN") == 0) {
                if(MdaUtils.isEmpty(trdgrpVo.getRec().getRecdistrictcode())) {
                    return errorMandatory();
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0041.script
     */
    @Validate(path = "trdgrp.rec.flowflag")
    public ValidResult checkTrdgrpRecFlowflagN1000(Trtp trtpVo){
        String finflg = trtpVo.getCrefinflg();
        if(MdaUtils.compareTo(SettleContext.getDirectTransName(),"TRTOPN") == 0
                || ((MdaUtils.compareTo(SettleContext.getDirectTransName(),"BRTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BCTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"BDTSET") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTOPN") == 0 || MdaUtils.compareTo(SettleContext.getDirectTransName(),"CPTATO") == 0 ) && !MdaUtils.isEmpty(finflg))) {
            String zmqflg = "";
            Bch bch = SettleContext.getUserSession().getBch();
            if (bch != null) {
                zmqflg = bch.getZmqflg();
            }
            if (StringUtils.isEmpty(zmqflg)) {
                Bch wrkbch = SettleContext.getUserSession().getWrkbch();
                if (wrkbch != null) {
                    zmqflg = wrkbch.getZmqflg();
                }
            }
            if(MdaUtils.compareTo(zmqflg, "X") == 0) {
                Trdgrp trdgrpVo = (Trdgrp) getParent();
                if( MdaUtils.isEmpty(trdgrpVo.getRec().getFlowflag()) ) {
                    return errorMandatory();
                }
            }
        }
        return null;
    }

    /**
     *   source:trtp.0044.script
     */
    @Validate(path="trdgrp.rec.goddspcn")
    public ValidResult checkTrdgrpRecGoddspcnN1000(Trtp trtpVo){
        String transName = SettleContext.getTransName();
        if ("TRTOPN".equalsIgnoreCase(transName) || "X".equalsIgnoreCase(trtpVo.getCrefinflg())) {
            Trdgrp trdgrpVo = (Trdgrp) getParent();
            if (MdaUtils.isEmpty(trdgrpVo.getRec().getGoddspcn())) {
                return errorMandatory();
            }
        }
        return null;
    }
}
