package com.brilliance.isc.common.transaction.help.loadcontext;

import com.brilliance.isc.bo.Bch;
import com.brilliance.isc.common.component.DyncDaoService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.transaction.TransactionService;
import com.brilliance.isc.common.transaction.TransactionServiceFactory;
import com.brilliance.isc.common.transaction.vo.BaseTransactionVo;
import com.brilliance.isc.common.transaction.vo.TrnInfo;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.vo.BizInfoVo;
import com.brilliance.isc.common.vo.PtsptaVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

@Component("ceb")
public class CebTransactionLoadContext implements ITransactionLoadContext{

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SettleContext settleContext;

    @Autowired
    private TransactionServiceFactory transactionServiceFactory;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private DyncDaoService dyncDaoService;

    @Override
    public void loadContext(BaseTransactionVo bo) {
        String transName = bo.getTransName();
        logger.debug("加载交易{}上下文信息", transName);
        bo.reset();
        String sptinr = "";
        if (bo.getSpt() != null) {
            sptinr = bo.getSpt().getInr();
        }
        BizInfoVo rec = invokeBizInfo(bo);
        //无法获取业务主要信息，加载默认上下文
        if (rec == null) {
            settleContext.loadSettleSession(transName, "", "");
        }
        String objtyp = rec.getObjtyp();
        if (StringUtils.isEmpty(objtyp)) {
            throw new CommonServiceException("请明确该交易的业务类型");
        }
        String objinr = rec.getObjinr();
        logger.debug("交易业务类型为{}，业务主键为{}", objtyp, objinr);
        if (StringUtils.isEmpty(objinr)) {
            logger.debug("起头交易，需要根据客户获取归属机构");
            List<PtsptaVo> ptsList = new ArrayList<>();
            Object xxxgrp = Utils.getFieldValue(bo, objtyp.toLowerCase() + "grp");
            if (xxxgrp == null) {
                throw new CommonServiceException("无法获取交易下的"+objtyp.toLowerCase() + "grp,请核对交易模型是否正确");
            }
            Field[] fields = xxxgrp.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (PtsptaVo.class.equals(field.getType())) {
                    PtsptaVo ptspta = Utils.getFieldValue(xxxgrp, field.getName());
                    if (ptsptaToolComponent.ptsIsRolSet(ptspta)) {
                        ptsList.add(ptspta);
                    }
                }
            }
            settleContext.loadSettleSession(transName, "", rec, ptsList, sptinr);
        } else {
            String branchinr = dyncDaoService.dyncReadFieldByInr(objtyp, objinr, "branchinr");
            String bchkeyinr = dyncDaoService.dyncReadFieldByInr(objtyp, objinr, "bchkeyinr");
            logger.debug("交易归属机构为{}，经办机构为{}", objtyp, objinr, branchinr, bchkeyinr);
            if (StringUtils.isNotEmpty(branchinr) && StringUtils.isNotEmpty(bchkeyinr)) {
                settleContext.loadSettleSession(transName, branchinr, bchkeyinr, sptinr);
            } else {
                logger.debug("归属机构或者经办机构为空，需要根据客户获取归属机构");
                Map<String, PtsptaVo> maps = ptsptaToolComponent.getPtsptaList(objinr, objtyp);
                settleContext.loadSettleSession(transName, "", rec, maps.values().stream().collect(Collectors.toList()), sptinr);
            }
        }
        //设置自贸区标识
        Bch bch = SettleContext.getUserSession().getBch();
        if (bch != null) {
            if(bo.getTrnInfo() == null){
                bo.setTrnInfo(new TrnInfo());
            }
            bo.getTrnInfo().setZmqflg(bch.getZmqflg());
            logger.debug("该业务自贸区标识为{}", bch.getZmqflg());
        }
        logger.debug("加载上下文信息结束");
    }

    /**
     * 找到业务交易里面的bizinfo
     * @param bo
     * @return
     */
    private BizInfoVo invokeBizInfo(BaseTransactionVo bo) {
        try {
            String transName = bo.getTransName();
            TransactionService transactionService = transactionServiceFactory.getTransactionService(transName.toLowerCase());
            Class<?> clazz = transactionService.getClass();
            String methodName = "buildBizInfo";
            Method method = clazz.getDeclaredMethod(methodName, bo.getClass());
            if (method != null) {
                method.setAccessible(true);
                return (BizInfoVo)method.invoke(transactionService, bo);
            }
            return null;
        }catch (NoSuchMethodException e) {
            throw new CommonServiceException(e.getMessage());
        } catch (InvocationTargetException e) {
            throw new CommonServiceException(e.getMessage());
        } catch (IllegalAccessException e) {
            throw new CommonServiceException(e.getMessage());
        }
    }
}
