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

import com.brilliance.isc.bo.Cci;
import com.brilliance.isc.bo.Pta;
import com.brilliance.isc.common.cache.pta.PtaCacheService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.esb.account.IAccountFeign;
import com.brilliance.isc.common.exception.ValidateException;
import com.brilliance.isc.common.register.cci.CliBanInfoFactory;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.transaction.help.TransactionServiceSet;
import com.brilliance.isc.common.transaction.newcheck.AbstractModuleValidator;
import com.brilliance.isc.common.transaction.newcheck.Warning;
import com.brilliance.isc.common.transaction.newcheck.WarningResult;
import com.brilliance.isc.common.transaction.vo.BaseTransactionVo;
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.esb.model.inner.*;
import com.brilliance.isc.vo.WarnVo;
import com.brilliance.isc.warn.WarnService;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component
public class Ecif0958Validator extends AbstractModuleValidator<BaseTransactionVo> {
    private static final String CR = "\n";
    private static final String BR = "<br/>";
    @Resource
    private SysmodService sysmodService;
    @Resource
    private TransactionHelpService transactionHelpService;
    @Resource
    private CliBanInfoFactory cliBanInfoFactory;
    @Resource
    private CounterService counterService;
    @Resource
    private PtaCacheService ptaCacheService;
    @Autowired(required = false)
    private IAccountFeign accountFeign;
    @Autowired
    private WarnService warnService;

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

    @Override
    public Map<String, String> validate(BaseTransactionVo vo) {
        return super.validate(vo);
    }

    @Warning(path = "ecif.0958")
    public WarningResult check0958(BaseTransactionVo vo) {
        return doValidate(vo);
    }

    /**
     * 确定是否执行0958校验，满足下列条件才执行【一期保函不包含在内】
     * <ol>
     *    <li>码表开关打开</li>
     *    <li>交易必须是起头交易</li>
     * </ol>
     */
    public boolean isValidate() {
        if (sysmodService.isInterfaceOpen("SFXXCK")) {
            /**
             * 起头交易判断
             * 托收代收：BOTDAV1-BCTDAV-CCTDAV
             * 汇款：CPTOPN-CPTADV
             * 融资：BPTOPN-TRTOPN
             * 信用证：LITOPN1-LETOPN
             * 国内证：DITOPN-DETOPN
             * 衍生品：JSTOPT-JSTOPN-JSTOPM-MCTOPN
             * 保函：GITOPN-GITPOP-NITOPN-NITPOP-HITOPN-HITPOP-GETOPN-NETOPN[*****一期保函去掉*****]
             */
            String transName = SettleContext.getDirectTransName();
            if (("BOTDAV1-BCTDAV-CCTDAV-CPTOPN-CPTADV-BPTOPN-TRTOPN-LITOPN1-LETOPN-DITOPN-DETOPN-JSTOPT-" +
                    "JSTOPN-JSTOPM-MCTOPN").indexOf(transName) != -1) {
                return true;
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("当前交易不是起头交易，不用做对公客户信息校验:{}", transName);
                }
                return false;
            }
        }
        return false;
    }

    /**
     * 做0958核验
     */
    public WarningResult doValidate(BaseTransactionVo baseTransactionVo) {
        TransactionServiceSet transactionStoreSet = transactionHelpService.getTransactionStoreSet();
        Object rec = transactionStoreSet.getRec();
        String objTyp = Utils.getBoType(rec);
        List<PtsptaVo> ptsList = transactionStoreSet.getPtsList();
        Cci cci = new Cci();
        cliBanInfoFactory.getCliBanInfo(objTyp).buildValue("", objTyp, ptsList, cci);
        Pta pta = ptaCacheService.getPtaByInr(cci.getCcicusptainr());
        String ptyextkey = pta.getPtyextkey();
        if (StringUtils.isEmpty(ptyextkey)) {
            if (log.isDebugEnabled()) {
                log.debug("客户编号为空无须校验");
            }
            registFirstLevelWarn(null);
            return WarningResult.buildEmpty("warn");
        }
        //调0958接口
        InnerRes res = callInterfaceAndCheck(ptyextkey, MdaUtils.toString(counterService.dbCounterFormat("ECIFTRN", 6)));
        if (res == null) {
            throw new ValidateException("调ECIF0958接口返回信息为空");
        }
        //对返回结果做校验
        if ("CFC4010".equals(res.header.code)) {
            registFirstLevelWarn(null);
            return WarningResult.buildEmpty("warn");
        }
        if (!"AAAAAAA".equals(res.header.code)) {
            throw new ValidateException(res.header.description);
        }
        InnerRes0958 res0958 = (InnerRes0958) res.DATA;
        List<InnerRes0958.Item0958> item0958List = res0958.lst0958;
        String limitFlag = res0958.limitFlag;
        if ("1".equals(limitFlag)) {
            StringBuffer message = new StringBuffer();
            message.append("客户在我行留存的身份基本信息存在限制类错误，不允许继续交易");
            message.append(" 客户号：");
            message.append(pta.getPtyextkey());
            message.append(CR);
            for (int i = 0; i < item0958List.size(); i++) {
                message.append(i + 1 + "." + item0958List.get(i).filedCname + "：" + item0958List.get(i).validResults);
                if (i != item0958List.size() - 1) {
                    message.append(CR);
                }
            }
            registFirstLevelWarn(message.toString());
        } else {
            registFirstLevelWarn(null);
        }
        String cueFlag = res0958.cueFlag;
        if ("1".equals(cueFlag)) {
            StringBuffer message = new StringBuffer();
            message.append("客户在我行留存的身份基本信息不完善");
            message.append(" 客户号：");
            message.append(pta.getPtyextkey());
            message.append(BR);
            for (int i = 0; i < item0958List.size(); i++) {
                message.append(i + 1 + "." + item0958List.get(i).filedCname + "：" + item0958List.get(i).validResults);
                if (i != item0958List.size() - 1) {
                    message.append(BR);
                }
            }
            return WarningResult.build("warn", message.toString());
        }
        return WarningResult.buildEmpty("warn");
    }

    private void registFirstLevelWarn(String message) {
        warnService.registerWarn("1", "ecif.0958", "fatal", WarnVo.SOURCE_BACK, message);
    }

    private InnerRes callInterfaceAndCheck(String ptyextkey, String trninr) {
        Header header = new Header();
        InnerReq<InnerReq0958> req = new InnerReq<>();
        InnerReq0958 data = new InnerReq0958();
        data.orgNo = ptyextkey;
        data.begRecNo = "1";
        data.recSize = "50";
        req.DATA = data;
        req.header = header;
        if (sysmodService.isShangYun("ECIFSY")) {
            data.qantno = trninr;
        }
        return accountFeign.call0958(req);
    }

}
