package com.jeelowcode.service.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
import com.jeelowcode.tool.framework.common.pojo.PageResult;
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
import com.jeelowcode.service.system.controller.vo.dept.duty.DutyPageReqVO;
import com.jeelowcode.service.system.controller.vo.dept.duty.DutySaveReqVO;
import com.jeelowcode.service.system.entity.DutyDO;
import com.jeelowcode.service.system.mapper.DutyMapper;
import com.jeelowcode.service.system.constant.ErrorCodeConstants;
import com.jeelowcode.service.system.service.IDutyService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static com.jeelowcode.tool.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertMap;


/**
 * 职务 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class DutyServiceImpl implements IDutyService {

    @Resource
    private DutyMapper dutyMapper;

    @Override
    public Long createDuty(DutySaveReqVO createReqVO) {
        // 校验正确性
        validateDutyForCreateOrUpdate(null, createReqVO.getName());

        // 插入职务
        DutyDO Duty = BeanUtils.toBean(createReqVO, DutyDO.class);
        dutyMapper.insert(Duty);
        return Duty.getId();
    }

    @Override
    public void updateDuty(DutySaveReqVO updateReqVO) {
        // 校验正确性
        validateDutyForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getName());

        // 更新职务
        DutyDO updateObj = BeanUtils.toBean(updateReqVO, DutyDO.class);
        dutyMapper.updateById(updateObj);
    }

    @Override
    public void deleteDuty(Long id) {
        // 校验是否存在
        validateDutyExists(id);
        // 删除部门
        dutyMapper.deleteById(id);
    }

    private void validateDutyForCreateOrUpdate(Long id, String name) {
        // 校验自己存在
        validateDutyExists(id);
        // 校验职务名的唯一性
        validateDutyNameUnique(id, name);
    }

    private void validateDutyNameUnique(Long id, String name) {
        DutyDO Duty = dutyMapper.selectByName(name);
        if (Duty == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的职务
        if (id == null) {
            throw exception(ErrorCodeConstants.DUTY_NAME_DUPLICATE);
        }
        if (!Duty.getId().equals(id)) {
            throw exception(ErrorCodeConstants.DUTY_NAME_DUPLICATE);
        }
    }

    private void validateDutyExists(Long id) {
        if (id == null) {
            return;
        }
        if (dutyMapper.selectById(id) == null) {
            throw exception(ErrorCodeConstants.DUTY_NOT_FOUND);
        }
    }

    @Override
    public List<DutyDO> getDutyList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return dutyMapper.selectBatchIds(ids);
    }

    @Override
    public List<DutyDO> getDutyList() {
        return dutyMapper.selectList();
    }

    @Override
    public List<DutyDO> getDutyList(Collection<Long> ids, Collection<Integer> statuses) {
        return dutyMapper.selectList(ids, statuses);
    }

    @Override
    public PageResult<DutyDO> getDutyPage(DutyPageReqVO reqVO) {
        return dutyMapper.selectPage(reqVO);
    }

    @Override
    public DutyDO getDuty(Long id) {
        return dutyMapper.selectById(id);
    }

    @Override
    public void validateDutyList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        // 获得职务信息
        List<DutyDO> Dutys = dutyMapper.selectBatchIds(ids);
        Map<Long, DutyDO> DutyMap = convertMap(Dutys, DutyDO::getId);
        // 校验
        ids.forEach(id -> {
            DutyDO Duty = DutyMap.get(id);
            if (Duty == null) {
                throw exception(ErrorCodeConstants.DUTY_NOT_FOUND);
            }
            if (!CommonStatusEnum.ENABLE.getStatus().equals(Duty.getStatus())) {
                throw exception(ErrorCodeConstants.DUTY_NOT_ENABLE, Duty.getName());
            }
        });
    }
}
