package com.brilliance.isc.common.api.fftmsg.service.impl;

import com.brilliance.isc.bo.Fftmsg;
import com.brilliance.isc.bo.Que;
import com.brilliance.isc.bo.Smh;
import com.brilliance.isc.bo.Spt;
import com.brilliance.isc.common.api.fftmsg.service.FftmsgService;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.lock.BizLocker;
import com.brilliance.isc.common.lock.LockInfo;
import com.brilliance.isc.common.quemod.vo.TaskStatus;
import com.brilliance.isc.constant.ErrorCode;
import com.brilliance.isc.exception.RestBizException;
import com.brilliance.isc.mda.dao.FftmsgMapper;
import com.brilliance.isc.mda.dao.QueMapper;
import com.brilliance.isc.mda.dao.SmhMapper;
import com.brilliance.isc.mda.dao.SptMapper;
import com.brilliance.isc.vo.FftmsgVo;
import com.brilliance.mda.runtime.mda.util.Dates;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
public class FftmsgServiceImpl implements FftmsgService {

    private final Logger logger = LoggerFactory.getLogger(FftmsgServiceImpl.class);

    @Autowired
    private FftmsgMapper fftmsgMapper;

    @Autowired
    private SptMapper sptMapper;

    @Autowired
    private SmhMapper smhMapper;

    @Autowired
    private QueMapper queMapper;

    @Autowired
    private BizLocker bizLocker;

    @Override
    public PageInfo queryFftmsg(FftmsgVo fftmsgvo) {
        Fftmsg fftmsg = new Fftmsg();
        BeanUtils.copyProperties(fftmsgvo, fftmsg);
        PageHelper.startPage(fftmsgvo.getPageNumber(), fftmsgvo.getPageSize()).setReasonable(true);
        List<Fftmsg> fftmsfList = fftmsgMapper.selectWithConditon(fftmsg);
        return new PageInfo(fftmsfList);
    }

