package com.app.admin.framework.system.permission.authorization.service.impl;

import com.app.admin.framework.system.administrator.model.SysAdministrator;
import com.app.admin.framework.system.administrator.service.SysAdministratorService;
import com.app.admin.framework.system.module.convert.SysModuleTreeConvert;
import com.app.admin.framework.system.module.model.SysModule;
import com.app.admin.framework.system.module.service.SysModuleService;
import com.app.admin.framework.system.module.view.SysModuleTreeNode;
import com.app.admin.framework.system.permission.authorization.model.SysAdministratorRole;
import com.app.admin.framework.system.permission.authorization.model.SysRoleModule;
import com.app.admin.framework.system.permission.authorization.service.SysAdministratorRoleService;
import com.app.admin.framework.system.permission.authorization.service.SysAuthorityService;
import com.app.admin.framework.system.permission.authorization.service.SysRoleModuleService;
import com.app.admin.framework.system.permission.authorization.view.SysAdministratorRoleView;
import com.app.admin.framework.system.permission.role.service.SysRoleService;
import com.app.admin.framework.system.permission.shiro.service.ShiroCacheManagerService;
import com.app.framework.core.support.auth.LoginUser;
import com.app.framework.core.support.enums.common.StateEnum;
import com.app.framework.core.support.view.form.AjaxResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限管理
 */
@Service
public class SysAuthorityServiceImpl implements SysAuthorityService {

    @Resource
    SysAdministratorService sysAdministratorService;

    @Resource
    SysModuleService sysModuleService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SysAdministratorRoleService sysAdministratorRoleService;

    @Resource
    SysRoleModuleService sysRoleModuleService;

    @Resource
    ShiroCacheManagerService shiroCacheManagerService;

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 登录密码,标准md5加密
     */
    public AjaxResult login(String username, String password) {
        AjaxResult loginResult = sysAdministratorService.login(username, password, null);
        if (loginResult.success()) {
            SysAdministrator loginUser = (SysAdministrator) loginResult.getData();
            if (!loginUser.getUserType().equals(LoginUser.TYPE_SUPER)) {//非超级管理员
                List<SysAdministratorRoleView> roles = sysAdministratorRoleService.selectByUserId(loginUser.getId(), StateEnum.NORMAL);
                if (roles.isEmpty()) {//用户无权限
                    loginResult.setCode(false);
                    loginResult.setMsg("您没有得到相应的授权");
                }
            }
        }
        return loginResult;
    }


    /**
     * 获取登录用户的所有资源
     *
     * @param loginUser  登录用户
     * @param moduleType 资源类型
     */
    public List<SysModule> getLoginUserModule(LoginUser loginUser, Integer moduleType) {
        if (loginUser.getUserType().equals(LoginUser.TYPE_SUPER)) {//超级管理员
            SysModule view = new SysModule();
            view.setState(StateEnum.NORMAL.getValue());
            view.setMtype(moduleType);
            view.setOrganizationId(loginUser.getOrganizationId());
            return sysModuleService.getPageList(view, null);
        }
        List<SysAdministratorRoleView> roles = sysAdministratorRoleService.selectByUserId(loginUser.getId(), StateEnum.NORMAL);
        if (roles.isEmpty()) {
            return Collections.emptyList();
        }
        Set<Long> roleIds = roles.stream().map(SysAdministratorRoleView::getRoleId).collect(Collectors.toSet());
        return sysRoleModuleService.selectByRoleIds(moduleType, roleIds);
    }

    /**
     * 加载角色下的关联模块
     */
    public List<SysModuleTreeNode> selectModuleByRoleId(LoginUser loginUser, Long roleId) {
        //角色已有权限
        Set<String> moduleIds = new HashSet<>();
        if (roleId != null) {
            List<SysRoleModule> relations = sysRoleModuleService.listByRoleId(roleId);
            if (null != relations && relations.size() > 0) {
                for (Iterator<SysRoleModule> iterator = relations.iterator(); iterator.hasNext(); ) {
                    SysRoleModule r = iterator.next();
                    moduleIds.add(r.getModuleId().toString());
                }
            }
        }
        //登录用户权限
        List<SysModule> list = this.getLoginUserModule(loginUser, null);
        return new SysModuleTreeConvert().transStaticTree(list, moduleIds);
    }

    /**
     * 保存角色模块关联
     *
     * @param roleId
     * @param moduleIds
     */
    public void saveRoleModuleRelation(Long roleId, Long[] moduleIds) {
        //清楚原有模块关联
        sysRoleModuleService.deleteByRoleId(roleId);
        //保存新的模块关联
        if (null != moduleIds && moduleIds.length > 0) {
            for (Long moduleId : moduleIds) {
                if (moduleId == null) continue;
                SysRoleModule r = new SysRoleModule();
                r.setRoleId(roleId);
                r.setModuleId(moduleId);
                sysRoleModuleService.save(r);
            }
        }
        //清除Shiro缓存
        List<String> users = sysAdministratorRoleService.getUsernameByRoleId(roleId);
        shiroCacheManagerService.destroy(users);
    }

    /**
     * 删除角色
     * 同时删除与用户对应关系
     * 同时删除角色模块关联关系
     *
     * @param roleId 角色ID
     */
    public void deleteRole(Long roleId) {
        sysAdministratorRoleService.deleteByRoleId(roleId);
        sysRoleModuleService.deleteByRoleId(roleId);
        sysRoleService.removeById(roleId);
    }


    /**
     * 保存用户角色对应关系
     *
     * @param userId  用户ID
     * @param roleIds 角色ID数组
     */
    public void saveUserRoleRelation(Long userId, Long roleIds[]) {
        sysAdministratorRoleService.deleteByUserId(userId);
        if (roleIds != null && roleIds.length > 0) {
            for (int i = 0; i < roleIds.length; i++) {
                if (roleIds[i] == null) continue;
                SysAdministratorRole r = new SysAdministratorRole();
                r.setUserId(userId);
                r.setRoleId(roleIds[i]);
                sysAdministratorRoleService.save(r);
            }
        }
        //清除该用户的shiro缓存
        SysAdministrator sysAdministrator = sysAdministratorService.getById(userId);
        shiroCacheManagerService.clearShiroCache(sysAdministrator.getUsername());
    }

    /**
     * 保存角色用户对应关系
     *
     * @param roleId  角色ID
     * @param userIds 用户ID数组
     */
    public void saveRoleUserRelation(Long roleId, Long userIds[]) {
        if (userIds != null && userIds.length > 0) {
            for (int i = 0; i < userIds.length; i++) {
                if (userIds[i] == null) continue;
                SysAdministratorRole r = new SysAdministratorRole();
                r.setUserId(userIds[i]);
                r.setRoleId(roleId);
                sysAdministratorRoleService.save(r);

                //清除该用户的shiro缓存
                SysAdministrator sysAdministrator = sysAdministratorService.getById(userIds[i]);
                shiroCacheManagerService.clearShiroCache(sysAdministrator.getUsername());
            }
        }
    }
}
