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

import com.brilliance.isc.bo.Entinf;
import com.brilliance.isc.bo.Pty;
import com.brilliance.isc.common.cache.pty.PtyCacheService;
import com.brilliance.isc.common.cbsmod.service.XrtmodService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.entmod.service.EntmodService;
import com.brilliance.isc.common.entmod.vo.EntmodBizInfo;
import com.brilliance.isc.common.entmod.vo.EntmodVo;
import com.brilliance.isc.common.esb.account.IAccountFeign;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
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.mda.dao.EntinfMapper;
import com.brilliance.isc.vo.model.EntinfVo;
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.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

import static com.brilliance.mda.runtime.mda.Constants.CR;
import static com.brilliance.mda.runtime.mda.Constants.NULLSTR;

@Service
public class EntmodServiceImpl implements EntmodService {

    @Autowired
    private XrtmodService xrtmodService;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private PtyCacheService ptyCacheService;

    @Autowired
    private CodetableService codetableService;

    @Autowired(required = false)
    private IAccountFeign accountFeign;

    @Autowired
    private CounterService counterService;

    @Autowired
    private EntinfMapper entinfMapper;

    @Autowired
    private TransactionHelpService transactionHelpService;

    @Autowired
    private SysmodService sysmodService;

    public void saveEntmod(EntmodVo entmodVo) {
        EntinfVo entinfVo = entmodVo.getEntinf();
        if ("X".equals(entmodVo.getVisflg()) && entinfVo != null) {
            if (StringUtils.isNotEmpty(entinfVo.getCode()) || StringUtils.isNotEmpty(entinfVo.getDetail())) {
                Entinf entinf = new Entinf();
                BeanUtils.copyProperties(entinfVo, entinf);
                entinf.setTrninr(transactionHelpService.getTrninr());
                entinf.setInr(counterService.dbCounterFormat("ENTINF"));
                entinfMapper.insert(entinf);
            }
        }
    }

    /**
     * 企业名录开关
     * @return
     */
    public boolean tm01Opn() {
        return sysmodService.isBusinessOpen("TM01");
    }

