package com.brilliance.isc.common.txnhold.service;

import cn.hutool.core.lang.Assert;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.exception.PublicServiceException;
import com.brilliance.isc.common.sysmod.SysmodService;
import com.brilliance.isc.common.transaction.help.TransactionHelpService;
import com.brilliance.isc.common.transaction.txnhold.service.TxnHoldService;
import com.brilliance.isc.common.transaction.txnhold.vo.TxnHoldVo;
import com.brilliance.isc.common.transaction.vo.BaseTransactionVo;
import com.brilliance.isc.common.txnhold.handler.TxnHoldHandlerManager;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.mda.runtime.mda.util.Inis;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.brilliance.isc.bo.Ers;
import com.brilliance.isc.bo.Smh;
import com.brilliance.isc.bo.Spt;
import com.brilliance.isc.mda.dao.ErsMapper;
import com.brilliance.isc.mda.dao.SmhMapper;
import com.brilliance.isc.mda.dao.SptMapper;
import com.brilliance.isc.mda.dao.TrnMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class TxnHoldServiceImpl implements TxnHoldService {

    private static Logger log = LoggerFactory.getLogger(TxnHoldServiceImpl.class);

    @Autowired
    private TransactionHelpService transactionHelpService;

    @Autowired
    private SysmodService sysmodService;

    @Autowired
    private TxnHoldHandlerManager txnHoldHandlerManager;

    @Autowired
    private SptMapper sptMapper;

    @Autowired
    private SmhMapper smhMapper;

    @Autowired
    private ErsMapper ersMapper;

    @Autowired
    private TrnMapper trnMapper;

    @Override
    public void txnHold(TxnHoldVo txnHoldVo) {
        txnHoldVo.reset();
        BaseTransactionVo txnVo = txnHoldVo.getBaseTransactionVo();
        //Mtabut.rulePenN300()
        if ("0".equals(SettleContext.getUserSession().getBch().getLev())) {
            throw new PublicServiceException("单证中心柜员不能经办业务！！！");
        }
        if (SettleContext.getUserSession().getWrkbch()==null || StringUtils.isEmpty(SettleContext.getUserSession().getWrkbch().getInr())) {
            throw new PublicServiceException("必须输入本行客户信息才能BREAK.");
        }
        //Mtabut.rulePenN500() 不需要实现

        //Mtabut.rulePenN901()
        String flg0541 = Inis.getIniBlock("intace.ini", "INF0541", "open");
        String flg0542 = Inis.getIniBlock("intace.ini", "INF0542", "open");
        String inifrm = SettleContext.getTransName();
        String comflg = NULLSTR;
        String fxqflg = NULLSTR;
        if (MdaUtils.compareTo(flg0542, "Y") == 0 || MdaUtils.compareTo(flg0541, "Y") == 0) {
            //新增电商支付汇出汇款CPTECO,PANEL为CPTP1,与原汇款逻辑保持一致
            /**
             if Pos( "-CPTOPN-CPTADV-", $inifrm ) > 0 then
             **/
            /**
             if Pos( "-CPTOPN-CPTADV-CPTECO-", $inifrm ) > 0 then
             **/
            if (Strings.pos("-CPTOPN-CPTADV-CPTECO-CPTECI-", inifrm) > 0) {
                comflg = Utils.getFieldValue(txnVo, "hmdmod\\comflg");
                if (StringUtils.isNotEmpty(comflg) && !"Y".equals(comflg)) {
                    throw new PublicServiceException("请完成黑名单认证提交操作！");
                }
            }
            //----------slq------------
            if (Strings.pos("-LITOPN-LITAME-LITDCK-BCTDAV-BCTAME-LETOPN-LETAME-LETRSV-LETDRW-BOTDAV-BOTAME-CCTDAV-CLTDAV-LTTOPN-LTTAME-LTTDCK-GITOPN-GITAME-GETOPN-GETAME-GITODZ-", inifrm) > 0) {
                fxqflg = Utils.getFieldValue(txnVo, "hmdmod2\\fxqflg");
                if (StringUtils.isNotEmpty(fxqflg)) {
                    throw new PublicServiceException("请完成黑名单认证流程!");
                }
                comflg = Utils.getFieldValue(txnVo, "hmdmod\\comflg");
                if (StringUtils.isNotEmpty(comflg) && !"Y".equals(comflg)) {
                    throw new PublicServiceException("请完成黑名单认证提交操作！");
                }
            }
        }
        //Mtabut.rulePenN950()
        updateErsForFBK(txnVo);
        //Mtabut.rulePenN1500()
        Spt spt = txnVo.getSpt();
        if (spt != null && sysmodService.sptIsExeLoaded(spt.getSta())) {
            xreSetCor(spt);
        } else {
            //找到当前交易下所有的方法 HandleInterruptTransaction
            txnHoldHandlerManager.doHandler(txnHoldVo);
        }
    }

    /**
     * source:mtabut.0095.script
     */
    public void updateErsForFBK(BaseTransactionVo baseTransactionVo) {
        //!############################
        //!更新ERS数据，更新退回交易需要保存的国结业务编号
        //!暂时只对单证通系统做处理
        //!来自云平台的保函也进行处理
        //!############################
        String frame = SettleContext.getDirectTransName();
        Spt spt = baseTransactionVo.getSpt();
        if (spt != null && StringUtils.isNotEmpty(spt.getInr())) {
            spt = sptMapper.selectByPrimaryKey(spt);
            Smh smh = new Smh();
            smh.setInr(spt.getSmhinr());
            smh = smhMapper.selectByPrimaryKey(smh);
            if (smh != null) {
                if ("ERX".equals(smh.getCortyp())) {
                    Ers ers = ersMapper.getErsBySmhinr(smh.getInr());
                    if (ers != null && "Z00238".equals(ers.getMsgfrm())) {
                        if ("BRTSET".equals(frame) || "BCTSET".equals(frame)) {
                            String ownref1 = Utils.getFieldValue(baseTransactionVo, "trtcre\\trdgrp\\rec\\ownref");
                            String ownref2 = Utils.getFieldValue(baseTransactionVo, "dftcre\\dfdgrp\\rec\\ownref");
                            ers.setTxtinf(ownref1 + "_" + ownref2);
                        }
                        if (Strings.pos("-LITOPN-CPTOPN-GITOPN-NITOPN-GITPOP-NITPOP-WITOPN-WITOPE-JSTOPN-BOTDAV-DITOPN-BPTOPN-GITODZ-", frame) > 0) {
                            String path = Strings.mid(frame, 1, 2) + "DGRP//REC//OWNREF";
                            ers.setTxtinf(Utils.getFieldValue(baseTransactionVo, path.toLowerCase()));
                        }
                        if(Strings.pos("-HITOPN-HITPOP-", frame) > 0){
                            String path ="NIDGRP//REC//OWNREF";
                            ers.setTxtinf(Utils.getFieldValue(baseTransactionVo, path.toLowerCase()));
                        }

                        ersMapper.updateByPrimaryKeySelective(ers);
                    }
                }
                // 保存来自云平台的保函产生的业务编号
                if ("YPT".equals(smh.getCortyp())) {
                    Ers ers = ersMapper.getErsBySmhinr(smh.getInr());
                    if (ers != null && ("321".equals(ers.getMsgfrm()) || "YPT".equals(ers.getMsgfrm()))) {
                        ers.setTxtinf(Utils.getFieldValue(baseTransactionVo, "nidgrp//rec//ownref"));
                        ersMapper.updateByPrimaryKeySelective(ers);
                    }
                }
            }
        }
    }

    /**
     * source:mtabut.0038.script
     */
    public void xreSetCor(Spt spt) {
        //! marks the picked transaction as "errornous", if recalculation was not sucessful
        // resave picked transaction / already locked thus no errorchecking
        if (spt != null && StringUtils.isNotEmpty(spt.getObjinr())) {
            trnMapper.updateTrnXreflag(spt.getObjinr(), "e");
            // update picked SPT
            sysmodService.sptUpdateInDb(spt, "COR");
        }
        // Clear Spt
        Assert.notNull(spt);
        sysmodService.queUpdate("SPT", spt.getInr(), " ", " ");
        // und die Session auf `C`ancelled setzen - wie mache ich das mit legalen Methoden ?
        // SettleContext.getUserSession().getSsn().setSta("C");
    }
}
