package com.hfkj.service.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.dao.BsAuditMapper;
import com.hfkj.entity.BsAudit;
import com.hfkj.entity.BsAuditExample;
import com.hfkj.entity.BsMerRateApply;
import com.hfkj.entity.BsMerSettleAcctApply;
import com.hfkj.model.BsAuditModel;
import com.hfkj.service.BsAuditService;
import com.hfkj.service.BsMerRateApplyService;
import com.hfkj.service.BsMerSettleAcctApplyService;
import com.hfkj.sysenum.AuditStatusEnum;
import com.hfkj.sysenum.AuditVocationalWorkType;
import com.hfkj.sysenum.MerRateApplyStatusEnum;
import com.hfkj.sysenum.MerSettleAcctApplyStatus;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @className: BsAuditServiceImpl
 * @author: HuRui
 * @date: 2023/5/9
 **/
@Service("auditService")
public class BsAuditServiceImpl implements BsAuditService {

    @Resource
    private BsAuditMapper auditMapper;
    @Resource
    private BsMerSettleAcctApplyService merSettleAcctApplyService;
    @Resource
    private BsMerRateApplyService merRateApplyService;

    @Override
    public void editData(BsAudit audit) {
        if (audit.getId() == null) {
            audit.setCreateTime(new Date());
            audit.setUpdateTime(new Date());
            auditMapper.insert(audit);
        } else {
            audit.setUpdateTime(new Date());
            auditMapper.updateByPrimaryKey(audit);
        }
    }

    @Override
    public BsAudit createAudit(BsAudit audit) {
        editData(audit);
        return audit;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void approve(Long auditId) {
        // 查询审核详情
        BsAudit audit = getAuditDetailById(auditId);
        if (audit == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的审批");
        }
        if (!audit.getStatus().equals(AuditStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "审批状态处于待审核");
        }
        audit.setStatus(AuditStatusEnum.status2.getNumber());
        editData(audit);

        approveCallback(audit);
    }

    @Override
    public void approveCallback(BsAudit audit) {
        if (audit.getVocationalWorkType().equals(AuditVocationalWorkType.type1.getNumber())) {
            BsMerSettleAcctApply acctApply = merSettleAcctApplyService.getApplyById(audit.getAuditObjectId());
            if (acctApply != null) {
                acctApply.setStatus(MerSettleAcctApplyStatus.status5.getNumber());
                merSettleAcctApplyService.applyUpdateSettleAcct(acctApply);
            }

        } else if (audit.getVocationalWorkType().equals(AuditVocationalWorkType.type2.getNumber())) {
            BsMerRateApply merRateApply = merRateApplyService.getRateApplyById(audit.getAuditObjectId());
            if (merRateApply != null) {
                merRateApply.setStatus(MerRateApplyStatusEnum.status5.getNumber());
                merRateApplyService.approveCallback(merRateApply);
            }
        }
    }

    @Override
    public void reject(Long auditId, String rejectReason) {
        // 查询审核详情
        BsAudit audit = getAuditDetailById(auditId);
        if (audit == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的审批");
        }
        if (!audit.getStatus().equals(AuditStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "审批状态处于待审核");
        }
        audit.setStatus(AuditStatusEnum.status3.getNumber());
        audit.setRejectReason(rejectReason);
        editData(audit);

        rejectCallback(audit);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void rejectCallback(BsAudit audit) {
        if (audit.getVocationalWorkType().equals(AuditVocationalWorkType.type1.getNumber())) {
            BsMerSettleAcctApply acctApply = merSettleAcctApplyService.getApplyById(audit.getAuditObjectId());
            if (acctApply != null) {
                acctApply.setRejectReason(audit.getRejectReason());
                acctApply.setStatus(MerSettleAcctApplyStatus.status4.getNumber());
                merSettleAcctApplyService.editData(acctApply);
            }
        } else if (audit.getVocationalWorkType().equals(AuditVocationalWorkType.type2.getNumber())) {
            BsMerRateApply merRateApply = merRateApplyService.getRateApplyById(audit.getAuditObjectId());
            if (merRateApply != null) {
                merRateApply.setRejectReason(audit.getRejectReason());
                merRateApply.setStatus(MerRateApplyStatusEnum.status4.getNumber());
                merRateApplyService.editData(merRateApply);
            }
        }
    }

    @Override
    public BsAudit getAuditDetailById(Long auditId) {
        return auditMapper.selectByPrimaryKey(auditId);
    }

    @Override
    public BsAuditModel getAuditDetailByNo(String auditNo) {
        BsAuditExample example = new BsAuditExample();
        example.createCriteria().andAuditNoEqualTo(auditNo).andStatusNotEqualTo(AuditStatusEnum.status0.getNumber());
        List<BsAudit> list = auditMapper.selectByExample(example);
        if (list.size() == 0) {
            return null;
        }
        BsAuditModel auditModel = new BsAuditModel();
        BeanUtils.copyProperties(list.get(0), auditModel);

        if (auditModel.getVocationalWorkType().equals(AuditVocationalWorkType.type1.getNumber())) {
            auditModel.setAuditObject(merSettleAcctApplyService.getApplyById(auditModel.getAuditObjectId()));
        }
        return auditModel;
    }

    @Override
    public List<BsAudit> getAuditList(Map<String, Object> param) {
        BsAuditExample example = new BsAuditExample();
        BsAuditExample.Criteria criteria = example.createCriteria().andStatusNotEqualTo(AuditStatusEnum.status0.getNumber());

        if (MapUtils.getInteger(param, "auditNo") != null) {
            criteria.andAuditNoLike("%" + MapUtils.getInteger(param, "auditNo") + "%");
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        if (MapUtils.getInteger(param, "opUserId") != null) {
            criteria.andOpUserIdEqualTo(MapUtils.getLong(param, "opUserId"));
        }

        if (MapUtils.getLong(param, "reviewedUserId") != null) {
            criteria.andReviewedUserIdEqualTo(MapUtils.getLong(param, "reviewedUserId"));
        }

        example.setOrderByClause("create_time desc");
        return auditMapper.selectByExample(example);
    }
}