    @Override
    public void searchEntmod(EntmodVo entmodVo) {
        entmodVo.reset();
        //根据交易码注册金额币种客户，接口调用标识，企业名录交易标识
        this.calcCurAmt(entmodVo);
        this.calcCustomer(entmodVo);
        //业务break或者repair，隔天处理，需要再次调用接口查询企业名录信息
        if(!MdaUtils.isEmpty(entmodVo.getRtyflg()) && MdaUtils.compareTo(entmodVo.getEntdat(), Dates.today()) != 0) {
            entmodVo.setRtyflg("");
        }
        if (StringUtils.isEmpty(entmodVo.getPtyinr()) || StringUtils.isEmpty(entmodVo.getExtkey()) || StringUtils.isEmpty(entmodVo.getCorpid())) {
            entmodVo.setErrorMsg("请输入待查询的客户号！");
            return;
        }
        if (StringUtils.isEmpty(entmodVo.getRtyflg())) {
            //调用TM01接口
            //String open = Inis.getIniStr("intace.ini","TM01","open0");
            if (tm01Opn()) {
                String merno = codetableService.getTblLabel("1001","ENTBCH","EN");
                if (StringUtils.isEmpty(merno)) {
                    merno = codetableService.getTblLabel("1001","ENTBCH","CN");
                }
                if(MdaUtils.isEmpty(merno)) {
                    entmodVo.setErrorMsg("查询所需机构号未维护,请到SYSTBL交易维护码表ENTBCH，COD默认填1001");
                    return;
                }
                this.dealTM01(entmodVo, merno);
                if (StringUtils.isNotEmpty(entmodVo.getErrorMsg())) {
                    return;
                }
                entmodVo.setRtyflg("X");
                entmodVo.setChkflg("X");
                entmodVo.setEntdat(Dates.today());
                entmodVo.getEntinf().setChkmsg("");
                switch(entmodVo.getEntinf().getEntrank()) {
                    case "A":
                        //A类客户
                        dealTypeA(entmodVo);
                        break;
                    case "B":
                        //B类客户
                        dealTypeB(entmodVo);
                        break;
                    case "C":
                        //C类客户
                        dealTypeC(entmodVo);
                        break;
                    case "":
                        entmodVo.setErrorMsg(entmodVo.getEntinf().getCode() + "-" + entmodVo.getEntinf().getDetail());
                        return;
                }
                if(Strings.pos("-A-B-C-", entmodVo.getEntinf().getEntrank()) > 0
                        && MdaUtils.isEmpty(entmodVo.getEntinf().getIsmoncorp())) {
                    entmodVo.getEntinf().setChkmsg(entmodVo.getEntinf().getChkmsg() + CR + "跨境人民币出口重点监管企业未获取到值，" + CR + " 请直接登录外汇局Asone系统完成货物贸易企业名录检核。");
                    entmodVo.setRtyflg(NULLSTR);
                    entmodVo.setChkflg(NULLSTR);
                    entmodVo.setRtynum(entmodVo.getRtynum() + 1);
                    if(entmodVo.getRtynum() >= 3) {
                        entmodVo.setRtyflg("X");
                        entmodVo.setChkflg("X");
                        entmodVo.setEntdat(Dates.today());
                    }
                    entmodVo.setErrorMsg("跨境人民币出口重点监管企业未获取到值，重试两次后若还未获取到值，" + CR + " 请直接登录外汇局Asone系统完成货物贸易企业名录检核。");
                    return;
                }
            } else {
                entmodVo.setErrorMsg("接口已关闭，请直接登录外汇局Asone系统完成货物贸易企业名录检核。");
                return;
            }
        } else {
            entmodVo.setChkflg("X");
            if ("B".equals(entmodVo.getEntinf().getEntrank())) {
                //B类客户需要重新校验金额币种账号变化
                this.dealTypeB(entmodVo);
            }
        }
    }

    private void calcCurAmt(EntmodVo entmodVo) {
        EntmodBizInfo rec = entmodVo.getRec();
        String cur = rec.getDoccur();
        BigDecimal amt = rec.getDocamt();
        if (MdaUtils.compareTo(entmodVo.getConcur(), cur) != 0
                || MdaUtils.compareTo(entmodVo.getConamt(), amt) != 0) {
            entmodVo.setConcur(cur);
            entmodVo.setConamt(amt);
            //金额币种发生修改 B类需要重新校验
            if ("B".equals(entmodVo.getEntinf().getEntrank())) {
                entmodVo.setChkflg("");
            }
            //重新计算币种 金额
            if ("USD".equals(cur)) {
                entmodVo.setConveramt(amt);
            } else {
                Argument<BigDecimal> rateBox = new Argument<>();
                Argument<BigDecimal> sqrRatBox = new Argument<>();
                xrtmodService.getratForENT(cur, "S", "USD", "B", Dates.today(), rateBox, sqrRatBox );
                BigDecimal rate = rateBox.value;
                BigDecimal sqrRat = sqrRatBox.value;
                entmodVo.setConveramt(xrtmodService.amtRnd(Decimals.mul(amt,rate), "USD"));
                entmodVo.setModified("converamt");
            }
            entmodVo.getEntinf().setConveramt(entmodVo.getConveramt());
        }
    }

