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


import com.brilliance.mda.runtime.mda.util.MdaUtils;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import com.brilliance.isc.bo.Pbl;
import com.brilliance.isc.bo.Que;
import com.brilliance.isc.bo.Spt;
import com.brilliance.isc.bo.Trn;
import com.brilliance.isc.common.util.BopUtils;
import com.brilliance.isc.common.bopset.service.RmbbopService;
import com.brilliance.isc.common.context.SpringEnvContext;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.rmbbop.common.AbstractRmb;
import com.brilliance.isc.common.rmbbop.entity.*;
import com.brilliance.isc.common.rmbbop.vo.Rmbbop;
import com.brilliance.isc.mda.dao.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

@Service
public class RmbbopServiceImpl implements RmbbopService {
    private static final Logger logger = LoggerFactory.getLogger(RmbbopServiceImpl.class);
    @Autowired
    private PblMapper pblMapper;
    @Autowired
    private QueMapper queMapper;
    @Autowired
    private SptMapper sptMapper;
    @Autowired
    private TdaMapper tdaMapper;
    @Autowired
    private TdbMapper tdbMapper;
    @Autowired
    private TcrMapper tcrMapper;
    @Autowired
    private TdoMapper tdoMapper;
    @Autowired
    private TdqMapper tdqMapper;
    @Autowired
    private TbzMapper tbzMapper;
    @Autowired
    private TbkMapper tbkMapper;

    @Override
    public void rmbRePair(String trninr) {
        logger.info(String.format("开始 回滚跨境担保信息trninr :%s", trninr));
        if (MdaUtils.isEmpty(trninr)) {
            return;
        }
        List<Pbl> list = pblMapper.selectinrByTrninr(trninr);
        if (list.isEmpty()) {
            return;
        }
        Pbl pbl;
        String objtyp;
        String objinr;
        for (Pbl value : list) {
            pbl = value;
            objtyp = pbl.getObjtyp();
            objinr = pbl.getObjinr();

            switch (objtyp) {
                case "TDA":
                    Tda tda = new Tda();
                    tda.setInr(objinr);
                    tdaMapper.deleteByPrimaryKey(tda);
                    break;
                case "TDB":
                    Tdb tdb = new Tdb();
                    tdb.setInr(objinr);
                    tbkMapper.deleteByobjtypAndobjinr("TDB", objinr);
                    tdbMapper.deleteByPrimaryKey(tdb);
                    break;
                case "TCR":
                    Tcr tcr = new Tcr();
                    tcr.setInr(objinr);
                    tbzMapper.deleteByobjtypAndobjinr("TCR", objinr);
                    tcrMapper.deleteByPrimaryKey(tcr);
                    break;
                case "TDO":
                    Tdo tdo = new Tdo();
                    tdo.setInr(objinr);
                    tdoMapper.deleteByPrimaryKey(tdo);
                    break;
                case "TDQ":
                    Tdq tdq = new Tdq();
                    tdq.setInr(objinr);
                    tdqMapper.deleteByPrimaryKey(tdq);
                    break;
            }
            pblMapper.deleteByPrimaryKey(pbl);
        }
        logger.info("回滚跨境担保信息成功");


    }

    @Override
    public void releaseRmbbop(Trn trn) {
        String trnInr = trn.getInr();
        if (StringUtils.isNotEmpty(trnInr)) {
            List<Pbl> pblList = pblMapper.selectinrByTrninr(trnInr);
            for (Pbl pbl : pblList) {
                if ("W".equals(pbl.getRelflg())) {
                    pblMapper.updateRelflgByInr(pbl.getInr());
                }
            }
        }
        List<Spt> sptList = sptMapper.selectByCreobjtypAndCreobjinr("TRN", trn.getInr());
        sptList.forEach(spt -> {
            spt.setDelflg("");
            sptMapper.updateByPrimaryKey(spt);
            Que que = new Que();
            que.setObjtyp("SPT");
            que.setObjinr(spt.getInr());
            que.setConobjtyp(trn.getObjtyp());
            que.setConobjinr(trn.getObjinr());
            que = queMapper.selectByQueAndCpd(que);
            que.setHldflg("");
            queMapper.updateByPrimaryKey(que);
        });
    }

    @Override
    public void calcRmbbop(Rmbbop rmbbop) {
        Map<String, Object> modifiedFields = BopUtils.backupModifiedFields(rmbbop);
        invokeMethod(rmbbop, "updrmb");
        BopUtils.restoreModifiedFields(rmbbop, modifiedFields);
    }


    @Override
    public void saveRmbbop(Rmbbop rmbbop) {
        String methodName = "2".equals(rmbbop.getAloneflg()) ? "saveSpt" : "save";
        invokeMethod(rmbbop, methodName);
    }

    private void invokeMethod(Rmbbop rmbbop, String methodName) {
        try {
            Field[] fields = rmbbop.getClass().getDeclaredFields();
            for (Field field : fields) {
                Class<?> fieldType = field.getType();
                if (AbstractRmb.class.isAssignableFrom(fieldType)) {
                    field.setAccessible(true);
                    AbstractRmb abstractRmb = (AbstractRmb) field.get(rmbbop);
                    if (abstractRmb != null) {
                        if (StringUtils.equals(abstractRmb.getRmbflg(), "1")) {
                            Object bean = SpringEnvContext.getBean(abstractRmb.getObjtyp().toLowerCase());
                            Method method = bean.getClass().getDeclaredMethod(methodName, abstractRmb.getClass());
                            method.invoke(bean, abstractRmb);
                        } else {
                            Method clear = fieldType.getDeclaredMethod("clear");
                            clear.invoke(abstractRmb);
                        }
                    }
                }
            }
        } catch (IllegalAccessException | NoSuchMethodException e) {
            throw new CommonServiceException(methodName + "执行异常：" + e.toString());
        } catch (InvocationTargetException e) {
            Throwable targetException = e.getTargetException();
            targetException.printStackTrace();
            throw new CommonServiceException(methodName + "执行异常：" + targetException.toString());
        }
    }

}
