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

import com.brilliance.isc.bo.Act;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.setfeg.vo.SetfelVo;
import com.brilliance.isc.common.setfog.vo.SetfolVo;
import com.brilliance.isc.common.setgll.vo.SetgllVo;
import com.brilliance.isc.common.setmod.vo.SetmodVo;
import com.brilliance.isc.common.transaction.newcheck.*;
import com.brilliance.isc.common.util.I18nUtil;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.mda.dao.ActMapper;
import com.brilliance.isc.mda.dao.StbMapper;
import com.brilliance.isc.vo.component.trtcre.TrtcreVo;
import com.brilliance.mda.runtime.mda.util.Decimals;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class SetmodValidator extends AbstractModuleValidator<SetmodVo> {

    @Autowired
    private SetfolValidator setfolValidator;

    @Autowired
    private SetfelValidator setfelValidator;

    @Autowired
    private SetgllValidator setgllValidator;

    @Autowired
    private StbMapper stbMapper;

    @Autowired
    private ActMapper actMapper;

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

    @Override
    public Map<String, String> validate(SetmodVo vo) {
        Map<String, String> maps = new HashMap<>();
        maps.putAll(super.validate(vo));
        //验证他行收费
        setfolValidator.registerParent(vo);
        List<SetfolVo> setfols = vo.getSetfog().getSetfol();
        for (int i = 0; i < setfols.size(); i++) {
            maps.putAll(setfolValidator.validate(setfols.get(i), i));
        }
        setfolValidator.removeTl();
        //验证我行收费
        setfelValidator.registerParent(vo);
        List<SetfelVo> setfels = vo.getSetfeg().getSetfel();
        for (int i = 0; i < setfels.size(); i++) {
            maps.putAll(setfelValidator.validate(setfels.get(i), i));
        }
        setfelValidator.removeTl();
        //验证账务条目
        setgllValidator.registerParent(vo);
        List<SetgllVo> setglls = vo.getSetglg().getSetgll();
        for (int i = 0; i < setglls.size(); i++) {
            maps.putAll(setgllValidator.validate(setglls.get(i), i));
        }
        setgllValidator.removeTl();
        return maps;
    }

    @Warning(path = "setmod.docamt")
    public WarningResult warningDocamt(SetmodVo setmodVo) {
        if (setmodVo.getDocamt().compareTo(setmodVo.getOpnamt()) > 0) {
            BigDecimal difAmt = Decimals.sub(setmodVo.getDocamt(), setmodVo.getOpnamt());
            return WarningResult.build("WrnDOCAMT", getMessage("0136", setmodVo.getDoccur() + " " + Utils.fmtAmount(difAmt, setmodVo.getDoccur())));
        }
        return WarningResult.buildEmpty("WrnDOCAMT");
    }

    @Validate(path = "setmod.docamt")
    public ValidResult checkDocamt(SetmodVo setmodVo) {
        if (setmodVo.getDocamt().compareTo(BigDecimal.ZERO) < 0) {
            return ValidResult.build(false, I18nUtil.getMessage("0041"));
        }
        return null;
    }

    @Validate(path = "setmod.redamt")
    public ValidResult checkRedamt(SetmodVo setmodVo) {
        if (setmodVo.getRedamt().compareTo(BigDecimal.ZERO) < 0) {
            return ValidResult.build(false, I18nUtil.getMessage("0022"));
        }
        if (setmodVo.getRedamt().compareTo(setmodVo.getDocamt()) > 0) {
            return ValidResult.build(false, I18nUtil.getMessage("0042"));
        }
        return null;
    }

    @Validate(path = "setmod.setfog.cur")
    public ValidResult checkSetfogCur(SetmodVo setmodVo) {
        List<SetfolVo> setfols = setmodVo.getSetfog().getSetfol();
        Set<String> curs = new HashSet<>();
        if (setfols != null && setfols.size() > 0) {
            setfols.forEach(setfolVo -> {
                if (StringUtils.isNotEmpty(setfolVo.getCur())
                        && setfolVo.getAmt().compareTo(BigDecimal.ZERO) != 0) {
                    curs.add(setfolVo.getCur());
                }
            });
        }
        if (curs.size() > 1) {
            return ValidResult.build(false, "多笔国外收费的币种不一致!");
        }
        return null;
    }

    @Warning(path = "setmod.setfeg")
    public WarningResult warningSetfeg(SetmodVo setmodVo) {
        List<SetfelVo> setfels = setmodVo.getSetfeg().getSetfel();
        boolean flag = false;
        if (setfels != null && setfels.size() > 0) {
            for (int i=0; i<setfels.size(); i++) {
                if ("P|E|T".indexOf(setfels.get(i).getSrc()) > -1 && "N".equals(setfels.get(i).getDsp())) {
                    flag = true;
                    break;
                }
            }
        }
        if (flag) {
            return WarningResult.build("WrnSETFEG", "The user accepted to remove fees");
        }
        return WarningResult.buildEmpty("WrnSETFEG");
    }

    @Warning(path = "setmod.setglg.act")
    public WarningResult warningSetglgAct(SetmodVo setmodVo) {
        Set<String> actpros = new HashSet<>();
        TrtcreVo trtcreVo = setmodVo.getRec().getTrtcreVo();
        if (trtcreVo != null && "X".equals(trtcreVo.getCrefinflg())) {
            String ffaflg = trtcreVo.getTrdgrp().getRec().getFfaflg();
            if ("Y".equals(ffaflg)) {
                actpros.add(trtcreVo.getTrtp().getWbdp().getAct());
            }
        } else if(MdaUtils.compareTo(SettleContext.getTransName(), "TRTOPN") == 0) {
            String ffaflg = Utils.getFieldValue(setmodVo.getRec(), "ffaflg", "");
            if ("Y".equals(ffaflg)) {
                actpros.add(Utils.getFieldValue(setmodVo.getRec(), "ffaacc", ""));
            }
        } else {
            List<SetgllVo> setglls = setmodVo.getSetglg().getSetgll();
            for (SetgllVo setgllVo : setglls) {
                if (StringUtils.isNotEmpty(setgllVo.getAct())) {
                    List<Act> acts = actMapper.selectByExtkeyAndActpro(setgllVo.getAct().trim());
                    if (acts != null && acts.size() > 0) {
                        actpros.add(setgllVo.getAct());
                    }
                }
            }
        }
        if (actpros.size() > 0) {
            return WarningResult.build("WrnSETGLGAct", "交易正在使用外币贷款专户,请确认", new Object[]{actpros.stream().collect(Collectors.joining(","))});
        }
        return WarningResult.buildEmpty("WrnSETGLGAct");
    }
}
