package com.zcxk.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcxk.dao.MenuMapper;
import com.zcxk.dao.RoleMapper;
import com.zcxk.dao.RoleMenuMapper;
import com.zcxk.dao.RoleOrgMapper;
import com.zcxk.dto.RoleDto;
import com.zcxk.dto.RoleRequestDto;
import com.zcxk.entity.*;
import com.zcxk.model.LoginUser;
import com.zcxk.service.RoleService;
import com.zcxk.util.ByteArrayUtils;
import com.zcxk.util.RedisUtil;
import com.zcxk.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 角色(Role表)服务实现类
 *
 * @author makejava
 * @since 2020-10-27 09:13:27
 */
@Service("roleService")
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleOrgMapper roleOrgMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private MenuMapper menuMapper;


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Role selectById(Integer id) {
        return this.roleMapper.selectById(id);
    }


    /**
     * 查询所有
     *
     * @return 实例对象的集合
     */
    @Override
    public List<Role> selectAll() {
        return this.roleMapper.selectAll();
    }

    /**
     * 根据条件查询
     *
     * @return 实例对象的集合
     */
    @Override
    public List<Role> selectList(Role role) {

        LoginUser currentUser = UserUtil.getCurrentUser();
        role.setTenantId(currentUser.getTenantId());
        role.setItems(currentUser.getProgramItemList());
        return this.roleMapper.selectList(role);
    }

    /**
     * 新增数据
     *
     * @param roleRequestDto 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public int insert(RoleRequestDto roleRequestDto) {

        Role role = roleRequestDto.getRole();
        LoginUser currentUser = UserUtil.getCurrentUser();
        if(currentUser.getDepartmentId()!=null){
            role.setOrgId(currentUser.getDepartmentId());
        }else {
            role.setOrgId(currentUser.getCompanyId());
        }
        role.setTenantId(currentUser.getTenantId());
        role.setCreateBy(currentUser.getUsername());
        role.setDateCreate(new Date());
        role.setStatus(1);
        int insert = this.roleMapper.insert(role);
        roleRequestDto.getRole().setId(role.getId());
        configDataPermission(roleRequestDto);
        return insert;
    }

    /**
     * 批量新增
     *
     * @param roles 实例对象的集合
     * @return 生效的条数
     */
    @Override
    public int batchInsert(List<Role> roles) {
        return this.roleMapper.batchInsert(roles);
    }

    /**
     * 修改数据
     *
     * @param roleRequestDto 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public int update(RoleRequestDto roleRequestDto) {
        Role role=roleRequestDto.getRole();


        //將禁用的角色放入redis，作为登出判断
        if(role.getRoleState()==0){
            String roleKey="disableRole:"+role.getId();
            redisUtil.setExpire(roleKey.getBytes(), ByteArrayUtils.objectToBytes("1").get(), 60*60*24);//15分钟过期

        } if(role.getRoleState()==1){
            String roleKey="disableRole:"+role.getId();
            redisUtil.del(roleKey.getBytes());

        }
        LoginUser currentUser = UserUtil.getCurrentUser();
        role.setUpdateBy(currentUser.getUsername());
        configDataPermission(roleRequestDto);
        return this.roleMapper.update(role);
    }
    private void configDataPermission(RoleRequestDto roleRequestDto){
        if(roleRequestDto.getRole().getPermissionType()==5){
           Integer roleId=roleRequestDto.getRole().getId();
           roleOrgMapper.deleteOrgRole(roleId);
            List<Integer> orgIds = roleRequestDto.getIds();
            List<RoleOrg>roleOrgs=new ArrayList<>();
            orgIds.forEach(id->{
                RoleOrg roleOrg = new RoleOrg();
                roleOrg.setRoleId(roleId);
                roleOrg.setOrgId(id);
                roleOrg.setStatus(1);
                roleOrgs.add(roleOrg);
            });

            roleOrgMapper.batchInsert(roleOrgs);
        }
    }
    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public int deleteById(Integer id) {
        return this.roleMapper.deleteById(id);
    }

    @Override
    public List<String> deleteAll(List<Integer> ids) {
        List<String>fail=new ArrayList<>();
        ids.forEach(id->{
            Role role=new Role();
            role.setId(id);
                Role roleUser = roleMapper.findRoleUser(role);
                if (roleUser==null){
                    role.setStatus(0);
                    roleMapper.update(role);
                    //删除用户与角色的关系
                    roleMapper.deleteRoleUser(role);
                    //删除用户与菜单关系
                   // roleMapper.deleteRoleMenu(role);
                }else {
                    fail.add(roleUser.getRoleName());
                }


        });

        return fail;
    }

    /**
     * 查询总数据数
     *
     * @return 数据总数
     */
    @Override
    public int count() {
        return this.roleMapper.count();
    }

    /**
     * 分页查询
     *
     * @return 对象列表
     */
    @Override
    public IPage<RoleDto> selectPage(Role role, IPage<RoleDto> page) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        role.setTenantId(currentUser.getTenantId());
        role.setItems(currentUser.getProgramItemList());
        return this.roleMapper.selectPage(page, role);
    }

    @Override
    public IPage<UserEntity> findUsersByRole(Role role, IPage<UserEntity> iPage) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        role.setTenantId(currentUser.getTenantId());
        return  roleMapper.findUsersByRole(iPage,role);
    }

    @Override
    @Transactional
    public int updateRoleMenuRelations(RoleRequestDto dto) {
        Integer roleId =dto.getRole().getId();
        List<Integer> menuIds = dto.getIds();
        List<RoleMenu>menus=new ArrayList<>();
        roleMapper.deleteRoleMenu(dto.getRole());
        menuIds.forEach(id->{
            RoleMenu roleMenu=new RoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(id);
            roleMenu.setStatus(1);
            menus.add(roleMenu);
        });
        if(menus.size()>0){
            roleMenuMapper.batchInsert(menus);
        }

        return 0;
    }

    @Override
    public List<RoleOrg> getRoleOrgs(RoleOrg roleOrg) {
        return  roleOrgMapper.selectList(roleOrg);
    }
    @Override
    public  Role getRoleMenuByRoleId(Integer id) {
        Role role = roleMapper.selectById(id);
        RoleMenu roleMenu = new RoleMenu();
        roleMenu.setRoleId(id);
        roleMenu.setStatus(1);
        List<RoleMenu> roleMenus = roleMenuMapper.selectList(roleMenu);
        List<Long> menuIds = new ArrayList<>();
        for (RoleMenu item : roleMenus)
        {
            menuIds.add(Long.valueOf(item.getMenuId()));
        }
        role.setMenuIds(menuIds);
        return role;
    }
}