    private void calcCustomer(EntmodVo entmodVo) {
        EntmodBizInfo rec = entmodVo.getRec();
        PtsptaVo ptsptaVo = ptsptaToolComponent.getPtsFromListByRol(rec.getPtsList(), rec.getRol());
        if (ptsptaVo == null || !ptsptaToolComponent.ptsIsRolSet(ptsptaVo)) {
            entmodVo.setPtyinr("");
            entmodVo.setExtkey("");
            entmodVo.setCorpid("");
            return;
        }
        String ptyinr = ptsptaVo.getPtyinr();
        if (StringUtils.isEmpty(ptyinr)) {
            entmodVo.setPtyinr("");
            entmodVo.setExtkey("");
            entmodVo.setCorpid("");
            return;
        }
        if(MdaUtils.compareTo(ptyinr, entmodVo.getPtyinr()) != 0) {
            //客户信息发生变化需要重新调用接口
            entmodVo.setPtyinr(ptyinr);
            entmodVo.setRtyflg(NULLSTR);
            entmodVo.setEntinf(new EntinfVo());
            Pty pty = ptyCacheService.getPtyById(ptyinr);
            if (pty != null) {
                entmodVo.setCorpid(pty.getJuscod());
                entmodVo.setExtkey(pty.getExtkey());
            }
        }
    }

    /**
     *   source:entmod.0002.script
     */
    public void dealTypeA(EntmodVo entmodVo) {
        if(MdaUtils.compareTo(entmodVo.getEntinf().getIsmoncorp(),"1") == 0 ) {
            entmodVo.getEntinf().setChkmsg("该客户为跨境人民币出口重点监管企业，请加强审核。");
        }
    }
    /**
     *   source:entmod.0003.script
     */
    public void dealTypeB(EntmodVo entmodVo) {
        String frame = entmodVo.getRec().getTransName();
        //有些交易，客户是B类客户时，需要校验金额
        if( Strings.pos("-CPTADV-CPTREP-BOTSET-BETSET-BPTOPN-JSTOPN-JSTOPT-MCTFEE-CPTATI-BTTSET-CPTFEE-",frame) > 0 ) {
            if( MdaUtils.compareTo(entmodVo.getConveramt(), entmodVo.getEntinf().getRcvbal())>0 ) {
                entmodVo.getEntinf().setChkmsg( "出口可收汇余额（美元）不足，请凭《登记表》办理。");
            } else {
                entmodVo.getEntinf().setChkmsg( "请加强审核，进行电子数据核查，酌情通过Asone系统中货贸系统扣减其对应的可收汇余额。");
            }
        }
        if( Strings.pos("-CPTOPN-BCTSET1-LITOPN1-TRTOPN-BRTUDP1-BRTSET1-CPTATO-LITAME1-",frame) > 0 ) {
            if( MdaUtils.compareTo(entmodVo.getConveramt(), entmodVo.getEntinf().getPaybal())>0 ) {
                entmodVo.getEntinf().setChkmsg( "进口可付汇余额（美元）不足，请凭《登记表》办理。");
            } else {
                entmodVo.getEntinf().setChkmsg( "请加强审核，进行电子数据核查，酌情通过Asone系统中货贸系统扣减其对应的可付汇余额。");
            }
        }
        if( Strings.pos("-LETOPN-LETRSV-LETDRW-",frame) > 0 ) {
            entmodVo.getEntinf().setChkmsg("请关注信用证期限是否超过90天。");
        }

    }
    /**
     *   source:entmod.0004.script
     */
    public void dealTypeC(EntmodVo entmodVo) {
        String frame = entmodVo.getRec().getTransName();
        entmodVo.getEntinf().setChkmsg( "请加强审核，请凭《登记表》办理，若无《登记表》请终止交易。");
        if( Strings.pos("-LETOPN-LETRSV-LETDRW-", frame) > 0 ) {
            entmodVo.getEntinf().setChkmsg(entmodVo.getEntinf().getChkmsg() + CR + "请关注信用证期限是否超过90天。");
        }
    }

