package com.mosty.common.core.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.mosty.common.base.constant.enums.DeletedEnum;
import com.mosty.common.base.constant.enums.PermissionLevelEnum;
import com.mosty.common.core.business.entity.*;
import com.mosty.common.core.business.entity.vo.*;
import com.mosty.common.core.business.mapper.SysDeptMapper;
import com.mosty.common.core.business.mapper.SysRoleDeptMapper;
import com.mosty.common.core.business.mapper.SysRoleMapper;
import com.mosty.common.core.business.mapper.SysUserRoleMapper;
import com.mosty.common.core.business.service.*;
import com.mosty.common.token.DeptInfo;
import com.mosty.common.token.UserInfo;
import com.mosty.common.token.UserInfoManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author li
 * @description 针对表【sys_role(角色表)】的数据库操作Service实现
 * @createDate 2022-02-12 16:53:11
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysRoleMenuService sysRoleMenuService;
    @Resource
    private SysMenuService sysMenuService;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SysRoleDeptMapper sysRoleDeptMapper;
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysDeptService sysDeptService;


    @Override
    public DeptInfo getSysDeptLevel(String orgCode) {
        DeptInfo deptInfo = new DeptInfo();
        SysDept sysDept = sysDeptMapper.selectOne(new QueryWrapper<SysDept>().eq("org_code", orgCode).eq("xt_zxbz", 0));
        if (sysDept != null) {
            deptInfo.setSsbmid(sysDept.getId());
            deptInfo.setSsbmdm(sysDept.getOrgCode());
            deptInfo.setSsbm(sysDept.getOrgName());
            //获取地市州
            SysDept dszDept = getDszDept(sysDept);
            if (dszDept != null) {
                deptInfo.setSssgajid(dszDept.getId());
                deptInfo.setSssgajdm(dszDept.getOrgCode());
                deptInfo.setSssgaj(dszDept.getOrgName());
            }
            //获取分县局
            SysDept fxjDept = getFxjDept(sysDept);
            if (fxjDept != null) {
                deptInfo.setSsxgajid(fxjDept.getId());
                deptInfo.setSsxgajdm(fxjDept.getOrgCode());
                deptInfo.setSsxgaj(fxjDept.getOrgName());
            }

            QueryWrapper<SysRoleDept> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("dept_id", sysDept.getId());
            List<SysRoleDept> list = sysRoleDeptMapper.selectList(queryWrapper);
            if (CollectionUtil.isEmpty(list)) {
                return deptInfo;
            }
            List<Long> roleList = list.stream().map(SysRoleDept::getRoleId).collect(Collectors.toList());
            Collection<SysRole> sysRoles = super.listByIds(roleList);
            List<SysRoleVO> collect = sysRoles.stream().filter(role -> DeletedEnum.NATURE.code.equals(role.getXtZxbz()))
                    .map(role -> BeanUtil.copyProperties(role, SysRoleVO.class))
                    .sorted(Comparator.comparing(SysRoleVO::getDataPermissionLevel))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                deptInfo.setPermissionsLevel(collect.get(0).getDataPermissionLevel());
                if (deptInfo.getPermissionsLevel().equals("5")) {
                    // 本部门以及下级部门权限
                    // 查询下级部门
                    List<Long> childDeptIds = sysDeptService.getAllChildDeptIds(sysDept.getId());
                    List<String> collect1 = childDeptIds.stream().map(String::valueOf).collect(Collectors.toList());
                    collect1.add(String.valueOf(sysDept.getId()));
                    deptInfo.setIds(String.join(",", collect1));
                }
            }
        }
        return deptInfo;
    }


    // 根据当前地市州
    public SysDept getDszDept(SysDept sysDept) {
        if (sysDept == null) {
            return null;
        }
        long id;
        String path = sysDept.getRootPath();
        if (path.contains("_")) {
            String[] paths = path.split("_");
            id = Long.parseLong(paths[1]);
        } else {
            id = Long.parseLong(path);
        }
        return sysDeptService.getById(id);
    }

    // 根据当前部门获取分县局部门
    public SysDept getFxjDept(SysDept sysDept) {
        if (sysDept == null) {
            return null;
        }
        Long id = null;
        String path = sysDept.getRootPath();
        if (path.contains("_")) {
            String[] paths = path.split("_");
            if (paths.length == 2) {
                id = Long.valueOf(paths[1]);
            } else if (paths.length == 3) {
                id = Long.valueOf(paths[2]);
            } else if (paths.length >= 4) {
                id = Long.valueOf(paths[2]);
            }
        } else {
            id = Long.valueOf(path);
        }
        return sysDeptService.getById(id);
    }

    @Override
    public IPage<SysRole> selectByPage(RolePage rolePage) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(rolePage.getRoleName())) {
            queryWrapper.and(wrapper -> wrapper.like("role_name", rolePage.getRoleName()));
        }
        queryWrapper.and(wrapper -> wrapper.eq("xt_zxbz", DeletedEnum.NATURE.code));
        return getBaseMapper().selectPage(rolePage, queryWrapper);
    }

    @Override
    public List<SysRoleVO> getUserRoleList(Long userId) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", String.valueOf(userId));
        List<SysUserRole> list = sysUserRoleService.list(queryWrapper);
        if (CollectionUtil.isEmpty(list)) {
            return Lists.newArrayList();
        }

        List<Long> roleList = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        Collection<SysRole> sysRoles = super.listByIds(roleList);

        return sysRoles.stream().filter(role -> DeletedEnum.NATURE.code.equals(role.getXtZxbz()))
                .map(role -> BeanUtil.copyProperties(role, SysRoleVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public void insertRole(AddRoleVO addRoleVo, String ipAddress) {
        SysRole sysRole = BeanUtil.copyProperties(addRoleVo, SysRole.class);

        UserInfo userInfo = UserInfoManager.get();
        sysRole.setXtZxbz(DeletedEnum.NATURE.code);

        sysRole.setXtCjsj(new Date());
        sysRole.setXtZhxgsj(new Date());
        sysRole.setXtZhxgrid(userInfo.getUserId().toString());
        sysRole.setXtZhxgrxm(userInfo.getUserName());
        sysRole.setXtZhxgrbmid(userInfo.getDeptId().toString());
        sysRole.setXtZhxgrbm(userInfo.getDeptName());

        sysRole.setXtLrsj(new Date());
        sysRole.setXtLrrid(userInfo.getUserId().toString());
        sysRole.setXtLrrxm(userInfo.getUserName());
        sysRole.setXtLrrbmid(userInfo.getDeptId().toString());
        sysRole.setXtLrrbm(userInfo.getDeptName());

        sysRole.setXtZhxgip(ipAddress);
        sysRole.setXtLrip(ipAddress);

        this.save(sysRole);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRoleMenuInfo(AddRoleMenuVO roleMenuVO) {
        // 先删除已绑定的菜单
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleMenuVO.getRoleId());
        sysRoleMenuService.remove(queryWrapper);

        List<SysRoleMenu> list = new ArrayList<>();
        List<Long> menuIds = roleMenuVO.getMenuIds();
        menuIds.forEach(item -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleMenuVO.getRoleId());
            sysRoleMenu.setMenuId(item);
            list.add(sysRoleMenu);
        });
        sysRoleMenuService.saveBatch(list);
    }

    @Override
    public void saveDataPermission(AddRoleDataPartitionVO addRoleDataPartitionVO, String ipAddress) {
        UserInfo userInfo = UserInfoManager.get();
        SysRole sysRole = new SysRole();
        sysRole.setId(addRoleDataPartitionVO.getId());
        sysRole.setDataPermissionLevel(addRoleDataPartitionVO.getDataPermissionLevel());
        sysRole.setXtZhxgsj(new Date());
        sysRole.setXtZhxgrid(userInfo.getUserId().toString());
        sysRole.setXtZhxgrxm(userInfo.getUserName());
        sysRole.setXtZhxgrbmid(userInfo.getDeptId().toString());
        sysRole.setXtZhxgrbm(userInfo.getDeptName());
        sysRole.setXtZhxgip(ipAddress);
        sysRole.setXtLrip(ipAddress);

        this.updateById(sysRole);
    }

    @Override
    public DataPermissionVO getDataPermission(String menuUrl) {
        UserInfo userInfo = UserInfoManager.get();
        DataPermissionVO vo = new DataPermissionVO();
        SysMenu menu = sysMenuService.getOne(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getMenuUrl, menuUrl).eq(SysMenu::getXtZxbz, DeletedEnum.NATURE.code));
        Set<Long> roleIds = sysRoleMenuService.listByMenuId(menu.getId());
        if (CollectionUtils.isNotEmpty(roleIds)) {
            SysRole sysRole = this.list(new LambdaQueryWrapper<SysRole>()
                    .in(SysRole::getId, roleIds).orderByAsc(SysRole::getDataPermissionLevel)).get(0);
            vo.setPermissionLevel(sysRole.getDataPermissionLevel());
            if (PermissionLevelEnum.DEPT_AND_CHILD.level.equals(sysRole.getDataPermissionLevel())) {
                List<Long> deptIds = sysDeptService.getAllChildDeptIds(userInfo.getDeptId());
                vo.setDeptIds(deptIds);
            }
        } else {
            vo.setPermissionLevel(PermissionLevelEnum.ALL.level.toString());
        }

        return vo;
    }

    @Override
    public IPage<SysRole> selectUnAccreditPage(RolePage rolePage) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(rolePage.getRoleName())) {
            queryWrapper.and(wrapper -> wrapper.like("role_name", rolePage.getRoleName()));
        }
        queryWrapper.and(wrapper -> wrapper.eq("xt_zxbz", DeletedEnum.NATURE.code));
        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.and(wrapper -> wrapper.eq("user_id", rolePage.getUserId()));
        List<SysUserRole> list = sysUserRoleService.list(sysUserRoleQueryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            List<Long> roleList = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
            queryWrapper.and(wrapper -> wrapper.notIn("id", roleList));
        }
        return getBaseMapper().selectPage(rolePage, queryWrapper);
    }

    @Override
    public IPage<SysUserVO> getRoleUserList(GetUserRoleListVo vo) {
        List<SysUserVO> roleUserList = sysUserRoleMapper.getRoleUserList(vo);
        Page<SysUserVO> page = BeanUtil.copyProperties(roleUserList, Page.class);
        page.setRecords(roleUserList);
        page.setTotal(roleUserList.size());
        return page;
    }

    @Override
    public List<Long> getRoleMenuIds(Long roleId) {
        List<SysRoleMenu> list = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
        return list.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
    }


}




