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

import com.brilliance.isc.bo.*;
import com.brilliance.isc.bo.finance.RelWhjDatasBo;
import com.brilliance.isc.bo.model.Blcgrp;
import com.brilliance.isc.bo.model.Zxbgrp;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.lock.BizLocker;
import com.brilliance.isc.common.lock.LockInfo;
import com.brilliance.isc.common.user.service.UserService;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.common.whj.service.WhjService;
import com.brilliance.isc.constant.ErrorCode;
import com.brilliance.isc.esb.model.inner.InnerRes;
import com.brilliance.isc.esb.model.inner.InnerResWhj;
import com.brilliance.isc.esb.model.whj.res.sinosure.BankApply;
import com.brilliance.isc.esb.model.whj.res.sinosure.Invoices;
import com.brilliance.isc.exception.RestBizException;
import com.brilliance.isc.mda.dao.*;
import com.brilliance.isc.vo.finance.BlcStoreVo;
import com.brilliance.isc.vo.finance.ZxbStoreVo;
import com.brilliance.isc.vo.manager.UserVo;
import com.brilliance.isc.vo.manager.UsrntfVo;
import com.brilliance.mda.runtime.mda.util.Formats;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

@Service
public class WhjServiceImpl implements WhjService {

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

    private static final String WHJ_SUCCESS = "0";

    private static final String ALL_USR = "All Usr";

    private static final String ALL_ONLINE_USR = "All Online Usr";

    @Resource
    SettleContext settleContext;

    @Autowired
    private BizLocker bizLocker;

    @Autowired
    private CounterService counterService;

    @Resource
    private UsrntfMapper usrntfMapper;

    @Resource
    private UserService userService;

    @Autowired
    private WhjBlcToolComponent whjBlcToolComponent;

    @Autowired
    private WhjZxbToolComponent whjZxbToolComponent;

    @Autowired
    private FinMapper finMapper;

    @Autowired
    private CusMapper cusMapper;

    @Autowired
    private IneMapper ineMapper;

    @Autowired
    private FsaMapper fsaMapper;

    @Override
    public Blcgrp getBlcgrpByInr(String inr) {
        Blcgrp blcgrp = new Blcgrp();
        blcgrp.reset();

        Fin fin = blcgrp.getRec();
        fin.setInr(inr);
        fin = finMapper.selectByPrimaryKey(fin);
        if (fin != null) {
            blcgrp.setRec(fin);
        }

        Fsa fsa = blcgrp.getFsa();
        String validinr = fsaMapper.selectValidInr(inr);
        fsa = fsaMapper.selectByInr(validinr);
        if (fsa != null) {
            blcgrp.setFsa(fsa);
        }

        List<Ine> inelst = ineMapper.selectListByFininr(inr);
        if (inelst != null) {
            blcgrp.setInelst(inelst);
        }

        List<Cus> cuslst = cusMapper.selectListByFininr(inr);
        if (cuslst != null) {
            blcgrp.setCuslst(cuslst);
        }

        return blcgrp;
    }

    @Override
    public Zxbgrp getZxbgrpByInr(String inr) {
        Zxbgrp zxbgrp = new Zxbgrp();
        zxbgrp.reset();

        Fin fin = zxbgrp.getRec();
        fin.setInr(inr);
        fin = finMapper.selectByPrimaryKey(fin);
        if (fin != null) {
            zxbgrp.setRec(fin);
        }

        Fsa fsa = zxbgrp.getFsa();
        String validinr = fsaMapper.selectValidInr(inr);
        fsa = fsaMapper.selectByInr(validinr);
        if (fsa != null) {
            zxbgrp.setFsa(fsa);
        }

        List<Ine> inelst = ineMapper.selectListByFininr(inr);
        if (inelst != null) {
            zxbgrp.setInelst(inelst);
        }

        List<Cus> cuslst = cusMapper.selectListByFininr(inr);
        if (cuslst != null) {
            zxbgrp.setCuslst(cuslst);
        }

        return zxbgrp;
    }

