package com.storlead.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.storlead.framework.auth.vo.LoginUser;
import com.storlead.framework.common.constant.CommonConstant;
import com.storlead.framework.util.LoginUserUtil;
import com.storlead.system.enums.OrganizationalTypeEnum;
import com.storlead.system.pojo.entity.RoleEntity;
import com.storlead.system.service.IRoleService;
import com.storlead.user.pojo.entity.CompanyEntity;
import com.storlead.user.pojo.entity.DeptEntity;
import com.storlead.user.pojo.entity.SubCompanyEntity;
import com.storlead.user.pojo.entity.UserEntity;
import com.storlead.system.pojo.entity.UserRoleEntity;
import com.storlead.system.mapper.UserRoleMapper;
import com.storlead.system.service.IUserRoleService;
import com.storlead.user.service.ICompanyService;
import com.storlead.user.service.IDepartService;
import com.storlead.user.service.ISubCompanyService;
import com.storlead.user.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户角色表 服务实现类
 * </p>
 *
 * @Author scott
 * @since 2018-12-21
 */
@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRoleEntity> implements IUserRoleService {

    @Resource
    private IUserService userService;
    @Resource
    private ISubCompanyService subCompanyService;
    @Resource
    private IDepartService departService;
    @Resource
    private ICompanyService companyService;
    @Resource
    private IRoleService roleService;
    private final String[] scopeType = {"全部", "本公司", "自定义","仅自己","本部门"};

    @Override
    public List<UserRoleEntity> selectUserRole(Wrapper wrapper) {
        return baseMapper.selectUserRole(wrapper);
    }

    @Override
    public Set<Long> selectUserRoleByUserId(Long id) {
        LambdaQueryWrapper<UserRoleEntity> wrapper = new LambdaQueryWrapper();
        wrapper.eq(UserRoleEntity::getUserId,id);
        List<UserRoleEntity> urs = baseMapper.selectUserRole(wrapper);
        if(CollectionUtil.isNotEmpty(urs)) {
            return urs.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toSet());
        }
        return null;
    }

    @Override
    public void initUserRole() {
         baseMapper.initUserRole();
    }

    @Override
    public Set<Long> dataSelete(OrganizationalTypeEnum organizationalTypeEnum) {
        StringBuilder whereCondition = new StringBuilder();
        LoginUser currentUser = LoginUserUtil.getLoginUser();
        UserEntity user = userService.getById(currentUser.getId());

        Set<Long> roleIds = new HashSet<>();
        if (Integer.valueOf(1).equals(currentUser.getCommonScope())) {
            roleIds = userService.selectUserRoleIdsByCommonScopeType(currentUser.getId(),currentUser.getCommonScopeType());
        } else {
            roleIds =  userService.selectUserRoleIdsByMenuId(currentUser.getId(),currentUser.getScopeMenuId());
        }
        if (CollectionUtil.isNotEmpty(roleIds)) {
            List<RoleEntity> roles = roleService.listByIds(roleIds).stream().collect(Collectors.toList());
            boolean allDataScope = this.isAllDataScope(roles);
            Set<Long> dataIds = new HashSet<>();

            if (organizationalTypeEnum.equals(OrganizationalTypeEnum.COMPANY_GROUP)){
                //集团通过菜单权限判定
//                    return dataIds;
                List<CompanyEntity> companyList = companyService.list(new LambdaQueryWrapper<CompanyEntity>().eq(CompanyEntity::getIsDelete, CommonConstant.DEL_FLAG_0));
                if (CollectionUtil.isNotEmpty(companyList)) {
                    for (CompanyEntity company : companyList) {
                        dataIds.add(company.getId());
                    }
                }
            }
            if (organizationalTypeEnum.equals(OrganizationalTypeEnum.SUB_COMPANY_GROUP)){
                if (!allDataScope) {
                    //分公司权限判定
                    Long selfSubCompanyId = this.getSubCompanyId(roles, user);
                    Set<Long> selfSubCompanyIds = this.getSubCompanyIds(roles, user);
//                    dataIds.add(selfSubCompanyId);
                    dataIds.addAll(selfSubCompanyIds);
//                    return dataIds;
                }else {
                    List<SubCompanyEntity> subCompanyList = subCompanyService.list(new LambdaQueryWrapper<SubCompanyEntity>().eq(SubCompanyEntity::getIsDelete, CommonConstant.DEL_FLAG_0));
                    if (CollectionUtil.isNotEmpty(subCompanyList)) {
                        for (SubCompanyEntity subCompany : subCompanyList) {
                            dataIds.add(subCompany.getId());
                        }
                    }
                }
            }
            if (organizationalTypeEnum.equals(OrganizationalTypeEnum.DEPT_GROUP)){
                if (!allDataScope) {
                    Long selfSubCompanyId = this.getSubCompanyId(roles, user);
                    if (!Objects.isNull(selfSubCompanyId)) {
                        List<DeptEntity> deptList = departService.list(new LambdaQueryWrapper<DeptEntity>().eq(DeptEntity::getSubCompanyId, selfSubCompanyId));
                        List<Long> subDeptIds = deptList.stream().map(DeptEntity::getId).collect(Collectors.toList());
                        dataIds.addAll(subDeptIds);
                    }
                    Set<Long> deptIds = this.getDeptIds(roles, user);
                    dataIds.addAll(deptIds);
//                    return dataIds;
                }else {
                    List<DeptEntity> deptList = departService.list(new LambdaQueryWrapper<DeptEntity>().eq(DeptEntity::getIsDelete, CommonConstant.DEL_FLAG_0));
                    if (CollectionUtil.isNotEmpty(deptList)) {
                        for (DeptEntity dept : deptList) {
                            dataIds.add(dept.getId());
                        }
                    }
                }
            }
            if (organizationalTypeEnum.equals(OrganizationalTypeEnum.USER_GROUP)){
                if (!allDataScope) {
                    Long selfSubCompanyId = this.getSubCompanyId(roles, user);
                    if (!Objects.isNull(selfSubCompanyId)) {
                        List<UserEntity> userList = userService.list(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getSubCompanyId, selfSubCompanyId));
                        List<Long> userIds = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
                        dataIds.addAll(userIds);
                    }
                    Set<Long> deptIds = this.getDeptIds(roles, user);
                    if (CollectionUtil.isNotEmpty(deptIds)) {
                        List<UserEntity> userList = userService.list(new LambdaQueryWrapper<UserEntity>().in(UserEntity::getDeptId, deptIds));
                        List<Long> userIds = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
                        dataIds.addAll(userIds);
                    }
                    dataIds.add(user.getId());
//                    return dataIds;
                }else {
                    List<UserEntity> userList = userService.list(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getIsDelete, CommonConstant.DEL_FLAG_0));
                    if (CollectionUtil.isNotEmpty(userList)) {
                        for (UserEntity userEntity : userList) {
                            dataIds.add(userEntity.getId());
                        }
                    }
                }

            }
            return dataIds;
        }else {
            // 如果没有权限就让他查不到数据
            return Set.of(0L);
        }

    }

    @Override
    public Boolean dataAllSelete(OrganizationalTypeEnum organizationalTypeEnum) {

        StringBuilder whereCondition = new StringBuilder();
        LoginUser currentUser = LoginUserUtil.getLoginUser();
        UserEntity user = userService.getById(currentUser.getId());
        Set<Long> roleIds = new HashSet<>();
        if (Integer.valueOf(1).equals(currentUser.getCommonScope())) {
            roleIds = userService.selectUserRoleIdsByCommonScopeType(currentUser.getId(),currentUser.getCommonScopeType());
        } else {
            roleIds =  userService.selectUserRoleIdsByMenuId(currentUser.getId(),currentUser.getScopeMenuId());
        }
        if (CollectionUtil.isNotEmpty(roleIds)) {
            List<RoleEntity> roles = roleService.listByIds(roleIds).stream().collect(Collectors.toList());
            boolean allDataScope = this.isAllDataScope(roles);
            return allDataScope;
        }
        return false;
    }


    public boolean isAllDataScope(List<RoleEntity> roleSet) {
        for (RoleEntity role : roleSet) {
            if (scopeType[0].equals(role.getDataScope())) {
                return true;
            }
        }
        return false;
    }

    public Long getSubCompanyId(List<RoleEntity> roleSet, UserEntity user) {
        // 存储本公司的数据权限
        for (RoleEntity role : roleSet) {
            if (scopeType[1].equals(role.getDataScope())) {
                return user.getSubCompanyId();
            }
        }

        return null;
    }

    public Set<Long> getSubCompanyIds(List<RoleEntity> roleSet, UserEntity user) {
        // 存储本公司的数据权限
        Set<Long> subIds =  new HashSet<>();
        for (RoleEntity role : roleSet) {
            if (scopeType[1].equals(role.getDataScope())) {
                subIds.add(user.getSubCompanyId());
            }

            if (scopeType[2].equals(role.getDataScope())) {
                //deptIds.add(user.getDept().getId());
                List<SubCompanyEntity> subCompanyEntities = subCompanyService.getHasSublist(role.getId());
                if (!CollectionUtils.isEmpty(subCompanyEntities)){
                    subIds.addAll(subCompanyEntities.stream().map(SubCompanyEntity::getId).collect(Collectors.toList()));
                }
            }

        }
        return subIds;
    }
    public Set<Long> getDeptIds(List<RoleEntity> roleSet, UserEntity user) {
        // 用于存储部门id
        Set<Long> deptIds = new HashSet<>();

        for (RoleEntity role : roleSet) {
            if (scopeType[0].equals(role.getDataScope())) {
                return new HashSet<>();
            }


            // 存储自定义的数据权限
            if (scopeType[2].equals(role.getDataScope())) {
                Set<DeptEntity> depts = departService.findByRoleId(role.getId());
                for (DeptEntity dept : depts) {
                    deptIds.add(dept.getId());
                    List<DeptEntity> deptChildren = departService.findByPid(dept.getId());
                    if (deptChildren != null && deptChildren.size() != 0) {
                        deptIds.addAll(departService.getDeptChildren(deptChildren));
                    }
                }
            }
            // 存储本部的数据权限
            if (scopeType[4].equals(role.getDataScope())) {
                //deptIds.add(user.getDept().getId());
                deptIds.add(user.getDeptId());
            }
        }
        return deptIds;
    }
}
