package com.brilliance.isc.common.umdmod.service.impl;

import com.brilliance.mda.runtime.mda.util.MdaUtils;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.util.ObjectUtils;
import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.bo.Stb;
import com.brilliance.isc.bo.Umd;
import com.brilliance.isc.common.api.bch.service.BchService;
import com.brilliance.isc.common.cache.atpbch.AtpBchCacheService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.context.SpringEnvContext;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.esb.tymd.ITymdFeign;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.umdmod.service.UmdmodService;
import com.brilliance.isc.common.umdmod.vo.UmdmodVo;
import com.brilliance.isc.common.usermd.IUmdRegister;
import com.brilliance.isc.common.utils.UmdmodUtil;
import com.brilliance.isc.common.vo.PtsptaVo;
import com.brilliance.isc.esb.model.inner.InnerReq;
import com.brilliance.isc.esb.model.inner.InnerReqE200;
import com.brilliance.isc.esb.model.inner.InnerRes;
import com.brilliance.isc.esb.model.inner.InnerResE200;
import com.brilliance.isc.esb.model.tymd.ReqE200;
import com.brilliance.isc.mda.dao.StbMapper;
import com.brilliance.isc.mda.dao.UmdMapper;
import com.brilliance.isc.transfer.esb.IEsbMapper;
import com.brilliance.isc.utils.BigDecimalUtils;
import com.brilliance.isc.utils.DateUtils;
import com.brilliance.isc.utils.StringUtils;
import com.brilliance.isc.vo.manager.StbVo;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class UmdmodServiceImpl implements UmdmodService {
    private static Logger logger = LoggerFactory.getLogger(UmdmodServiceImpl.class);
    private final String FRMS = "CPTOPN,CPTECO,CPTADV,CPTECI,LITOPN,LITAME,LITDCK,BCTDAV,BCTAME,LETOPN,LETAME,LETRSV,LETDRW,LETDRV,BOTDAV,BOTAME,CCTDAV,CLTDAV,LTTOPN,LTTAME,LTTDCK,GITOPN,GITAME,GETOPN,GETAME,BRTSET,BCTSET,GITSET,DFTMSG,GITODZ";
    @Autowired
    private UmdMapper umdMapper;
    @Autowired
    private CounterService counterService;
    @Autowired(required = false)
    private ITymdFeign iTymdFeign;
    @Autowired
    private StbMapper stbMapper;

    @Autowired
    private BchService bchService;

    @Autowired
    private AtpBchCacheService atpBchCacheService;

    public void assertUmdmod(UmdmodVo umdmodVo) {
        if (umdmodVo.getPtsaddg() == null) {
            umdmodVo.setPtsaddg(new ArrayList<>());
        }
        //初始化erromaps
        umdmodVo.setErrormaps(new ArrayList<>());
        if (!tymdOpn()) {
            return;
        }
        internalPostRegisterUmdCheck(umdmodVo);

        if ("N".equals(umdmodVo.getExcuteflg())) {
            logger.info("###########:当前交易不需要进行名单校验！");
            return;
        }
        //统一名单检核
        checkTymd(umdmodVo);

    }

    @Override
    public void initUmdmod(UmdmodVo umdmodVo) {
        //1.交易注册生成bennam以及统一名单注册信息
        internalPostRegisterUmdCheck(umdmodVo);

        if ("N".equals(umdmodVo.getExcuteflg())) {
            umdmodVo.getUmdList().clear();
            umdmodVo.setCASE_NO("");
            logger.info("###########:当前交易不需要进行名单校验！");
            return;
        }
        //2.得到当前umdlist
        List<Umd> umdList = umdmodVo.getUmdList();
        //3.根据mac获取案例编号
        String mac = UmdmodUtil.calculateMac(umdmodVo);
        String caseNo = "";
        if (umdList != null) {
            for (Umd umd : umdList) {
                if (mac.equals(umd.getMac())) {
                    caseNo = umd.getCaseno();
                    break;
                }
            }
        }
        umdmodVo.setCASE_NO(caseNo);
    }

    /**
     * 校验统一名单
     *
     * @param umdmodVo
     */
    public void checkTymd(UmdmodVo umdmodVo) {
        //计算mac
        String maccontent = UmdmodUtil.calculateMac(umdmodVo);
        //根据mac查到是否存在umd
        Umd umd = null;
        if (umdmodVo.getUmdList() != null) {
            Optional<Umd> optional = umdmodVo.getUmdList().stream().filter(umd1 -> maccontent.equals(umd1.getMac())).findFirst();
            if (optional.isPresent()) {
                umd = optional.get();
            }
        }
        if (ObjectUtils.isEmpty(umd)) {
            //创建一条umd数据
            buildUmd(umdmodVo);
            umdmodVo.getUmd().setRequest(umdmodVo.getMaccontent());
            umdmodVo.setCASE_NO("");
            umdmodVo.getUmd().setMac(maccontent);
            umdmodVo.getUmdList().add(umdmodVo.getUmd());
            //调接口查询
            callUMDInterface(umdmodVo);
        } else {
            umdmodVo.setUmd(umd);
            umdmodVo.setCASE_NO(umdmodVo.getUmd().getCaseno());

            if ("000".equals(umdmodVo.getUmd().getCode())) {
                logger.info("该笔名单已校验过并且未命中,案例编号为:{}", umdmodVo.getUmd().getCaseno());

            }
            if ("001".equals(umdmodVo.getUmd().getCode())) {
                logger.info("该笔名单已经校验过且是命中的，案例编号为：{}", umdmodVo.getUmd().getCaseno());
                logger.info("-----------开始调用认定接口-------------");
                if ("100".equals(umdmodVo.getUmd().getCasecode())) {
                    logger.info("该笔名单已校验过并且命中|放行,案例编号为:{}", umdmodVo.getUmd().getCaseno());
                } else {
                    logger.info("该笔名单已校验过并且命中|未放行,案例编号为:{}", umdmodVo.getUmd().getCaseno());
                    callUMDInterface(umdmodVo);
                }
            }

        }
    }

    /**
     * 处理统一名单接口调用结果
     *
     * @param innerResE200InnerRes
     * @param umdmodVo
     */
    void dealResponse(InnerRes<InnerResE200> innerResE200InnerRes, UmdmodVo umdmodVo) {
        //每次查询完设置案例编号
        umdmodVo.setCASE_NO(innerResE200InnerRes.DATA.case_no);
        if (StringUtils.isEmpty(umdmodVo.getUmd().getCaseno())) {
            logger.info("--------------处理筛查结果----------------");
            umdmodVo.getUmd().setCode(innerResE200InnerRes.DATA.list_code);
            if ("000".equals(innerResE200InnerRes.DATA.list_code)) {
                logger.info("该笔统一名单筛查未命中，案例编号：{}", innerResE200InnerRes.DATA.case_no);
            } else if ("001".equals(innerResE200InnerRes.DATA.list_code)) {
                Map errormap = new HashMap();
                errormap.put("key", umdmodVo.getUmd().getInr());
                errormap.put("message", "统一名单命中！，请去统一名单系统处理");

                umdmodVo.getErrormaps().add(errormap);

            } else {
                dealCodError(innerResE200InnerRes.DATA.list_code);
            }
            umdmodVo.getUmd().setCaseno(innerResE200InnerRes.DATA.case_no);
            umdMapper.insert(umdmodVo.getUmd());
        } else {
            logger.info("--------------处理认定结果----------------");
            umdmodVo.getUmd().setCasecode(innerResE200InnerRes.DATA.case_code);
            umdmodVo.setCASE_NO(umdmodVo.getUmd().getCaseno());
            if ("100".equals(innerResE200InnerRes.DATA.case_code)) {
                logger.info("该笔统一名单认定通过,案例编号为{}", umdmodVo.getUmd().getCaseno());
            } else if ("101".equals(innerResE200InnerRes.DATA.case_code)) {
                umdmodVo.getUmd().setCasecode(innerResE200InnerRes.DATA.case_code);
                Map errormap = new HashMap();
                errormap.put("key", umdmodVo.getUmd().getInr());
                errormap.put("message", "统一名单认定结果为禁止，请去统一名单系统处理");

                umdmodVo.getErrormaps().add(errormap);
                logger.info("统一名单认定结果为禁止,案例编号为{}", umdmodVo.getUmd().getCaseno());

            } else if ("102".equals(innerResE200InnerRes.DATA.case_code)) {
                umdmodVo.getUmd().setCasecode(innerResE200InnerRes.DATA.case_code);
                Map errormap = new HashMap();
                errormap.put("key", umdmodVo.getUmd().getInr());
                errormap.put("message", "统一名单认定结果为认定中！，请去统一名单系统处理");

                umdmodVo.getErrormaps().add(errormap);
                logger.info("统一名单认定结果为认定中,案例编号为{}", umdmodVo.getUmd().getCaseno());

            } else {
                dealCaseError(innerResE200InnerRes.DATA.case_code);
            }

            umdMapper.updateByPrimaryKey(umdmodVo.getUmd());
        }
    }

    /**
     * 处理筛查异常
     *
     * @param code
     */
    void dealCodError(String code) {
        if (StringUtils.isEmpty(code)) {
            throw new CommonServiceException("统一名单系统查询出错:无返回值");
        }
        switch (code) {
            case "020":
                throw new CommonServiceException("统一名单系统查询出错:关闭查询服务");
            case "202":
                throw new CommonServiceException("统一名单系统查询出错:筛查业务类型不存在");
            case "203":
                throw new CommonServiceException("统一名单系统查询出错:请求参数错误");
            case "204":
                throw new CommonServiceException("统一名单系统查询出错:名单查询失败");
            case "209":
                throw new CommonServiceException("统一名单系统查询出错:筛查超时");
            default:
                throw new CommonServiceException("统一名单系统查询出错!");
        }
    }

    /**
     * 处理认定异常
     *
     * @param code
     */
    void dealCaseError(String code) {
        if (StringUtils.isEmpty(code)) {
            throw new CommonServiceException("统一名单系统查询出错:无返回值");
        }
        switch (code) {
            case "103":
                throw new CommonServiceException("统一名单系统查询出错:该案例不存在!");
            case "104":
                throw new CommonServiceException("统一名单系统查询出错:案例信息和筛查要素不符!");
            case "200":
                throw new CommonServiceException("统一名单系统查询出错:案例信息查询失败!");
            default:
                throw new CommonServiceException("统一名单系统查询出错!");
        }
    }


    /**
     * 如果数据库没查到的时候组装umd表数据
     *
     * @param umdmodVo
     */
    void buildUmd(UmdmodVo umdmodVo) {
        Umd umd = new Umd();
        umd.setInr(counterService.dbCounterFormat("UMD"));
        umd.setInifrm(SettleContext.getTransName());
        umd.setUsr(umdmodVo.getOPERATOR());
        umd.setOrgcode(SettleContext.getUserSession().getOrgBch().getBranch());
        umd.setInifrm(SettleContext.getTransName());
        umd.setTrninr(umdmodVo.getTrninr());
        umd.setOrdinr(umdmodVo.getOrdinr());
        umd.setSptinr(umdmodVo.getSptinr() != null ? umdmodVo.getSptinr() : "");
        umd.setOwnref(umdmodVo.getTRANS_NO());
        umd.setObjtyp(umdmodVo.getRec().getObjtyp());
        umd.setObjinr(umdmodVo.getRec().getObjinr());

        umd.setCredat(DateUtils.getNowDate());
        umd.setLstdat(DateUtils.getNowDate());
        umd.setExtkey(umdmodVo.getCUST_NO());

        if (!StringUtils.isEmpty(umd.getExtkey()) && umd.getExtkey().length() > 10) {

            umd.setExtkey(umd.getExtkey().substring(0, 10));
        }

        umd.setBranch(SettleContext.getUserSession().getOrgBch().getBranch());


        umdmodVo.setUmd(umd);
    }


    @Override
    public void internalPostRegisterUmdCheck(UmdmodVo umdmodVo) {

        //按照交易码，获取注册Spring的交易Bean
        String transName = SettleContext.getTransName();
        try {
            IUmdRegister umdRegister = SpringEnvContext.getBean(atpBchCacheService.getSdTransNameForRegister().toLowerCase() + "." + "umdRegister");
            umdRegister.RegisterUmdCheck(umdmodVo);
        } catch (NoSuchBeanDefinitionException e) {
            throw new CommonServiceException("没有找到交易注册类");
        }


    }

    public void setUMDHeader(UmdmodVo umdmodVo, String argCustno, String argLoanFlag, String argCur, BigDecimal argAmt) {

        //ORGCODE = \\SYSMOD\\WRKBCH\\ACCBCH

        Bch bch = SettleContext.getUserSession().getBch();
        String accbch = "";
        if (bch == null) {
            accbch = SettleContext.getUserSession().getOrgBch().getBranch();
        } else {
            accbch = bch.getBranch();
        }
        umdmodVo.setORG_CODE(accbch);
        umdmodVo.setTRANS_CODE(SettleContext.getUserSession().getTransName());
        umdmodVo.setTRANS_NO(umdmodVo.getRec().getOwnref());

        umdmodVo.setOPERATOR(readUsr(umdmodVo));

        argCustno = StringUtils.mid(argCustno, 0, 10);
        umdmodVo.setCUST_NO(argCustno);
        umdmodVo.setLOAN_FLAG(argLoanFlag);
        umdmodVo.setTRANS_CUR(argCur);
        umdmodVo.setTRANS_AMT(BigDecimalUtils.BigD2stringHalfUP(argAmt, 2));
        if (StringUtils.isNotEmpty(umdmodVo.getQUERY_TYPE())) {
            return;
        }
        if ("1".equals(argLoanFlag)) {
            umdmodVo.setQUERY_TYPE("03");
        } else {
            umdmodVo.setQUERY_TYPE("02");
        }
    }

    /**
     * 获取柜员 ，需要上收交易中的 总行环节查上一条umd的usr 否则直接取当前柜员
     *
     * @param umdmodVo
     * @return
     */
    public String readUsr(UmdmodVo umdmodVo) {
        boolean isselect = false;
        String accbranch = SettleContext.getUserSession().getBch().getBranch();
        if (accbranch == null) {
            isselect = true;
        } else {
            if (bchService.isOrderBranchByFrm(atpBchCacheService.getSdTransNameForRegister())) {
                if (!bchService.isSdanfrmByBranchInifrm(accbranch, SettleContext.getTransName())) {
                    isselect = true;
                }
            }
        }
        if (isselect) {
            List<Umd> umds = umdMapper.selectUmdByOwnref(umdmodVo.getTRANS_NO(), atpBchCacheService.getSdTransNameForRegister());
            if (umds.size() > 0) {
                if (!StringUtils.isEmpty(umds.get(0).getUsr())) {
                    return umds.get(0).getUsr();
                }
            }
        } else {
            return SettleContext.getUserSession().getUsr().getExtkey();
        }
        return null;
    }

    @Override
    public void callUMDInterface(UmdmodVo umdmodVo) {
        if (!MdaUtils.isEmpty(umdmodVo.getUmd())) {
            if (!MdaUtils.isEmpty(umdmodVo.getUmd().getExtkey())) {
                umdmodVo.getUmd().setExtkey((umdmodVo.getUmd().getExtkey().split("-"))[0]);
            }
        }
        //接口调用状态

        umdmodVo.getUmd().setSta("成功");
        //交易流水号
        umdmodVo.getUmd().setTransid(StringUtils.stringAppend("270", DateUtils.dateTimeNow("yyyyMMdd"), counterService.dbCounterFormat("UMDCHK")));

        umdmodVo.setTRANS_ID(umdmodVo.getUmd().getTransid());

        ReqE200 reqE200 = IEsbMapper.INSTANCE.copyUmdData(umdmodVo);

        InnerReqE200 innerReqE200 = new InnerReqE200(reqE200);
        InnerReq<InnerReqE200> innerReqE200InnerReq = new InnerReq<InnerReqE200>(innerReqE200);

        InnerRes<InnerResE200> innerResE200InnerRes = null;
        InnerResE200 innerResE200 = null;

        try {

            innerResE200InnerRes = iTymdFeign.callE200(innerReqE200InnerReq);

            logger.info("########名单校验成功!");


        } catch (NoSuchBeanDefinitionException e) {
            throw new CommonServiceException(StringUtils.stringAppend("统一名单接口调用失败", "###", e.getMessage()));
        }
        if (!"AAAAAAA".equals(innerResE200InnerRes.header.code)) {
            throw new CommonServiceException(StringUtils.stringAppend("统一名单接口调用失败", "###", innerResE200InnerRes.header.description));
        }
        dealResponse(innerResE200InnerRes, umdmodVo);
    }

    public boolean tymdOpn() {
        StbVo stbVo = new StbVo();
        stbVo.setTbl("TYMDOP");
        List<Stb> stbs = stbMapper.queryByPage(stbVo);
        return "Y".equals(stbs.get(0).getCod()) ? true : false;
    }

    /**
     * 获取角色
     *
     * @param ptsptaVoList
     * @param rol
     * @return
     */
    public PtsptaVo getPtsptaFromPtslist(List<PtsptaVo> ptsptaVoList, String rol) {

        List<PtsptaVo> ptsptaVos = ptsptaVoList.stream().filter(ptsptaVo -> {
            return rol.equalsIgnoreCase(ptsptaVo.getRol());
        }).collect(Collectors.toList());
        if (ptsptaVos.size() > 0) {
            return ptsptaVos.get(0);
        }
        return null;
    }
}