    @Override
    public boolean handleResult(Fin fin, Fsa fsa, String typ, InnerRes<InnerResWhj> innerRes) {
        String code = innerRes.header.code;
        String description = innerRes.header.description;
        if (WHJ_SUCCESS.equals(code)) {
            if (innerRes.DATA.detail != null) {
                if (!"CXZ".equals(typ)) {
                    BankApply bankApply = (BankApply) Utils.getObjectByMap(BankApply.class.getName(), (LinkedHashMap) innerRes.DATA.detail);
                    if (!MdaUtils.isEmpty(bankApply.getSafeAssetId())) {
                        fin.setWgrref(bankApply.getSafeAssetId());
                    }
                }
            }
            if ("RTY".equals(typ)) {
                fsa.setHinmsg("操作成功");
            } else {
                if ("RCV".equals(typ)) {
                    fsa.setAplret("D");
                    fsa.setHinmsg("还款金额" + fin.getRcvcur() + Formats.fmtAmount(fin.getRcvamt(), fin.getRcvcur()));
                } else if ("CXZ".equals(typ)) {
                } else {
                    fsa.setAplret("D");
                    fsa.setHinmsg("操作成功");
                }
            }
            return true;
        } else {
            if (!"RTY".equals(typ)) {
                fsa.setAplret("O");
            }
            fsa.setBlcsta("STAGE");
            fsa.setHinmsg("操作失败，失败原因：" + description);
            if ("AME".equals(typ)) {
                if (innerRes.DATA.detail != null) {
                    BankApply bankApply = (BankApply) Utils.getObjectByMap(BankApply.class.getName(), (LinkedHashMap) innerRes.DATA.detail);
                    List<Invoices> invoicesList = bankApply.getInvoices();
                    if (invoicesList != null) {
                        StringBuffer buffer = new StringBuffer();
                        for (Invoices invoices : invoicesList) {
                            buffer = buffer.append(invoices.getInvoiceCode()).append("\t").append(invoices.getIsAvailable()).append("\t").append(invoices.getNotAvailableReason()).append("\n");
                        }
                        fsa.setHinmsg(buffer.toString());
                    }
                }
            }
            return false;
        }
    }

    @Override
    public void setFsaHandType(Fsa fsa, String hndtyp) {
        String fsainr = fsa.getInr();
        if (!MdaUtils.isEmpty(fsainr)) {
            fsaMapper.deleteByInr(fsainr);

            if ("APL".equals(hndtyp) || "CHK".equals(hndtyp) || "RFU".equals(hndtyp) || "REG".equals(hndtyp) || "RCV".equals(hndtyp) || "RTY".equals(hndtyp) || "UND".equals(hndtyp) || "ABA".equals(hndtyp) || "AME".equals(hndtyp) || "CHG".equals(hndtyp)) {
                fsa.setSta("");
                fsa.setBlcsta("");
            }
            fsa.setInr(counterService.dbCounterFormat("FSA"));
            fsa.setHndtyp(hndtyp);
            if ("CXZ".equals(hndtyp)) {
                fsa.setHndtyp("KJC");
            }
            fsa.setUpdtim(new Date());
            if (SettleContext.getUserSession() == null) {
                settleContext.simpleLoadSettleSession();
            }
            fsa.setHndusr(SettleContext.getUserSession().getUsr().getExtkey());
            fsa.setIsvalid("Y");
            fsaMapper.insert(fsa);
        }
    }

