package com.purui.prims.headless.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.purui.prims.common.pojo.enums.ItemType;
import com.purui.prims.common.util.BeanMapper;
import com.purui.prims.headless.api.pojo.request.BatchRoleAuthReq;
import com.purui.prims.headless.api.pojo.request.RoleAuthReq;
import com.purui.prims.headless.api.pojo.response.RoleAuthResp;
import com.purui.prims.headless.server.persistence.dataobject.RoleAuthDO;
import com.purui.prims.headless.server.persistence.mapper.RoleAuthDOMapper;
import com.purui.prims.headless.server.service.RoleAuthService;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色权限表 服务实现类
 * </p>
 *
 * @author charlie
 * @since 2024-07-05
 */
@Service
public class RoleAuthServiceImpl extends ServiceImpl<RoleAuthDOMapper, RoleAuthDO> implements RoleAuthService {

    @Override
    public List<RoleAuthResp> getMetricRoleAuthList(Integer roleId) {
        return getRoleAuthList(roleId, ItemType.METRIC);
    }

    @Override
    public List<RoleAuthResp> getDatasetRoleAuthList(Integer roleId) {
        return getRoleAuthList(roleId, ItemType.DATASET);
    }

    @Override
    public List<RoleAuthResp> getDimensionRoleAuthList(Integer roleId) {
        return getRoleAuthList(roleId, ItemType.DIMENSION);
    }

    @Override
    public List<RoleAuthResp> getRoleAuthList(String dataType, Integer roleId, Long dataId) {
        QueryWrapper<RoleAuthDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                    .eq(RoleAuthDO::getDataType, dataType);
        if (dataId != null) {
            queryWrapper.lambda().eq(RoleAuthDO::getDataId, dataId);
        }
        if (roleId != null) {
            queryWrapper.lambda().eq(RoleAuthDO::getRoleId, roleId);
        }
        return list(queryWrapper).stream().map(this::convert).collect(Collectors.toList());
    }

    private List<RoleAuthResp> getRoleAuthList(Integer roleId, ItemType itemType) {
        QueryWrapper<RoleAuthDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                    .eq(RoleAuthDO::getDataType, itemType.name())
                    .eq(RoleAuthDO::getRoleId, roleId);
        return list(queryWrapper).stream().map(this::convert).collect(Collectors.toList());
    }

    @Override
    public List<RoleAuthResp> getDomainRoleAuthList(Integer roleId) {
        return getRoleAuthList(roleId, ItemType.DOMAIN);
    }

    private RoleAuthResp convert(RoleAuthDO roleAuthDO) {
        RoleAuthResp roleAuthResp = new RoleAuthResp();
        BeanMapper.mapper(roleAuthDO, roleAuthResp);
        roleAuthResp.setAuthType(Arrays.asList(roleAuthDO.getAuthType().split(",")));
        return roleAuthResp;
    }

    @Override
    public boolean grant(RoleAuthReq roleAuthReq) {
        // 先删除
        remove(new QueryWrapper<RoleAuthDO>().lambda()
                                             .eq(RoleAuthDO::getDataType, roleAuthReq.getDataType())
                                             .eq(RoleAuthDO::getDataId, roleAuthReq.getDataId()));
        RoleAuthDO roleAuthDO = new RoleAuthDO();
        roleAuthDO.setRoleId(roleAuthReq.getRoleId());
        roleAuthDO.setDataType(roleAuthReq.getDataType());
        roleAuthDO.setDataId(roleAuthReq.getDataId());
        roleAuthDO.setAuthType(String.join(",", roleAuthReq.getAuthType()));
        save(roleAuthDO);
        return true;
    }

    @Override
    public boolean batchGrant(BatchRoleAuthReq roleAuthReq) {
        roleAuthReq.getRoleIds().stream().forEach(
            roleId -> roleAuthReq.getDataIds().forEach(
                dataId -> {
                    grant(new RoleAuthReq(roleId, roleAuthReq.getDataType(), dataId, roleAuthReq.getAuthType()));
                }
            )
        );
        return true;
    }
}