    @Override
    public void bundFftmsg(FftmsgVo fftmsgvo) {
        LockInfo lockInfoFftmsg = null;
        LockInfo lockInfoSpt = null;
        try {
            //1.先锁定来报信息
            Fftmsg fftmsg = fftmsgMapper.selectByInr(fftmsgvo.getInr());
            lockInfoFftmsg = LockInfo.builder().objInr(fftmsg.getInr()).objType("FFTMSG")
                    .trnName(SettleContext.getTransName())
                    .usrId(SettleContext.getSessionUserVo().getLogName()).reentrant(true).build();
            if (!bizLocker.lock(lockInfoFftmsg)) {
                //锁定SPT失败
                logger.error("锁定报文失败[FFTMSG:{}]", fftmsg.getInr());
                LockInfo lockInfo = bizLocker.getLock(lockInfoFftmsg);
                if (lockInfo != null) {
                    throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "该笔报文已被" + lockInfo.getUsrId() + "使用" + lockInfo.getTrnName() + "锁定");
                }
                throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "锁定报文失败");
            }
            //2.先查询是否有该笔报文生成的待办记录,如果有待办，则需要将该笔待办改为删除状态
            String sptinr = sptMapper.selectBySmhinr(fftmsg.getSmhinr());
            Spt spt = sptMapper.getSptByInr(sptinr);
            if (spt != null) {
                lockInfoSpt = LockInfo.builder().objInr(spt.getInr()).objType("SPT")
                        .trnName(SettleContext.getTransName())
                        .usrId(SettleContext.getSessionUserVo().getLogName()).reentrant(true).build();
                if (!bizLocker.lock(lockInfoSpt)) {
                    //锁定SPT失败
                    logger.error("锁定待办任务失败[SPT:{}]", fftmsg.getInr());
                    LockInfo lockInfo = bizLocker.getLock(lockInfoSpt);
                    if (lockInfo != null) {
                        throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "该笔代办任务已被" + lockInfo.getUsrId() + "使用" + lockInfo.getTrnName() + "锁定");
                    }
                    throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "锁定待办任务失败");
                }
                Que que = queMapper.selectByObjtypAndObjinr("SPT", spt.getInr());
                if (que != null) {
                    if (TaskStatus.INCOMING.getValue().equals(que.getStatus())) {
                        que.setTardattim(Dates.now());
                        que.setOldstatus(que.getStatus());
                        que.setStatus(TaskStatus.DELETED.getValue());
                        queMapper.updateByPrimaryKey(que);

                        spt.setDelflg("X");
                        sptMapper.updateByPrimaryKey(spt);
                    }
                }
            }

            //3.更新FFTMSG表，与ordinr关联，在交易提交时，再根据ordinr查询该笔记录，更新smh和fftmsg的objtyp、objinr
            fftmsg.setOwnref(fftmsgvo.getOwnref());
            fftmsg.setObjtyp(fftmsgvo.getObjtyp());
            fftmsg.setObjinr(fftmsgvo.getObjinr());
            fftmsg.setOrdinr(fftmsgvo.getOrdinr());
            fftmsg.setBunsta("X");
            fftmsg.setBunusr(fftmsgvo.getBunusr());
            fftmsg.setBundattim(Dates.now());
            fftmsgMapper.updateByPrimaryKey(fftmsg);
        } finally {
            if (lockInfoSpt != null) {
                bizLocker.unlock(lockInfoSpt);
            }
            if (lockInfoFftmsg != null) {
                bizLocker.unlock(lockInfoFftmsg);
            }
        }
    }

    @Override
    public void unBundFftmsg(FftmsgVo fftmsgvo) {
        LockInfo lockInfoFftmsg = null;
        LockInfo lockInfoSpt = null;
        try {
            //1.先锁定来报信息
            Fftmsg fftmsg = fftmsgMapper.selectByInr(fftmsgvo.getInr());
            lockInfoFftmsg = LockInfo.builder().objInr(fftmsg.getInr()).objType("FFTMSG")
                    .trnName(SettleContext.getTransName())
                    .usrId(SettleContext.getSessionUserVo().getLogName()).reentrant(true).build();
            if (!bizLocker.lock(lockInfoFftmsg)) {
                //锁定SPT失败
                logger.error("锁定报文失败[FFTMSG:{}]", fftmsg.getInr());
                LockInfo lockInfo = bizLocker.getLock(lockInfoFftmsg);
                if (lockInfo != null) {
                    throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "该笔报文已被" + lockInfo.getUsrId() + "使用" + lockInfo.getTrnName() + "锁定");
                }
                throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "锁定报文失败");
            }
            //2.先查询是否有该笔报文生成的待办记录,如果有待办，则需要将该笔待办改为删除状态
            String sptinr = sptMapper.selectBySmhinr(fftmsg.getSmhinr());
            Spt spt = sptMapper.getSptByInr(sptinr);
            if (spt != null) {
                lockInfoSpt = LockInfo.builder().objInr(spt.getInr()).objType("SPT")
                        .trnName(SettleContext.getTransName())
                        .usrId(SettleContext.getSessionUserVo().getLogName()).reentrant(true).build();
                if (!bizLocker.lock(lockInfoSpt)) {
                    //锁定SPT失败
                    logger.error("锁定待办任务失败[SPT:{}]", fftmsg.getInr());
                    LockInfo lockInfo = bizLocker.getLock(lockInfoSpt);
                    if (lockInfo != null) {
                        throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "该笔代办任务已被" + lockInfo.getUsrId() + "使用" + lockInfo.getTrnName() + "锁定");
                    }
                    throw new RestBizException(ErrorCode.LOCK_BIZ_FAIL, "锁定待办任务失败");
                }
                Que que = queMapper.selectByObjtypAndObjinr("SPT", spt.getInr());
                if (que != null) {
                    if (TaskStatus.DELETED.getValue().equals(que.getStatus()) && TaskStatus.INCOMING.getValue().equals(que.getOldstatus())) {
                        que.setTardattim(Dates.now());
                        que.setOldstatus(que.getStatus());
                        que.setStatus(TaskStatus.INCOMING.getValue());
                        queMapper.updateByPrimaryKey(que);

                        spt.setDelflg("");
                        sptMapper.updateByPrimaryKey(spt);
                    }
                }
            }
            Smh smh = smhMapper.getSmhInfoBySptSmhinr(fftmsg.getSmhinr());
            if (smh != null) {
                smh.setObjtyp("");
                smh.setObjinr("");
                smh.setTrninr("");
                smhMapper.updateByPrimaryKey(smh);
            }
            //3.更新FFTMSG表
            fftmsg.setOwnref("");
            fftmsg.setObjtyp("");
            fftmsg.setObjinr("");
            fftmsg.setOrdinr("");
            fftmsg.setBunsta("");
            fftmsg.setUnbusr(fftmsgvo.getUnbusr());
            fftmsg.setUnbdattim(Dates.now());
            fftmsgMapper.updateByPrimaryKey(fftmsg);
        } finally {
            if (lockInfoSpt != null) {
                bizLocker.unlock(lockInfoSpt);
            }
            if (lockInfoFftmsg != null) {
                bizLocker.unlock(lockInfoFftmsg);
            }
        }
    }
}
