package org.nl.system.service.permission.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils;
import org.nl.system.service.dict.dao.Dict;
import org.nl.system.service.dict.dao.mapper.SysDictMapper;
import org.nl.system.service.permission.ISysDataPermissionService;
import org.nl.system.service.permission.dao.SysDataPermission;
import org.nl.system.service.permission.dao.SysDataScope;
import org.nl.system.service.permission.dao.mapper.SysDataPermissionMapper;
import org.nl.system.service.permission.dto.DataScopeEnum;
import org.nl.system.service.permission.dto.SysDataPermissionQuery;
import org.nl.system.service.user.ISysUserService;
import org.nl.system.service.user.dto.UserDataPermissionDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;

/**
 * <p>
 * 数据数据权限表 服务实现类
 * </p>
 *
 * @author generator
 * @since 2022-12-20
 */
@Service
public class SysDataPermissionServiceImpl extends ServiceImpl<SysDataPermissionMapper, SysDataPermission> implements ISysDataPermissionService {

    @Autowired
    private SysDataPermissionMapper dataPermissionMapper;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysDictMapper dictMapper;

    @Override
    public IPage<SysDataPermission> queryAll(SysDataPermissionQuery dataPermissionQuery, PageQuery page) {
        return this.page(page.build(SysDataPermission.class), dataPermissionQuery.build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SysDataPermission permission) {
        SysDataPermission sysDataPermission = dataPermissionMapper.selectOne(new LambdaQueryWrapper<SysDataPermission>().eq(SysDataPermission::getCode, permission.getCode()));
        if (ObjectUtil.isNotEmpty(sysDataPermission)) throw new BadRequestException("编码为[" + permission.getCode() + "]的数据权限已存在");
        String currentUserId = SecurityUtils.getCurrentUserId();
        String nickName = SecurityUtils.getCurrentNickName();
        String now = DateUtil.now();

        permission.setPermission_id(IdUtil.getSnowflake(1, 1).nextIdStr());
        permission.setCreate_id(currentUserId);
        permission.setCreate_name(nickName);
        permission.setUpdate_id(currentUserId);
        permission.setUpdate_name(nickName);
        permission.setUpdate_time(now);
        permission.setCreate_time(now);
        dataPermissionMapper.insert(permission);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysDataPermission permission) {
        SysDataPermission dataPermission = dataPermissionMapper.selectById(permission.getPermission_id());
        if (ObjectUtil.isEmpty(dataPermission)) throw new BadRequestException("被删除或无权限，操作失败!");
        permission.setUpdate_time(DateUtil.now());
        permission.setUpdate_id(SecurityUtils.getCurrentUserId());
        permission.setUpdate_name(SecurityUtils.getCurrentNickName());
        dataPermissionMapper.updateById(permission);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Set<String> ids) {
        ids.forEach(id -> {
            List<UserDataPermissionDto> permissions = userService.getUserDataPermissionByPermissionId(id);
            if (ObjectUtil.isNotEmpty(permissions)) throw new BadRequestException("存在相关联的数据权限，请解除关联后删除");
            dataPermissionMapper.deleteById(id);
        });
    }

    @Override
    public List<Dict> getDataScopeType() {
        return dictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, "permission_scope_type"));
    }

    @Override
    public List<SysDataPermission> getDataPermissionOption() {
        return this.list();
    }

    @Override
    public List<UserDataPermissionDto> getDataShow(String userId) {
        List<UserDataPermissionDto> userDataPermissionDtoList = userService.getUserDataPermissionByUserId(userId);
        userDataPermissionDtoList.forEach(userDataPermissionDto -> {
            SysDataPermission sysDataPermission = dataPermissionMapper.selectOne(new LambdaQueryWrapper<SysDataPermission>().eq(SysDataPermission::getPermission_id, userDataPermissionDto.getPermission_id()));
            if (sysDataPermission.getCode().equals(DataScopeEnum.USER.getCode())) { // 用户权限
                List<String> userIds = dataPermissionMapper.findDataScopeUserIdBySelfUserIdAndScopeType(userId, userDataPermissionDto.getPermission_scope_type());
                if (ObjectUtil.isNotEmpty(userIds)) userDataPermissionDto.setUsers(userIds);
            } else if (sysDataPermission.getCode().equals(DataScopeEnum.DEPT.getCode())) { // 部门权限
                List<String> deptIds = dataPermissionMapper.findDataScopeDeptIdBySelfUserIdAndScopeType(userId, userDataPermissionDto.getPermission_scope_type());
                if (ObjectUtil.isNotEmpty(deptIds)) userDataPermissionDto.setDepts(deptIds);
            } else if (sysDataPermission.getCode().equals(DataScopeEnum.SELF.getCode())) { // 自身
                List<String> userIds = dataPermissionMapper.findDataScopeUserIdBySelfUserIdAndScopeType(userId, userDataPermissionDto.getPermission_scope_type());
                if (ObjectUtil.isNotEmpty(userIds)) userDataPermissionDto.setUsers(userIds);
            }
            // 其他不做处理
        });
        return userDataPermissionDtoList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePermission(JSONObject datas) {
        String user_id = datas.getString("user_id");
        JSONArray data = datas.getJSONArray("datas");
        if (ObjectUtil.isEmpty(user_id)) throw new BadRequestException("用户不能为空");
        // 删除用户绑定的数据
        userService.deleteDataPermissionById(user_id);
        dataPermissionMapper.deleteScopeBySelfUserId(user_id);
        for (int i = 0; i < data.size(); i++) {
            JSONObject scopeObj = data.getJSONObject(i);
            String permission_scope_type = scopeObj.getString("value");
            String permission_id = scopeObj.getString("permission_id");
            UserDataPermissionDto userDataPermissionDto = new UserDataPermissionDto();
            userDataPermissionDto.setUser_id(user_id);
            userDataPermissionDto.setPermission_id(permission_id);
            userDataPermissionDto.setPermission_scope_type(permission_scope_type);
            // 保存用户数据权限
            userService.insertDataPermission(userDataPermissionDto);
            JSONArray users = scopeObj.getJSONArray("users");
            if (ObjectUtil.isNotEmpty(users)) { // 如果是用户直接将用户的id绑定进去
                for (int j = 0; j < users.size(); j++) {
                    JSONObject user = users.getJSONObject(j);
                    String userId = user.getString("user_id");
                    SysDataScope dataScope = new SysDataScope();
                    dataScope.setUser_id(userId);
                    dataScope.setSelf_user_id(user_id);
                    dataScope.setPermission_scope_type(permission_scope_type);
                    dataPermissionMapper.insertDataScope(dataScope);
                }
            }
            JSONArray depts = scopeObj.getJSONArray("depts");
            if (ObjectUtil.isNotEmpty(depts)) { // 如果是部门，先根据部门id求出所有的用户id
                for (int j = 0; j < depts.size(); j++) {
                    JSONObject dept = depts.getJSONObject(j);
                    String dept_id = dept.getString("dept_id");
                    List<String> user_ids = userService.getUserIdByDeptId(dept_id);
                    user_ids.forEach(id -> {
                        SysDataScope dataScope = new SysDataScope();
                        dataScope.setUser_id(id);
                        dataScope.setDept_id(dept_id);
                        dataScope.setSelf_user_id(user_id);
                        dataScope.setPermission_scope_type(permission_scope_type);
                        dataPermissionMapper.insertDataScopes(dataScope);
                    });
                }
            }
        }
    }

    @Override
    public List<SysDataScope> getDataDetail(JSONObject data) {
        return dataPermissionMapper.getDataDetail(data.getString("userId"), data.getString("permissionScopeType"));
    }
}
