/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package io.renren.modules.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.Constant;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.business.entity.BusinessPermissionsEntity;
import io.renren.modules.sys.dao.SysRoleDao;
import io.renren.modules.sys.dao.SysRoleMenuDao;
import io.renren.modules.sys.dao.SysUserDao;
import io.renren.modules.sys.entity.SysRoleEntity;
import io.renren.modules.sys.entity.SysRoleMenuEntity;
import io.renren.modules.sys.service.SysRoleMenuService;
import io.renren.modules.sys.service.SysRoleService;
import io.renren.modules.sys.service.SysUserRoleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 角色
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service("sysRoleService")
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRoleEntity> implements SysRoleService {
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String roleName = (String) params.get("roleName");
        Long createUserId = (Long) params.get("createUserId");

        IPage<SysRoleEntity> page = this.page(
                new Query<SysRoleEntity>().getPage(params),
                new QueryWrapper<SysRoleEntity>()
                        .like(StringUtils.isNotBlank(roleName), "role_name", roleName)
                        .eq(createUserId != null, "create_user_id", createUserId)
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRole(SysRoleEntity role) {
        role.setCreateTime(new Date());
        this.save(role);

        //检查权限是否越权
        checkPrems(role);

        //保存角色与菜单关系
        sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRoleEntity role) {
        this.updateById(role);

        //检查权限是否越权
        checkPrems(role);

        //更新角色与菜单关系
        sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] roleIds) {
        //删除角色
        this.removeByIds(Arrays.asList(roleIds));

        //删除角色与菜单关联
        sysRoleMenuService.deleteBatch(roleIds);

        //删除角色与用户关联
        sysUserRoleService.deleteBatch(roleIds);
    }


    @Override
    public List<Long> queryRoleIdList(Long createUserId) {
        return baseMapper.queryRoleIdList(createUserId);
    }

    /**
     * 保存角色权限
     *
     * @param params
     */
    @Override
    public void qxSave(Map<String, Object> params) {
//        传入人员需要单独处理
        // System.out.println(params);
        //根据roleId 和 menuId 去查询数据如果有并且对应的flag = 0   删除  如果有且flag= 1  添加
        List<BusinessPermissionsEntity> list = new ArrayList<>();
        if (params.get("qxList") != null) {
            String[] rmList = params.get("qxList").toString().split("},");
            for (int i = 0; i < rmList.length; i++) {
                //传入的数据解析成实体
                BusinessPermissionsEntity businessPermissionsEntity = new BusinessPermissionsEntity();
                if (i + 1 != rmList.length) {
                    businessPermissionsEntity = JSON.parseObject(rmList[i] + "}", BusinessPermissionsEntity.class);
                } else {
                    businessPermissionsEntity = JSON.parseObject(rmList[i], BusinessPermissionsEntity.class);
                }
                list.add(businessPermissionsEntity);
            }
        }
        for (BusinessPermissionsEntity i : list) {
            //人员查看部分   特殊处理
            if ((i.getMenuId().equals("35") || i.getMenuId().equals("155")) && params.get("type").equals("0")) {//查看 权限操作
                //查看是否有这条数据
                SysRoleMenuEntity sysRME = sysRoleMenuDao.getInfoByRM(i.getRoleId(), i.getMenuId());
                if (i.getFlag() == 0 && sysRME != null) {//说明  此角色被取消 需要删除
                    //将数据删除
                    sysRoleMenuDao.deleteById(sysRME.getId());
                } else if (i.getFlag() == 1 && sysRME == null) {//说明此角色 选择此功能并且 数据库中无此数据
                    //创建新实体  传入数据
                    SysRoleMenuEntity sys = new SysRoleMenuEntity();
                    sys.setRoleId((long) Integer.parseInt(i.getRoleId()));
                    sys.setMenuId((long) Integer.parseInt(i.getMenuId()));
                    //插入到数据库中
                    sysRoleMenuDao.insert(sys);
                }
            } else if (!i.getMenuId().equals("") && i.getMenuId() != null) {//通用的所有的权限处理
                if (params.get("type").equals("0")) {//查看权限处理
//                    根据角色id和菜单id获取信息列表
                    List<SysRoleMenuEntity> listSysRMEty = sysRoleMenuDao.getInfoByRMCK(i.getRoleId(), i.getMenuId());
                    //0说明是取消权限，size > 0说明有数据  则 删除
                    if (i.getFlag() == 0 && listSysRMEty.size() > 0) {
                        //根据查询的数组进行删除处理
                        sysRoleMenuDao.deleteBySysRMList(listSysRMEty);
                    } else if (i.getFlag() == 1 && !(listSysRMEty.size() > 0)) {//1确认权限，不大于0是数据为空则插入数据
                        sysRoleMenuDao.insertCk(i.getRoleId(), i.getMenuId());
                    }
                } else if (params.get("type").equals("1")) {//编辑权限处理
                    List<SysRoleMenuEntity> listSysRMEty = sysRoleMenuDao.getInfoByRMBJ(i.getRoleId(), i.getMenuId());
                    //0说明是取消权限，size > 0说明有数据  则 删除
                    if (i.getFlag() == 0 && listSysRMEty.size() > 0) {
                        //根据查询的数组进行删除处理
                        sysRoleMenuDao.deleteBySysRMList(listSysRMEty);
                    } else if (i.getFlag() == 1 && !(listSysRMEty.size() > 0)) {//1确认权限，不大于0是数据为空则插入数据
                        sysRoleMenuDao.insertBJ(i.getRoleId(), i.getMenuId());
                    }
                }
            }
        }
    }

    /**
     * 检查权限是否越权
     */
    private void checkPrems(SysRoleEntity role) {
        //如果不是超级管理员，则需要判断角色的权限是否超过自己的权限
        if (role.getCreateUserId() == Constant.SUPER_ADMIN) {
            return;
        }

        //查询用户所拥有的菜单列表
        List<Long> menuIdList = sysUserDao.queryAllMenuId(role.getCreateUserId());

        //判断是否越权
        if (!menuIdList.containsAll(role.getMenuIdList())) {
            throw new RRException("新增角色的权限，已超出你的权限范围");
        }
    }
}
