package com.brilliance.isc.common.api.codetable.service;

import com.brilliance.isc.bo.Adr;
import com.brilliance.isc.bo.Bopcod;
import com.brilliance.isc.bo.Cbe;
import com.brilliance.isc.bo.Stb;
import com.brilliance.isc.common.api.codetable.vo.CodetableRequestVo;
import com.brilliance.isc.common.api.codetable.vo.CodetableResponseVo;
import com.brilliance.isc.common.cache.adr.AdrCacheService;
import com.brilliance.isc.common.codetable.service.CodetableService;
import com.brilliance.isc.common.component.PtsptaToolComponent;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.glemod.service.GlemodService;
import com.brilliance.isc.common.setfeg.service.SetfegService;
import com.brilliance.isc.common.trndoc.service.DoceotService;
import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.mda.dao.*;
import com.brilliance.isc.vo.ResponseSet;
import com.brilliance.isc.vo.manager.StbVo;
import com.brilliance.mda.runtime.mda.CodetableItem;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class CodetableCommonServiceImpl implements CodetableCommonService {

    @Autowired
    private CodetableService codetableService;

    @Autowired
    private SetfegService setfegService;

    @Autowired
    private BopcodMapper bopcodMapper;

    @Autowired
    private ActMapper actMapper;

    @Autowired
    private TrmMapper trmMapper;

    @Autowired
    private GlemodService glemodService;

    @Autowired
    private CbeMapper cbeMapper;

    @Autowired
    private CnyctyMapper cnyctyMapper;

    @Autowired
    private BopctyMapper bopctyMapper;

    @Autowired
    private PtsptaToolComponent ptsptaToolComponent;

    @Autowired
    private DoceotService doceotService;

    @Autowired
    private AdrCacheService adrCacheService;

    @Override
    public CodetableResponseVo getSetmodCodetable(CodetableRequestVo request) {
        CodetableResponseVo codetableResponseVo = new CodetableResponseVo();
        codetableResponseVo.reset();
        //他行收费角色列表
        List<CodetableItem> foreignRoleSet = new ArrayList<>();
        String ownRole = "OWN";
        foreignRoleSet.add(new CodetableItem(codetableService.getTblLabel(ownRole, "ROLALL"), ownRole));
        if (request.getPtsList() != null) {
            ptsptaToolComponent.addPtspta(request.getPtsList(), request.getRec().getPntinr(), request.getRec().getPnttyp());
            //我行收费角色列表
            List<CodetableItem> roleSet = new ArrayList<>();
            request.getPtsList().forEach(ptsptaVo -> {
                if (StringUtils.isNotEmpty(ptsptaVo.getPtyinr())) {
                    String role = ptsptaVo.getRol();
                    String roleLabel = codetableService.getTblLabel(role, "ROLALL");
                    if (!includeRole(roleSet, role)) {
                        roleSet.add(new CodetableItem(roleLabel, role));
                        foreignRoleSet.add(new CodetableItem(roleLabel, role));
                    }
                }
            });
            codetableResponseVo.setRoleSet(roleSet);
        }
        codetableResponseVo.setForeignRoleSet(foreignRoleSet);
        String transName = request.getTransName();
        List<CodetableItem> feeCodeSet = setfegService.getAvbfeecod(transName);
        if (feeCodeSet != null) {
            codetableResponseVo.setFeeCodeSet(feeCodeSet);
        }
        return codetableResponseVo;
    }

    @Override
    public List<Bopcod> getBopcodList(CodetableRequestVo request) {
        String zmqflg = "";
        if (SettleContext.getUserSession().getBch() != null) {
            zmqflg = SettleContext.getUserSession().getBch().getZmqflg();
        }
        if (StringUtils.isEmpty(zmqflg)) {
            return bopcodMapper.getBopcodByCondition(request.getTyp(), "A", "D", request.getTrntyp());
        } else {
            return bopcodMapper.getBopcodByCondition(request.getTyp(), "A", "9", request.getTrntyp());
        }
    }

    @Override
    public List<Bopcod> getBopcod(CodetableRequestVo request) {
        String zmqflg = "";
        if (SettleContext.getUserSession().getBch() != null) {
            zmqflg = SettleContext.getUserSession().getBch().getZmqflg();
        }
        if (StringUtils.isEmpty(zmqflg)) {
            return bopcodMapper.getBopcod(request.getTyp(), "D", request.getTrntyp());
        } else {
            return bopcodMapper.getBopcod(request.getTyp(), "9", request.getTrntyp());
        }
    }

    @Override
    public List<StbVo> opnenConfig(StbVo stbVo) {
        List<StbVo> stbVoList = new ArrayList<>();
        Stb stb = new Stb();
        stb.setTbl(stbVo.getTbl());
        stb.setUil("EN");
        List<Stb> stbList = codetableService.getStbFromDb(stb);
        stbList.forEach(stb1 -> {
            StbVo stbVo1 = new StbVo();
            stbVo1.setTbl(stb1.getTbl());
            stbVo1.setSrt(stb1.getCod());
            stbVo1.setTblnam(stb1.getTxt());
            stbVoList.add(stbVo1);
        });
        return stbVoList;
    }

    @Override
    public List<String> getPriIntAcctList(String ptyinr, String cur, String dsp) {
        //利息转入账户列表
        List<String> list = new ArrayList<>();
        if ("LO".equals(dsp)) {
            List<String> extkeys = actMapper.selectExtkeyListByPtyinr(ptyinr, cur);
            if (extkeys != null && extkeys.size() > 0) {
                for (String extkey : extkeys) {
                    if (!list.contains(extkey)) {
                        list.add(extkey);
                    }
                }
            }
        } else {
            List<String> actVal = getAccountsByTrmcod(ptyinr, cur, dsp);
            if (CollectionUtils.isNotEmpty(actVal)) {
                list.addAll(actVal);
            }
        }
        return list;
    }

    @Override
    public Map<String, String> getMarginAcct(String objinr, String objtyp) {
        Map<String, String> maps = new LinkedHashMap<>();
        //通过cbe判断是否有定期保证金存在
        List<Cbe> cbes = cbeMapper.getCbeListByObjTypAndInrWithCbt(objtyp, objinr, "CCVIN");
        for (Cbe cbe : cbes) {
            String acc = StringUtils.trim(cbe.getAcc());
            if (StringUtils.isNotEmpty(acc)) {
                String rflg = "";
                if (Strings.len(acc) == 17) {
                    rflg = Strings.mid(acc, 7, 2);
                } else if (Strings.len(acc) == 21) {
                    rflg = Strings.mid(acc, 11, 2);
                }
                if (MdaUtils.compareTo(Strings.mid(acc, 1, 3), "ZMQ") == 0
                        || MdaUtils.compareTo(Strings.mid(acc, 1, 3), "NRA") == 0) {
                    rflg = Strings.mid(acc, 10, 2);
                }
                if (MdaUtils.compareTo(rflg, "81") == 0) {
                    maps.put(acc, cbe.getCur());
                }
            }
        }
        return maps;
    }

    @Override
    public ResponseSet getBopCnyctyCodeList(Map<String, Object> map) {
        String zmqflg = "";
        if (SettleContext.getUserSession().getBch() != null) {
            zmqflg = SettleContext.getUserSession().getBch().getZmqflg();
        }
        int pageNum = (int) map.get("pageNum");
        int pageSize = (int) map.get("pageSize");
        String countryCod = map.get("countryCod").toString();
        PageHelper.startPage(pageNum, pageSize);
        if ("X".equals(zmqflg)) {
            return new ResponseSet(new PageInfo(cnyctyMapper.getCnyctyCod(countryCod)));
        } else {
            return new ResponseSet(new PageInfo(bopctyMapper.getBopCtyCountryData(countryCod)));
        }
    }

    @Override
    public List<String> getAccListByTrmtyp(CodetableRequestVo request) {
        ArrayList<String> result = new ArrayList<>();
        String actVal = glemodService.getAvailAcc(request.getTrmtyp(), request.getCur(), request.getPtyinr(), BigDecimal.ZERO);
        if (StringUtils.isNotEmpty(actVal)) {
            Arrays.stream(actVal.split("[\\r\\n]{1,2}")).forEach(account -> {
                if (!result.contains(account)) {
                    result.add(account);
                }
            });
        }
        return result;
    }

    @Override
    public Map<String, String> getSwtInfo(String ptainr) {
        Map<String, String> map = new HashMap<>();
        String adrbicaut = doceotService.getPtmField(ptainr, "SWT", "AUTFLG");
        map.put("adrbicaut", adrbicaut);
        Adr adr = adrCacheService.selectByPtaInr(ptainr);
        if (adr != null) {
            map.put("adrbic", adr.getBic());
        }
        return map;
    }

    private List<String> getAccountsByTrmcod(String aplptyinr, String actcur, String trmcod) {
        //!根据科目代号取得账号
        //!=======================================================
        //!参数： trmcod    - 4位科目代号
        //!       aplptyinr - 账号对应的PTYINR
        //!       actcur    - 账号对应的币种
        //!返回： 账号
        //!=======================================================
        List<String> actList = new ArrayList<>();
        if (StringUtils.isNotEmpty(trmcod) && StringUtils.isNotEmpty(aplptyinr) && StringUtils.isNotEmpty(actcur)) {
            List<String> trmTyps = trmMapper.getTrmTypByTrmCod(trmcod);
            trmTyps.forEach(str -> {
                if (StringUtils.isNotEmpty(str)) {
                    String actVal = glemodService.getAvailAcc(str, actcur, aplptyinr, BigDecimal.ZERO);
                    if (StringUtils.isNotEmpty(actVal)) {
                        Arrays.stream(actVal.split("[\\r\\n]{1,2}")).forEach(account -> {
                            if (!actList.contains(account)) {
                                actList.add(account);
                            }
                        });
                    }
                }
            });
        }
        return actList;
    }

    private boolean includeRole(List<CodetableItem> list, String role) {
        boolean flag = false;
        for (CodetableItem codetableItem : list) {
            if (role.equals(codetableItem.getValue())) {
                flag = true;
                break;
            }
        }
        return flag;
    }
}
