package com.qmth.teachcloud.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.teachcloud.common.entity.SysPrivilege;
import com.qmth.teachcloud.common.entity.SysRole;
import com.qmth.teachcloud.common.entity.SysRolePrivilege;
import com.qmth.teachcloud.common.mapper.SysRolePrivilegeMapper;
import com.qmth.teachcloud.common.service.CommonCacheService;
import com.qmth.teachcloud.common.service.SysPrivilegeService;
import com.qmth.teachcloud.common.service.SysRolePrivilegeService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 角色和菜单关联表 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class SysRolePrivilegeServiceImpl extends ServiceImpl<SysRolePrivilegeMapper, SysRolePrivilege> implements SysRolePrivilegeService {
    @Resource
    private CommonCacheService commonCacheService;

    @Resource
    SysPrivilegeService sysPrivilegeService;

    @Override
    public void removeByRoleId(Long id) {
        UpdateWrapper<SysRolePrivilege> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SysRolePrivilege::getRoleId, id);
        this.remove(updateWrapper);
    }

    @Override
    public boolean saveBatch(SysRole role) {
        Long schoolId = Objects.nonNull(ServletUtil.getRequestHeaderSchoolIdByNotVaild()) ? Long.valueOf(ServletUtil.getRequestHeaderSchoolIdByNotVaild().toString()) : null;

        List<SysRolePrivilege> sysRolePrivilegeList = commonCacheService.rolePrivilegeCache(schoolId, role.getId());
        if (schoolId == null && role.getDefaultRole()) {
            sysRolePrivilegeList = sysRolePrivilegeList.stream().filter(m -> m.getSchoolId() == null).collect(Collectors.toList());
        }

        QueryWrapper<SysPrivilege> sysPrivilegeQueryWrapper = new QueryWrapper<>();
        sysPrivilegeQueryWrapper.lambda().in(SysPrivilege::getId, role.getPrivilegeIds());
        List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.list(sysPrivilegeQueryWrapper);

        Set<String> relatedSet = sysPrivilegeList.stream().filter(s -> Objects.nonNull(s.getRelated())).map(s -> s.getRelated()).collect(Collectors.toSet());
        Set<Long> finalRelatedSet = new HashSet<>(Arrays.asList(role.getPrivilegeIds()));
        for (String s : relatedSet) {
            if (s.contains(",")) {
                String[] arrays = s.split(",");
                for (int i = 0; i < arrays.length; i++) {
                    finalRelatedSet.add(Long.parseLong(arrays[i].trim()));
                }
            } else {
                finalRelatedSet.add(Long.parseLong(s));
            }
        }
        // 修改后权限集合
        List<Long> relatedList = new ArrayList<>(finalRelatedSet);
        List<Long> finalRelatedList = relatedList;
        int count = (int) sysRolePrivilegeList.stream().filter(s -> finalRelatedList.contains(s.getPrivilegeId())).count();
        if (count != sysRolePrivilegeList.size() || count != finalRelatedSet.size()) {
            //学校角色编辑超管
            if (role.getDefaultRole()) {
                // 超管页面
                if (schoolId == null) {
                    this.removeBySchoolIdAndRoleId(schoolId, role.getId());
                }
                // 学校页面
                else {
                    this.removeBySchoolIdAndRoleId(schoolId, role.getId());
                    List<Long> sysRolePrivilegeIdList = sysRolePrivilegeList.stream().filter(m -> m.getSchoolId() == null).map(SysRolePrivilege::getPrivilegeId).collect(Collectors.toList());
                    relatedList = relatedList.stream().filter(m -> !sysRolePrivilegeIdList.contains(m)).collect(Collectors.toList());
                }
            } else {
                this.removeByRoleId(role.getId());
            }
            List<SysRolePrivilege> list = new ArrayList<>();
            for (Long privilegeId : relatedList) {
                SysRolePrivilege sysRolePrivilege = new SysRolePrivilege();
                sysRolePrivilege.setRoleId(role.getId());
                sysRolePrivilege.setPrivilegeId(privilegeId);
                if(role.getDefaultRole() && schoolId != null){
                    sysRolePrivilege.setSchoolId(schoolId);
                }
                list.add(sysRolePrivilege);
            }
            this.saveBatch(list);
            return true;
        }
        return false;
    }

    @Override
    public void removeBySchoolIdAndRoleId(Long schoolId, Long roleId) {
        UpdateWrapper<SysRolePrivilege> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SysRolePrivilege::getRoleId, roleId);
        if (schoolId == null) {
            updateWrapper.lambda().isNull(SysRolePrivilege::getSchoolId);
        } else {
            updateWrapper.lambda().eq(SysRolePrivilege::getSchoolId, schoolId);
        }
        this.remove(updateWrapper);
    }

    @Override
    public List<SysRolePrivilege> listByRoleId(Long roleId) {
        QueryWrapper<SysRolePrivilege> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysRolePrivilege::getRoleId, roleId);
        return this.list(queryWrapper);
    }
}
