package com.zsc.edu.gateway.modules.system.service.impl;

import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.modules.system.dto.RoleDto;
import com.zsc.edu.gateway.modules.system.entity.*;
import com.zsc.edu.gateway.modules.system.mapper.RoleMapper;
import com.zsc.edu.gateway.modules.system.repo.RoleMenuRepository;
import com.zsc.edu.gateway.modules.system.repo.RoleRepository;
import com.zsc.edu.gateway.modules.system.repo.UserRolesRepository;
import com.zsc.edu.gateway.modules.system.service.RoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.modules.system.vo.RoleVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author Yao
 * @since 2023-04-06
 */
@AllArgsConstructor
@Service
public class RoleServiceImpl extends ServiceImpl<RoleRepository, Role> implements RoleService {

    private final RoleMapper mapper;
    private final UserRolesRepository urRepo;

    private final RoleMenuRepository roleMenuRepository;
    private final RoleRepository roleRepository;

    @Override
    public Role create(RoleDto dto) {
        boolean existsByName = count(new LambdaQueryWrapper<Role>().eq(Role::getName, dto.getName())) > 0;
        if (existsByName) {
            throw new ConstraintException("name", dto.name, "角色已存在");
        }
        Role role = new Role();
        role.setName(dto.getName());
        role.setRemark(dto.getRemark());
        save(role);
        if (dto.getMenuIds() != null) {
            roleMenuRepository.insert(
                    dto.getMenuIds().stream()
                            .map(menuId -> new RoleMenu(role.getId(), menuId)).collect(Collectors.toList()));
        }
        return role;
    }

    @Override
    public Boolean toggle(Long id) {
        Role role = getById(id);
        role.setEnabled(!role.getEnabled());
        return updateById(role);
    }

    @Override
    public Boolean delete(Long id) {
        boolean hasUser = urRepo.selectCount(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, id)) > 0;
        if (hasUser) {
            throw new ConstraintException("存在与本角色绑定的用户，请先删除用户");
        }
        roleMenuRepository.delete(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, id));
        return removeById(id);
    }

    @Override
    public Role edit(RoleDto dto, Long id) {
        Role selectyRole = getById(id);
        if (selectyRole == null) {
            throw new ConstraintException("id", id.toString(), "角色不存在");
        }
        if (!Objects.equals(selectyRole.getName(), dto.getName()) &&
                count(new LambdaQueryWrapper<Role>().eq(Role::getName, dto.getName())) > 0) {
            throw new ConstraintException("name", dto.getName(), "同名角色已存在");
        }
        Role role = new Role();
        role.setName(dto.getName());
        role.setRemark(dto.getRemark());
        updateById(role);
        if (dto.getMenuIds() != null) {
            roleMenuRepository.delete(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, id));
            roleMenuRepository.insert(
                    dto.getMenuIds().stream()
                            .map(menuId -> new RoleMenu(id, menuId)).collect(Collectors.toList()));
        }
        return role;
    }


    @Override
    public RoleVo detail(Long id) {
        return roleRepository.selectRoleById(id);
    }

}
