package com.persagy.dmp.rwd.version.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.persagy.dmp.common.constant.ValidEnum;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.dmp.rwd.version.dao.VersionDefineMapper;
import com.persagy.dmp.rwd.version.entity.VersionDefine;
import com.persagy.dmp.rwd.version.service.IObjectInfoHistoryService;
import com.persagy.dmp.rwd.version.service.IObjectTypeHistoryService;
import com.persagy.dmp.rwd.version.constant.VersionState;
import com.persagy.dmp.rwd.version.service.IVersionDefineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * 版本定义实现类
 * @author Charlie Yu
 * @date 2021-06-23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class VersionDefineServiceImpl implements IVersionDefineService {

    @Resource
    private VersionDefineMapper dao;
    @Autowired
    private IObjectTypeHistoryService typeHistoryService;
    @Autowired
    private IObjectInfoHistoryService infoHistoryService;

    @Override
    public VersionDefine insertVersion(VersionDefine vo) {
        validate(vo);
        // 查询最新版本
        VersionDefine lastVersion = queryLastVersion();
        if(lastVersion != null) {
            vo.setLastVersion(lastVersion.getVersion());
            vo.setShowOrder(lastVersion.getShowOrder() + 1);
            // 修改原最新版本标识
            lastVersion.setLastFlag(false);
            dao.updateById(lastVersion);
            // 生成此版本数据字典
            typeHistoryService.copyByVersion(lastVersion.getVersion(), vo.getVersion());
            infoHistoryService.copyByVersion(lastVersion.getVersion(), vo.getVersion());
        } else {
            vo.setShowOrder(1);
        }
        // 默认值
        vo.setState(VersionState.TO_CONFIRM.getIndex());
        vo.setLastFlag(true);
        dao.insert(vo);
        return vo;
    }

    /**
     * 查询最新版本
     * @return
     */
    private VersionDefine queryLastVersion() {
        LambdaQueryWrapper<VersionDefine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VersionDefine::getValid, ValidEnum.TRUE.getType());
        queryWrapper.eq(VersionDefine::getLastFlag, true);
        return dao.selectOne(queryWrapper);
    }

    /**
     * 保存校验
     * @param vo
     */
    private void validate(VersionDefine vo) {
        // 新增校验
        if(StrUtil.isBlank(vo.getId())) {
            if(hasFlowingVersion()) {
                throw new BusinessException("存在未发布完成版本，不可重复创建!");
            }
        }
        // 重名校验
        LambdaQueryWrapper<VersionDefine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VersionDefine::getValid, ValidEnum.TRUE.getType());
        queryWrapper.eq(VersionDefine::getVersion, vo.getVersion());
        if(StrUtil.isNotBlank(vo.getId())) {
            queryWrapper.ne(VersionDefine::getId, vo.getId());
        }
        Integer count = dao.selectCount(queryWrapper);
        if(count != null && count >0) {
            throw new BusinessException("版本编号已存在!");
        }
    }

    /**
     * 是否存在流程中版本
     * 流程中：待确认、待发布、发布中
     * @return
     */
    private boolean hasFlowingVersion() {
        // 流程中的状态
        List<String> flowingState = Arrays.asList(VersionState.TO_CONFIRM.getIndex(),
                VersionState.TO_PUBLISH.getIndex(), VersionState.PUBLISHING.getIndex());
        // 查询
        LambdaQueryWrapper<VersionDefine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(VersionDefine::getState, flowingState);
        queryWrapper.eq(VersionDefine::getValid, ValidEnum.TRUE.getType());
        Integer count = dao.selectCount(queryWrapper);
        return count != null && count > 0;
    }

    @Override
    public VersionDefine updateVersion(VersionDefine vo) {
        validate(vo);
        dao.updateById(vo);
        return vo;
    }

    @Override
    public void deleteVersion(String id) {
        VersionDefine vo = dao.selectById(id);
        if(VersionState.TO_CONFIRM.getIndex() != vo.getState()) {
            throw new BusinessException("版本不是待确认状态，不允许删除!");
        }
        // 版本中存在维护记录时，不允许删除
        typeHistoryService.validateOnVersionDelete(vo.getVersion());
        infoHistoryService.validateOnVersionDelete(vo.getVersion());
        // 恢复上一版本的最新标识
        if(StrUtil.isNotBlank(vo.getLastVersion())) {
            VersionDefine lastVersion = dao.selectById(vo.getLastVersion());
            lastVersion.setLastFlag(true);
            dao.updateById(lastVersion);
        }
        vo.setValid(ValidEnum.FALSE.getType());
        dao.updateById(vo);
    }
}
