package com.microservices.zone.project.service.impl;

import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.datascope.annotation.DataScope;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.zone.detail.domain.ZoneDetail;
import com.microservices.zone.detail.service.IZoneDetailService;
import com.microservices.zone.project.domain.ZoneProject;
import com.microservices.zone.project.domain.ZoneProjectType;
import com.microservices.zone.project.domain.vo.ZoneProjectSearchVo;
import com.microservices.zone.project.domain.vo.ZoneProjectTypeInputVo;
import com.microservices.zone.project.domain.vo.ZoneProjectTypeUpdateVo;
import com.microservices.zone.project.mapper.ZoneProjectMapper;
import com.microservices.zone.project.mapper.ZoneProjectTypeMapper;
import com.microservices.zone.project.service.IZoneProjectTypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 特色专区项目分类Service业务层处理
 *
 * @author otto
 * @date 2023-05-05
 */
@Service
public class ZoneProjectTypeServiceImpl implements IZoneProjectTypeService {
    private static final Logger logger = LoggerFactory.getLogger(ZoneProjectTypeServiceImpl.class);
    @Autowired
    private ZoneProjectTypeMapper zoneProjectTypeMapper;
    @Autowired
    private IZoneDetailService zoneDetailService;
    @Autowired
    private ZoneProjectMapper zoneProjectMapper;

    /**
     * 查询特色专区项目分类
     *
     * @param id 特色专区项目分类主键
     * @return 特色专区项目分类
     */
    @Override
    public ZoneProjectType selectZoneProjectTypeById(Long id) {
        ZoneProjectType zoneProjectType = zoneProjectTypeMapper.selectZoneProjectTypeById(id);
        if (zoneProjectType == null) {
            throw new ServiceException("该项目类型不存在或无权限访问(项目类型id[" + id + "])");
        }
        zoneDetailService.checkZoneDataScope(zoneProjectType.getZoneId());
        return zoneProjectType;
    }

    /**
     * 查询特色专区项目分类列表
     *
     * @param zoneProjectType 特色专区项目分类
     * @return 特色专区项目分类
     */
    @Override
    @DataScope(deptAlias = "zmt")
    public List<ZoneProjectType> selectZoneProjectTypeList(ZoneProjectType zoneProjectType) {
        return zoneProjectTypeMapper.selectZoneProjectTypeList(zoneProjectType);
    }

    /**
     * 新增特色专区项目分类
     *
     * @param zoneProjectTypeInputVo 特色专区项目分类
     * @return 结果
     */
    @Override
    public int insertZoneProjectType(ZoneProjectTypeInputVo zoneProjectTypeInputVo) {
        zoneDetailService.checkZoneDataScope(zoneProjectTypeInputVo.getZoneId());
        List<ZoneProjectType> zoneProjectTypeListByNameAndZone = zoneProjectTypeMapper.selectZoneProjectTypeListByNameAndZoneId(zoneProjectTypeInputVo);
        if (!zoneProjectTypeListByNameAndZone.isEmpty()) {
            throw new ServiceException("该专区下已存在该名称分类(项目分类名称[" + zoneProjectTypeInputVo.getName() + "])");
        }
        ZoneProjectType zoneProjectType = zoneProjectTypeInputVo.toZoneProjectType();
        ZoneDetail zoneDetail = zoneDetailService.selectZoneDetailById(zoneProjectType.getZoneId());
        zoneProjectType.setDeptId(zoneDetail.getDeptId());
        zoneProjectType.setCreateTime(DateUtils.getNowDate());
        zoneProjectType.setCreateBy(SecurityUtils.getUsername());
        //设置排序值为当前最大的排序值+1
        Integer maxSort = zoneProjectTypeMapper.selectMaxSortByZoneId(zoneProjectTypeInputVo.getZoneId());
        if (maxSort == null) {
            maxSort = 1;
        } else {
            maxSort++;
        }
        zoneProjectType.setSort(maxSort);
        return zoneProjectTypeMapper.insertZoneProjectType(zoneProjectType);
    }

