package com.ruoyi.oa.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.oa.domain.SysOssAcl;
import com.ruoyi.oa.domain.vo.SysUserVo;
import com.ruoyi.oa.mapper.SysOssAclMapper;
import com.ruoyi.oa.service.SysOssAclService;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.mapper.SysOssMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class SysOssAclServiceImpl extends ServiceImpl<SysOssAclMapper, SysOssAcl> implements SysOssAclService {


    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysOssMapper sysOssMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grant(Long ossId, Long userId, Long grantBy) {
        grantBy = LoginHelper.getUserId();
        SysOssAcl acl = lambdaQuery()
                .eq(SysOssAcl::getOssId, ossId)
                .eq(SysOssAcl::getUserId, userId)
                .one();

        if (acl == null) {
            acl = new SysOssAcl();
            acl.setOssId(ossId);
            acl.setUserId(userId);
            acl.setGrantBy(grantBy);
            save(acl);
        } else {
            updateById(acl);
        }
    }

    @Override
    public void revoke(Long ossId, Long userId) {
        lambdaUpdate()
                .eq(SysOssAcl::getOssId, ossId)
                .eq(SysOssAcl::getUserId, userId)
                .remove();
    }

    @Override
    public boolean hasPerm(Long userId, Long ossId) {
        SysOssAcl acl = lambdaQuery()
                .eq(SysOssAcl::getOssId, ossId)
                .eq(SysOssAcl::getUserId, userId)
                .one();
        return acl != null;
    }

    @Override
    public List<SysUserVo> listUsersByOssId(Long ossId) {
        /* 1. 校验文件是否存在 / 是否已公开 */
        System.out.println(ossId);
        SysOss oss = sysOssMapper.selectById(ossId);
        if (oss == null) {
            throw new ServiceException("文件不存在");
        }
        if (oss.getIsPublic() == 1) {
            // 公开文件：直接返回空集（前端可用 isPublic 判断）
            return Collections.emptyList();
        }

        /* 2. 查询 ACL 获得已授权用户 ID */
        List<SysOssAcl> aclList = this.lambdaQuery()
                .eq(SysOssAcl::getOssId, ossId)
                .list();
        if (aclList.isEmpty()) {
            return Collections.emptyList();
        }

        List<Long> userIds = aclList.stream()
                .map(SysOssAcl::getUserId)
                .distinct()
                .collect(Collectors.toList());

        /* 3. 批量查询用户表 */
        List<SysUser> users = userMapper.selectBatchIds(userIds);
        /* 4. 转成 DTO */
        return users.stream().map(u -> {
            SysUserVo dto = new SysUserVo();
            dto.setUserId(u.getUserId());
            dto.setNickName(u.getNickName());
            dto.setPhonenumber(u.getPhonenumber());
            // 若 SysUser 中已有 deptName，可直接取；否则自行拼装
            if (u.getDept() != null) {
                dto.setDept(u.getDept());
            }
            return dto;
        }).collect(Collectors.toList());
    }
}