    @Override
    public void lockFin(Fin fin) {
        if (fin == null || MdaUtils.isEmpty(fin.getInr())) {
            return;
        }
        //锁定FIN
        LockInfo lockInfoFin = LockInfo.builder().objInr(fin.getInr()).objType("FIN").trnName(SettleContext.getTransName()).usrId(SettleContext.getSessionUserVo().getLogName()).reentrant(true).build();
        if (!bizLocker.lock(lockInfoFin.genLockKey(), lockInfoFin.genLockValue(), 1800)) {
            //锁定SPT失败
            logger.error("锁定待办任务失败[FIN:{}]", fin.getInr());
            LockInfo lockInfo = bizLocker.getLock(lockInfoFin);
            if (lockInfo != null) {
                throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "该笔业务数据已被" + lockInfo.getUsrId() + "使用" + lockInfo.getTrnName() + "锁定");
            }
            throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "锁定待办任务失败");
        }
    }

    @Override
    public void unLockFin(Fin fin) {
        if (fin == null || MdaUtils.isEmpty(fin.getInr())) {
            return;
        }
        LockInfo lockInfoFin = LockInfo.builder().objInr(fin.getInr()).objType("FIN").trnName(SettleContext.getTransName()).usrId(SettleContext.getSessionUserVo().getLogName()).reentrant(true).build();
        bizLocker.unlock(lockInfoFin);
    }

    @Override
    public void unlockAllOfTrans(String userId) {
        bizLocker.unlockAllOfTrans("WHJFIN", userId);
    }

    @Override
    public void loanRegister(Trn trn) {
        Fin fin = finMapper.selectByRelref(trn.getOwnref());
        if (fin != null) {
            if ("Y".equals(fin.getZxbflg())) {
                loanReg_ZXB(trn.getObjinr());
            } else {
                loanReg_BLC(trn.getObjinr());
            }
        }
    }

    @Override
    public void recRegister(Trn trn) {
        Fin fin = finMapper.selectByRelref(trn.getOwnref());
        if (fin != null) {
            if ("Y".equals(fin.getZxbflg())) {
                recReg_ZXB(trn.getObjinr());
            } else {
                recReg_BLC(trn.getObjinr());
            }
        }
    }

    @Override
    public void loanReg_BLC(String bpdinr) {
        //!直接放款登记
        RelWhjDatasBo chkbcl = finMapper.loadChkBLC(bpdinr);
        if (chkbcl != null) {
            Fin fin = finMapper.selectByInr(chkbcl.getFininr());
            Fsa fsa = fsaMapper.selectByInr(chkbcl.getFsainr());
            BlcStoreVo blcStoreVo = new BlcStoreVo();
            blcStoreVo.reset();
            blcStoreVo.getRecgrp().setRec(fin);
            blcStoreVo.getRecgrp().setFsa(fsa);
            if (whjBlcToolComponent.buttonHandle1("REG", blcStoreVo)) {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("直接放款登记成功");
                sendUsrntf(usrntfVo);
            } else {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("直接放款登记" + blcStoreVo.getRecgrp().getFsa().getHinmsg());
                sendUsrntf(usrntfVo);
            }
        }
    }

    @Override
    public void recReg_BLC(String bpdinr) {
        //! 还款登记
        RelWhjDatasBo chkbcl = finMapper.loadRegBLC(bpdinr);
        if (chkbcl != null) {
            Fin fin = finMapper.selectByInr(chkbcl.getFininr());
            Fsa fsa = fsaMapper.selectByInr(chkbcl.getFsainr());
            BlcStoreVo blcStoreVo = new BlcStoreVo();
            blcStoreVo.reset();
            blcStoreVo.getRecgrp().setRec(fin);
            blcStoreVo.getRecgrp().setFsa(fsa);
            if (whjBlcToolComponent.buttonHandle1("RCV", blcStoreVo)) {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("还款登记成功");
                sendUsrntf(usrntfVo);
            } else {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("还款登记" + blcStoreVo.getRecgrp().getFsa().getHinmsg());
                sendUsrntf(usrntfVo);
            }
        }
    }

    @Override
    public void loanReg_ZXB(String bpdinr) {
        //!直接放款登记
        RelWhjDatasBo chkbcl = finMapper.loadChkZXB(bpdinr);
        if (chkbcl != null) {
//            Fin fin = finMapper.selectByInr(chkbcl.getFininr());
//            Fsa fsa = fsaMapper.selectByInr(chkbcl.getFsainr());
            ZxbStoreVo zxbStoreVo = new ZxbStoreVo();
            zxbStoreVo.reset();
//            zxbStoreVo.getRecgrp().setRec(fin);
//            zxbStoreVo.getRecgrp().setFsa(fsa);
            Zxbgrp zxbgrp = getZxbgrpByInr(chkbcl.getFininr());
            zxbStoreVo.setRecgrp(zxbgrp);
            if (whjZxbToolComponent.buttonHandle1("REG", zxbStoreVo)) {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("放款登记成功");
                sendUsrntf(usrntfVo);
            } else {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("放款登记" + zxbStoreVo.getRecgrp().getFsa().getHinmsg());
                sendUsrntf(usrntfVo);
            }
        }
    }

    @Override
    public void recReg_ZXB(String bpdinr) {
        //! 还款登记
        RelWhjDatasBo chkbcl = finMapper.loadRegBLC(bpdinr);
        if (chkbcl != null) {
            ZxbStoreVo zxbStoreVo = new ZxbStoreVo();
            zxbStoreVo.reset();
            Zxbgrp zxbgrp = getZxbgrpByInr(chkbcl.getFininr());
            zxbStoreVo.setRecgrp(zxbgrp);
            if (whjZxbToolComponent.buttonHandle1("RCV", zxbStoreVo)) {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("放款登记成功");
                sendUsrntf(usrntfVo);
            } else {
                UsrntfVo usrntfVo = new UsrntfVo();
                usrntfVo.setSndusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setRcvusr(SettleContext.getSessionUserVo().getLogName());
                usrntfVo.setNtfsta("9");
                usrntfVo.setNtftxt("放款登记" + zxbStoreVo.getRecgrp().getFsa().getHinmsg());
                sendUsrntf(usrntfVo);
            }
        }
    }

    @Override
    public void sendUsrntf(UsrntfVo usrntfVo) {
        if (ALL_USR.equalsIgnoreCase(usrntfVo.getUsrtyp())) {
            // 为所有用户新建通知
            List<UserVo> userVoList = userService.getAllUser();
            List<Usrntf> usrntfList = new ArrayList<>();
            for (UserVo userVo : userVoList) {
                Usrntf usrntf = new Usrntf();
                if (userVo.getLogName().equalsIgnoreCase(usrntfVo.getSndusr())) {
                    usrntf.setInr(counterService.dbCounterFormat("USRNTF"));
                    usrntf.setSndusr(usrntfVo.getSndusr());
                    usrntf.setRcvusr("ALL USER");
                    usrntf.setNtfsta(usrntfVo.getNtfsta());
                    usrntf.setNtftxt(usrntfVo.getNtftxt());
                    usrntf.setQfsta("A");
                    usrntf.setMac("0");
                } else {
                    usrntf.setInr(counterService.dbCounterFormat("USRNTF"));
                    usrntf.setSndusr(usrntfVo.getSndusr());
                    usrntf.setRcvusr(userVo.getLogName());
                    usrntf.setNtfsta(usrntfVo.getNtfsta());
                    usrntf.setNtftxt(usrntfVo.getNtftxt());
                    usrntf.setQfsta("A");
                    usrntf.setMac("0");
                }
                usrntfList.add(usrntf);
            }
            usrntfMapper.batchInsert(usrntfList);
        } else if (ALL_ONLINE_USR.equalsIgnoreCase(usrntfVo.getUsrtyp())) {
            // TODO 为所有在线用户新建通知
            List<UserVo> userVoList = userService.getAllUser();
            List<Usrntf> usrntfList = new ArrayList<>();
            for (UserVo userVo : userVoList) {
                Usrntf usrntf = new Usrntf();
                if (userVo.getLogName().equalsIgnoreCase(usrntfVo.getSndusr())) {
                    usrntf.setInr(counterService.dbCounterFormat("USRNTF"));
                    usrntf.setSndusr(usrntfVo.getSndusr());
                    usrntf.setRcvusr("ONLINE USER");
                    usrntf.setNtfsta(usrntfVo.getNtfsta());
                    usrntf.setNtftxt(usrntfVo.getNtftxt());
                    usrntf.setQfsta("O");
                    usrntf.setMac("0");
                } else {
                    usrntf.setInr(counterService.dbCounterFormat("USRNTF"));
                    usrntf.setSndusr(usrntfVo.getSndusr());
                    usrntf.setRcvusr(userVo.getLogName());
                    usrntf.setNtfsta(usrntfVo.getNtfsta());
                    usrntf.setNtftxt(usrntfVo.getNtftxt());
                    usrntf.setQfsta("O");
                    usrntf.setMac("0");
                }
                usrntfList.add(usrntf);
            }
            usrntfMapper.batchInsert(usrntfList);
        } else {
            Usrntf usrntf = new Usrntf();
            usrntf.setInr(counterService.dbCounterFormat("USRNTF"));
            usrntf.setSndusr(usrntfVo.getSndusr());
            usrntf.setRcvusr(usrntfVo.getRcvusr());
            usrntf.setNtfsta(usrntfVo.getNtfsta());
            usrntf.setNtftxt(usrntfVo.getNtftxt());
            usrntf.setQfsta("S");
            usrntf.setMac("0");
            usrntfMapper.insert(usrntf);
        }
    }

}