    /**
     * 修改特色专区项目分类
     *
     * @param zoneProjectTypeUpdateVo 特色专区项目分类
     * @return 结果
     */
    @Override
    public int updateZoneProjectType(ZoneProjectTypeUpdateVo zoneProjectTypeUpdateVo) {
        ZoneProjectType oldZoneProjectType = selectZoneProjectTypeById(zoneProjectTypeUpdateVo.getId());
        if (!oldZoneProjectType.getName().equals(zoneProjectTypeUpdateVo.getName())) {
            List<ZoneProjectType> zoneProjectTypeListByNameInZone = zoneProjectTypeMapper.selectZoneProjectTypeListByNameInZone(zoneProjectTypeUpdateVo);
            if (!zoneProjectTypeListByNameInZone.isEmpty()) {
                throw new ServiceException("该专区下已存在该名称分类(项目分类名称[" + zoneProjectTypeUpdateVo.getName() + "])");
            }
        }

        ZoneProjectType zoneProjectType = zoneProjectTypeUpdateVo.toZoneProjectType();
        zoneProjectType.setUpdateTime(DateUtils.getNowDate());
        zoneProjectType.setUpdateBy(SecurityUtils.getUsername());
        if (zoneProjectTypeUpdateVo.getOrder() != null) {
            Integer setSort = setSortByOrder(oldZoneProjectType, zoneProjectTypeUpdateVo.getOrder());
            zoneProjectType.setSort(setSort);
        }
        return zoneProjectTypeMapper.updateZoneProjectType(zoneProjectType);
    }

    private Integer setSortByOrder(ZoneProjectType data, Integer order) {
        int setSort;
        Long zoneId = data.getZoneId();
        Long id = data.getId();
        String name = data.getName();
        Integer maxCount = zoneProjectTypeMapper.selectCountByZoneId(zoneId);
        //检查用户输入顺序是否合法
        if (order < 1 || order > maxCount) {
            throw new ServiceException(String.format("顺序最小为1，最大为%d(名称[%s])", maxCount, name));
        }
        //获取所在行
        ZoneProjectType theOrderContainSelf = zoneProjectTypeMapper.selectDataByOrderAndZoneId(data, order, true);
        //当指定序号为当前数据时，不修改排序
        if (theOrderContainSelf != null && theOrderContainSelf.getId().equals(id)) {
            return null;
        }

        if (order == 1 || order.equals(maxCount)) {
            int minSort = zoneProjectTypeMapper.selectMinSortByZoneId(zoneId);
            int maxSort = zoneProjectTypeMapper.selectMaxSortByZoneId(zoneId);
            //当用户输入顺序为1时，数据顺序调整为最小值-1
            if (order == 1) {
                setSort = (minSort - 1);
            } else {
                //当用户输入顺序为列表总数时，数据顺序调整为最大值+1
                setSort = (maxSort + 1);
            }
        } else {
            //获取指定序号的数据(不包含当前数据)
            ZoneProjectType theOrderData = zoneProjectTypeMapper.selectDataByOrderAndZoneId(
                    data, order, false);
            if (theOrderData == null) {
                throw new ServiceException(String.format("指定顺序不存在(名称[%s]，顺序[%d])", name, order));
            }
            //计算用户上一个序号对应的排序值(不包含当前数据)
            ZoneProjectType theLastOrderData = zoneProjectTypeMapper.selectDataByOrderAndZoneId(
                    data, order - 1, false);
            Integer theLastSort = theLastOrderData.getSort();
            if (theOrderData.getSort() - theLastSort > 1) {
                setSort = theLastSort + 1;
            } else {
                setSort = theOrderData.getSort();
                //需要将大于等于该sort的所有数据项sort+1
                Integer updateCount = zoneProjectTypeMapper.batchUpdateSortIncreased(zoneId, setSort);
                logger.info("批量增加大于指定排序的排序值，共计更新{}条", updateCount);
            }
        }
        return setSort;
    }

    /**
     * 批量删除特色专区项目分类
     *
     * @param ids 需要删除的特色专区项目分类主键
     * @return 结果
     */
    @Override
    public int deleteZoneProjectTypeByIds(Long[] ids) {
        int success = 0;
        for (Long id : ids) {
            success += deleteZoneProjectTypeById(id);
        }
        return success;
    }

    private int deleteZoneProjectTypeById(Long id) {
        selectZoneProjectTypeById(id);
        ZoneProjectSearchVo zoneProjectSearchVo = new ZoneProjectSearchVo();
        zoneProjectSearchVo.setProjectTypeId(id);
        List<ZoneProject> zoneProjectList = zoneProjectMapper.selectZoneProjectList(zoneProjectSearchVo);
        if (!zoneProjectList.isEmpty()) {
            throw new ServiceException("该项目类型被项目关联，无法删除(项目类型id[" + id + "])");
        }
        return zoneProjectTypeMapper.deleteZoneProjectTypeById(id);
    }

    @Override
    public ZoneProjectType selectZoneProjectTypeByIdAndZoneId(Long projectTypeId, Long zoneId) {
        ZoneProjectType zoneProjectType = zoneProjectTypeMapper.selectZoneProjectTypeByIdAndZoneId(projectTypeId, zoneId);
        if (zoneProjectType == null) {
            throw new ServiceException("该项目类型在当前特色专区不存在或无权限访问(项目类型id[" + projectTypeId + "],特色专区id[" + zoneId + "])");
        }
        return null;
    }
}
