package com.mmc.iuav.user.service.impl;

import com.mmc.iuav.general.CodeUtil;
import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.response.ResultEnum;
import com.mmc.iuav.user.dao.RoleDao;
import com.mmc.iuav.user.entity.MenuInfoDO;
import com.mmc.iuav.user.entity.RoleInfoDO;
import com.mmc.iuav.user.enums.CompanyTypeEnums;
import com.mmc.iuav.user.model.dto.LoginSuccessDTO;
import com.mmc.iuav.user.model.dto.MenuInfoDTO;
import com.mmc.iuav.user.model.qo.RoleInfoQO;
import com.mmc.iuav.user.model.vo.RoleInfoVO;
import com.mmc.iuav.user.model.vo.RoleMenuInfoVO;
import com.mmc.iuav.user.service.RoleService;
import com.mmc.iuav.user.util.MenuTreeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author small
 * @Date 2023/7/10 16:05
 * @Version 1.0
 */
@Service
public class RoleServiceImpl implements RoleService {


    @Autowired
    private RoleDao roleDao;

    @Override
    public ResultBody insertRoleInfo(RoleInfoVO roleInfo, LoginSuccessDTO userLoginInfoFromRedis) {
        int count = roleDao.countRoleName(roleInfo.getRoleName());
        if (count > 0) {
            return ResultBody.error(ResultEnum.ROLE_NAME_REPEAT_ERROR);
        }
        RoleInfoDO rd = new RoleInfoDO(roleInfo);
        rd.setBackUserAccountId(userLoginInfoFromRedis.getUserAccountId());
        rd.setRoleNo(CodeUtil.createRoleNo(roleDao.findList()));
        roleDao.insertRoleInfo(rd);
        return ResultBody.success();
    }

    @Override
    public ResultBody updateRoleInfo(RoleInfoVO roleInfo, LoginSuccessDTO userLoginInfoFromRedis) {
        RoleInfoDO rd = new RoleInfoDO(roleInfo);
        int count = roleDao.countRoleNameId(rd);
        if (count > 0) {
            return ResultBody.error(ResultEnum.ROLE_NAME_REPEAT_ERROR);
        }
        rd.setBackUserAccountId(userLoginInfoFromRedis.getUserAccountId());
        roleDao.updateRoleInfo(rd);
        return ResultBody.success();
    }

    @Override
    public ResultBody removeRoleInfo(Integer id) {
        Integer count = roleDao.countNotDelUserAccountByRole(id);
        if (count > 0) {
            return ResultBody.error(ResultEnum.ROLE_AVL_USER_DELETE_ERROR);
        }
        roleDao.removeRoleInfo(id);
        return ResultBody.success();
    }

    @Override
    public PageResult listPageRoleInfo(RoleInfoQO param, LoginSuccessDTO loginSuccessDTO) {
        // 加盟公司只能看自己拥有的角色
        if (!loginSuccessDTO.getCompanyInfoVO().getCompanyType().equals(CompanyTypeEnums.KBT.getType())) {
            param.setId(loginSuccessDTO.getRoleInfo().getId());
        }
        int count = roleDao.countPageRoleInfo(param);
        if (count == 0) {
            return PageResult.buildPage(param.getPageNo(), param.getPageSize(), count);
        }
        Integer pageNo = param.getPageNo();
        param.buildCurrentPage();
        return PageResult.buildPage(pageNo, param.getPageSize(), count,
                roleDao.listPageRoleInfo(param).stream().map(d -> {
                    return d.buildRoleInfoDTO();
                }).collect(Collectors.toList()));
    }

    @Override
    public ResultBody listRoleMenuInfo(Integer roleId) {
        List<MenuInfoDO> menuInfoDOList = roleDao.listRoleMenuInfo(roleId);
        List<MenuInfoDTO> menuInfoDTOS = menuInfoDOList.stream().map(MenuInfoDO::buildMenuInfoDTO).collect(Collectors.toList());
        return ResultBody.success(MenuTreeUtil.buildTreePCMenu(menuInfoDTOS));
    }

    @Transactional
    @Override
    public ResultBody updateRoleMenuInfo(RoleMenuInfoVO roleMenuInfoVO, LoginSuccessDTO loginSuccessDTO) {
        // 判断该角色的菜单是否可以修改
        RoleInfoDO roleInfo = roleDao.getRoleInfo(roleMenuInfoVO.getRoleId());
        if (roleInfo.getSuperAdmin().equals(1)) {
            return ResultBody.error(ResultEnum.UPDATE_ADMIN_ROLE_MENUS_ERROR);
        }
        if (roleMenuInfoVO.getRoleId().equals(loginSuccessDTO.getRoleInfo().getId())) {
            return ResultBody.error(ResultEnum.UPDATE_OWNER_ROLE_MENUS_ERROR);
        }
        List<MenuInfoDO> menuInfoDOList = roleDao.listRoleMenuInfo(roleMenuInfoVO.getRoleId());
        List<Integer> existMenuIds = menuInfoDOList.stream().map(MenuInfoDO::getId).collect(Collectors.toList());
        // 新添加的权限
        List<Integer> addMenuIds = roleMenuInfoVO.getMenuInfoIds().stream().filter(v -> !existMenuIds.contains(v)).collect(Collectors.toList());
        // 需删除的权限
        List<Integer> deleteMenuIds = existMenuIds.stream().filter(v -> !roleMenuInfoVO.getMenuInfoIds().contains(v)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(addMenuIds)) {
            roleDao.batchAddMenuIds(roleMenuInfoVO.getRoleId(), addMenuIds);
        }
        if (!CollectionUtils.isEmpty(deleteMenuIds)) {
            roleDao.batchDeleteMenuIds(roleMenuInfoVO.getRoleId(), deleteMenuIds);
        }
        return ResultBody.success();
    }

}
