package com.xhkjedu.suser.service.system;

import com.xhkjedu.constant.PlatformConstant;
import com.xhkjedu.exception.MissingParametersException;
import com.xhkjedu.suser.mapper.gradeclass.SchoolMapper;
import com.xhkjedu.suser.mapper.system.RoleMapper;
import com.xhkjedu.suser.mapper.system.RoleModuleMapper;
import com.xhkjedu.suser.mapper.system.UserRoleMapper;
import com.xhkjedu.suser.model.system.TRole;
import com.xhkjedu.suser.model.system.TRoleModule;
import com.xhkjedu.suser.model.system.TUserRole;
import com.xhkjedu.suser.vo.system.SchoolVo;
import com.xhkjedu.utils.JedisUtil;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.suser.vo.system.RoleModuleVo;
import com.xhkjedu.suser.vo.system.RoleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName RoleService
 * Description TODO
 * Author WN
 * Date 2020/6/13 17:41
 **/
@Service
@Slf4j
public class RoleService extends JedisUtil{
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleModuleMapper roleModuleMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private SchoolMapper schoolMapper;
    @Resource
    private HttpServletRequest request;

    //保存
    @Transactional(rollbackFor = Exception.class)
    public Integer save(TRole role) throws Exception {
        try {
            role.setCreatetime(N_Utils.getSecondTimestamp());
            role.setRoletype(1);
            role.setCreateid(request.getIntHeader(PlatformConstant.XH_USER_ID));
            //保存角色信息
            roleMapper.insertUseGeneratedKeys(role);
            role.setRoleid(role.getId());

            //处理角色模块信息
            List<RoleModuleVo> rms = role.getModules();
            if(N_Utils.isListNotEmpty(rms)){
                saveRoleModules(rms,role);
            }

            return role.getId();
        } catch (Exception e) {
            log.error("角色保存失败：{}", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("角色保存失败");
        }
    }

    private void saveRoleModules(List<RoleModuleVo> rms,TRole role){
        List<TRoleModule> lst = new ArrayList<>();
        for(RoleModuleVo rm:rms){
            TRoleModule trm = new TRoleModule();
            trm.setRoleid(role.getRoleid());
            trm.setModuleid(rm.getModuleid());
            trm.setCreateid(role.getCreateid());
            trm.setCreatetime(N_Utils.getSecondTimestamp());
            trm.setSchoolid(role.getSchoolid());
            trm.setBelongcode(3);

            lst.add(trm);

            for(RoleModuleVo child : rm.getModulechilds()){
                TRoleModule trm2 = new TRoleModule();
                trm2.setRoleid(role.getRoleid());
                trm2.setModuleid(child.getModuleid());
                trm2.setCreateid(role.getCreateid());
                trm2.setCreatetime(N_Utils.getSecondTimestamp());
                trm2.setSchoolid(role.getSchoolid());
                trm2.setBelongcode(child.getBelongcode());

                lst.add(trm2);
            }
        }

        //批量保存角色模块信系
        roleModuleMapper.saveBathRoleModule(lst);
    }

    //修改
    @Transactional(rollbackFor = Exception.class)
    public Integer update(TRole role) throws Exception {
        try {
            //先删除角色模块关联信息
            roleModuleMapper.deleteByRoleid(role.getRoleid());
            if(N_Utils.isListNotEmpty(role.getModules())){
                //重新保存模块关联信息
                saveRoleModules(role.getModules(),role);
            }

            deleteNoRoleUserModule(role.getRoleid());//删除没有权限的用户常用模块
            role.setRoletype(null);
            role.setCreateid(null);
            int result = roleMapper.updateByPrimaryKeySelective(role);

            //清空角色关联用户存在redis中的用户模块
            List<TUserRole> users = userRoleMapper.listUsersByRoleid(role.getRoleid());
            if(N_Utils.isListNotEmpty(users)){
                //获取用户关联的学校区域码
                Integer userid = request.getIntHeader(PlatformConstant.XH_USER_ID);
                SchoolVo schoolVo = schoolMapper.getSchoolCloudByUserid(userid);
                String key = schoolVo.getCloudcode() + "_module_" + schoolVo.getSchoolid() + "_";
                for(TUserRole userRole : users){
                    String userKey = key + userRole.getUserid();
                    delete(userKey);
                }
            }
            return result;
        } catch (Exception e) {
            log.error("角色修改出错：{}", e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("角色修改失败");
        }
    }

    /**
     * @author ywx
     * @description 删除没有权限的用户常用模块
     * @date 2020/7/9 21:00
     **/
    private void deleteNoRoleUserModule(Integer roleid) {
        List<Integer> userids = userRoleMapper.listUserId(roleid);//获取有常用模块的用户id集合
        for (Integer userid : userids) {
            userRoleMapper.deleteNoRoleByUserId(userid);//根据用户id删除没有权限的常用模块
        }
    }

    //删除
    public Integer del(Integer roleid){
        Integer roletype = roleMapper.getTypeById(roleid);//根据角色id获取角色类型
        if (roletype == 0) throw new MissingParametersException("管理员角色禁止删除");
        Integer result = roleMapper.deleteByPrimaryKey(roleid);
        deleteNoRoleUserModule(roleid);//删除没有权限的用户常用模块
        return result;
    }

    //所有角色
    public List<TRole> listAllRoles(Integer schoolid){
        return roleMapper.listAllRoles(schoolid);
    }

    /**
     *功能描述 角色详情包含角色下用户
     * @author WN
     * @date 2020/6/15
     * @param  * @param roleid
     */
    public RoleVo getRoleDetail(Integer roleid){
        RoleVo roleVo = roleMapper.getRoleDetail(roleid);
        //获取角色下用户
        List<TUserRole> users = userRoleMapper.listUsersByRoleid(roleid);
        roleVo.setUsers(users);

        //获取角色下模块信息
        List<RoleModuleVo> modules = roleModuleMapper.listRoleModules(roleid);
        if(N_Utils.isListNotEmpty(modules)){
            roleVo.setModules(listRoleModuleForTree(modules));
        }

        return roleVo;
    }

    //处理返回值为层级结果
    private List<RoleModuleVo> listRoleModuleForTree(List<RoleModuleVo> modules){
        List<RoleModuleVo> lst = new ArrayList<>();
        for(RoleModuleVo m : modules){
            if(m.getLevel()==1){
                lst.add(m);
            }
        }

        for(RoleModuleVo m : lst){
            List<RoleModuleVo> childs = m.getModulechilds();
            for(RoleModuleVo mc: modules){
                if(m.getModuleid().equals(mc.getModulepid())){
                    if(!isExistModule(childs,m.getModuleid())){
                        childs.add(mc);
                    }
                }
            }
        }
        return lst.stream().filter(m -> N_Utils.isListNotEmpty(m.getModulechilds())).collect(Collectors.toList());
    }

    //判断集合中是否存在模块
    private boolean isExistModule(List<RoleModuleVo> lst, String moduleid){
        for(RoleModuleVo m: lst){
            if(m.getModuleid().equals(moduleid)){
                return true;
            }
        }
        return false;
    }

    /**
     *功能描述 用户有权限的所有模块
     * @author WN
     * @date 2020/6/15
     * @param  * @param userid
     * @return java.util.List<com.xhkjedu.suser.vo.system.RoleModuleVo>
     */
    public List<RoleModuleVo> listModulesByUserid(Integer userid,Integer belongcode){

        List<RoleModuleVo> modules = roleModuleMapper.listModulesByUserid(userid,belongcode);

        return listRoleModuleForTree(modules);
    }

    //角色选择列表
    public List<Map> listForSel(Integer schoolid){
        return roleMapper.listForSel(schoolid);
    }

    /**
     * @Description 角色用户
     * @Date 2024/6/27 16:27
     * @Author YWX
     * @Param [roleid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listRoleUser(Integer roleid) {
        return userRoleMapper.listRoleUser(roleid);
    }

    /**
     * @Description 角色用户-移除
     * @Date 2024/6/27 16:36
     * @Author YWX
     * @Param [urid]
     * @Return void
     **/
    public void delRoleUser(Integer urid) {
        userRoleMapper.deleteByPrimaryKey(urid);
    }

    /**
     * @Description 应用权限
     * @Date 2024/6/27 16:40
     * @Author YWX
     * @Param [roleid]
     * @Return java.util.List<com.xhkjedu.suser.vo.system.RoleModuleVo>
     **/
    public List<RoleModuleVo> listRoleModule(Integer roleid) {
        List<RoleModuleVo> modules = roleModuleMapper.listRoleModules(roleid);
        if (N_Utils.isListNotEmpty(modules)) {
            return listRoleModuleForTree(modules);
        } else {
            return new ArrayList<>();
        }
    }
}