    /**
     * 调用企业名录TM01接口
     * @param entmodVo
     */
    public void dealTM01(EntmodVo entmodVo, String merno) {
        EntinfVo entinfVo = entmodVo.getEntinf();
        String itfInr = counterService.dbCounterFormat("TM01", 6);
        InnerReqTM01 innerReqTM01 = new InnerReqTM01(merno, entmodVo.getCorpid(), "");
        InnerReq<InnerReqTM01> innerReq = new InnerReq<>(innerReqTM01);
        Header header = new Header();
        header.itfinr = itfInr;
        innerReq.header = header;
        InnerRes<InnerResTM01> innerRes = accountFeign.callTm01(innerReq);
        if (innerRes == null || innerRes.DATA == null || innerRes.header == null || !"AAAAAAA".equals(innerRes.header.code)) {
            //次数控制
            entmodVo.setRtynum(entmodVo.getRtynum() + 1);
            if(entmodVo.getRtynum() >= 3) {
                entmodVo.setRtyflg("X");
                entmodVo.setChkflg("X");
            }
            entmodVo.setEntdat(Dates.today());
            //接口调用失败
            entinfVo.setDetail("接口异常，请直接登录外汇局Asone系统完成货物贸易企业名录检核。");
            entmodVo.setErrorMsg(Strings.getText("错误信息:$1", "接口异常，重试两次若还报错，请直接登录外汇局Asone系统完成货物贸易企业名录检核。"));
        } else {
            //接口调用成功
            InnerResTM01 innerResTM01 = innerRes.DATA;
            entinfVo.setCode(innerResTM01.MSGCOD);
            entinfVo.setDetail(innerResTM01.DETAIL);
            if ("00000".equals(innerResTM01.MSGCOD)) {
                entinfVo.setPrtdat(Dates.today());
                entinfVo.setCorpid(innerResTM01.CORPID);
                entinfVo.setCorpname(innerResTM01.CORPNM);
                entinfVo.setSafecode(innerResTM01.SAFCOD);
                entinfVo.setSafename(innerResTM01.SAFNAM);
                entinfVo.setPaylist(innerResTM01.PAYLST);
                entinfVo.setNewcorp(innerResTM01.NEWCOP);
                entinfVo.setEntrank(innerResTM01.QYRANK);
                if (!"null".equals(innerResTM01.BEGDAT)) {
                    entinfVo.setRakbegdat(Utils.parseDate(innerResTM01.BEGDAT));
                }
                if (!"null".equals(innerResTM01.ENDDAT)) {
                    entinfVo.setRakenddat(Utils.parseDate(innerResTM01.ENDDAT));
                }
                entinfVo.setIstaxfre(innerResTM01.ISTAXF);
                if (!"nu".equals(innerResTM01.TAXCOD)) {
                    entinfVo.setTaxfrecod(innerResTM01.TAXCOD);
                }
                if (StringUtils.isEmpty(innerResTM01.PAYBAL) || "null".equals(innerResTM01.PAYBAL)) {
                    entinfVo.setPaybal(BigDecimal.ZERO);
                } else {
                    entinfVo.setPaybal(new BigDecimal(innerResTM01.PAYBAL));
                }
                if (StringUtils.isEmpty(innerResTM01.RCVBAL) || "null".equals(innerResTM01.RCVBAL)) {
                    entinfVo.setRcvbal(BigDecimal.ZERO);
                } else {
                    entinfVo.setRcvbal(new BigDecimal(innerResTM01.RCVBAL));
                }
                entinfVo.setIsmoncorp(innerResTM01.RESRV1);
            } else {
                //次数控制
                entmodVo.setRtynum(entmodVo.getRtynum() + 1);
                if(entmodVo.getRtynum() >= 3) {
                    entmodVo.setRtyflg("X");
                    entmodVo.setChkflg("X");
                }
                entmodVo.setEntdat(Dates.today());
                //接口调用失败
                entinfVo.setDetail(innerResTM01.DETAIL + CR + "接口异常，请直接登录外汇局Asone系统完成货物贸易企业名录检核。");
                entmodVo.setErrorMsg(Strings.getText("错误信息:$1", innerResTM01.DETAIL + CR + "重试两次若还报错，请直接登录外汇局Asone系统完成货物贸易企业名录检核。"));
            }
        }
    }

}
