package top.tqx.demo_1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.tqx.demo_1.dto.FilePermissionRequest;
import top.tqx.demo_1.entity.Department;
import top.tqx.demo_1.entity.File;
import top.tqx.demo_1.entity.FilePermission;
import top.tqx.demo_1.entity.Role;
import top.tqx.demo_1.entity.User;
import top.tqx.demo_1.exception.PermissionDeniedException;
import top.tqx.demo_1.mapper.DepartmentMapper;
import top.tqx.demo_1.mapper.FileMapper;
import top.tqx.demo_1.mapper.FilePermissionMapper;
import top.tqx.demo_1.mapper.UserMapper;
import top.tqx.demo_1.mapper.UserRoleMapper;
import top.tqx.demo_1.service.DataPermissionService;
import top.tqx.demo_1.service.FilePermissionService;
import top.tqx.demo_1.service.LogService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class FilePermissionServiceImpl implements FilePermissionService {
    
    @Autowired
    private FilePermissionMapper filePermissionMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private FileMapper fileMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private DepartmentMapper departmentMapper;
    
    @Autowired
    private DataPermissionService dataPermissionService;
    
    @Autowired
    private LogService logService;
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 检查用户是否有文件访问权限
     */
    @Override
    public boolean checkFilePermission(Long userId, Long fileId, Integer requiredPermission) {
        // 1. 超级管理员拥有所有权限
        if (isSuperAdmin(userId)) {
            return true;
        }
        
        // 2. 检查文件是否存在
        File file = fileMapper.selectById(fileId);
        if (file == null) {
            return false;
        }
        
        // 3. 检查是否是文件上传者
        if (file.getUploadUserId() != null && file.getUploadUserId().equals(userId)) {
            return true;
        }
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            return false;
        }
        
        // 4. 检查文件是否属于用户所在部门（支持多部门）
        if (isFileOwnedByUserDept(file, user.getDeptId())) {
            // 如果是本部门文件，部门管理员有权限
            if (isDeptAdmin(userId)) {
                return true;
            }
            // 公开文件本部门用户可访问
            if (file.getIsPublic() != null && file.getIsPublic() == 1) {
                return true;
            }
        }
        
        // 5. 检查授予的用户权限
        FilePermission userPermission = filePermissionMapper.selectByUserAndFile(userId, fileId);
        if (userPermission != null && userPermission.getPermissionType() >= requiredPermission) {
            if (userPermission.getExpireTime() == null || userPermission.getExpireTime().isAfter(LocalDateTime.now())) {
                return true;
            }
        }
        
        // 6. 检查授予的部门权限
        if (user.getDeptId() != null) {
            FilePermission deptPermission = filePermissionMapper.selectByDeptAndFile(user.getDeptId(), fileId);
            if (deptPermission != null && deptPermission.getPermissionType() >= requiredPermission) {
                if (deptPermission.getExpireTime() == null || deptPermission.getExpireTime().isAfter(LocalDateTime.now())) {
                    return true;
                }
            }
        }
        
        // 7. 检查上级部门权限（递归检查）
        if (user.getDeptId() != null) {
            List<Long> ancestorDeptIds = getAncestorDeptIds(user.getDeptId());
            for (Long ancestorDeptId : ancestorDeptIds) {
                FilePermission ancestorPermission = filePermissionMapper.selectByDeptAndFile(ancestorDeptId, fileId);
                if (ancestorPermission != null && ancestorPermission.getPermissionType() >= requiredPermission) {
                    if (ancestorPermission.getExpireTime() == null || ancestorPermission.getExpireTime().isAfter(LocalDateTime.now())) {
                        return true;
                    }
                }
            }
        }
        
        return false;
    }

    /**
     * 授予文件权限（支持用户和部门）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grantFilePermission(FilePermissionRequest request) {
        Long currentUserId = getCurrentUserId();
        
        // 验证当前用户是否为部门管理员
        if (!isDeptAdmin(currentUserId) && !isSuperAdmin(currentUserId)) {
            throw new PermissionDeniedException("只有部门管理员可以授予权限");
        }
        
        // 验证文件是否存在
        File file = fileMapper.selectById(request.getFileId());
        if (file == null) {
            throw new RuntimeException("文件不存在");
        }
        
        // 验证文件是否属于本部门（支持多部门检查）
        User currentUser = userMapper.selectById(currentUserId);
        if (currentUser != null && currentUser.getDeptId() != null) {
            if (!isFileOwnedByUserDept(file, currentUser.getDeptId())) {
                throw new PermissionDeniedException("只能管理本部门的文件权限");
            }
        }
        
        // 如果是按部门授权
        if (request.getDeptId() != null || (request.getDeptIds() != null && !request.getDeptIds().isEmpty())) {
            List<Long> targetDeptIds = new ArrayList<>();
            if (request.getDeptId() != null) {
                targetDeptIds.add(request.getDeptId());
            }
            if (request.getDeptIds() != null) {
                targetDeptIds.addAll(request.getDeptIds());
            }
            
            for (Long deptId : targetDeptIds) {
                // 检查是否已存在该部门的权限记录
                FilePermission existing = filePermissionMapper.selectByDeptAndFile(deptId, request.getFileId());
                if (existing != null) {
                    // 更新已有权限
                    existing.setPermissionType(request.getPermissionType());
                    existing.setExpireTime(request.getExpireTime());
                    filePermissionMapper.updateById(existing);
                } else {
                    // 创建新权限记录
                    FilePermission permission = new FilePermission();
                    permission.setFileId(request.getFileId());
                    permission.setDeptId(deptId);
                    permission.setPermissionType(request.getPermissionType());
                    permission.setGrantUserId(currentUserId);
                    permission.setExpireTime(request.getExpireTime());
                    filePermissionMapper.insert(permission);
                }
            }
            
            if (logService != null) {
                logService.recordLog(currentUserId, "GRANT_DEPT_PERMISSION",
                        String.format("授予部门%s文件%d的权限", targetDeptIds, request.getFileId()));
            }
        } else if (request.getUserId() != null) {
            // 按用户授权
            FilePermission existing = filePermissionMapper.selectByUserAndFile(request.getUserId(), request.getFileId());
            if (existing != null) {
                existing.setPermissionType(request.getPermissionType());
                existing.setExpireTime(request.getExpireTime());
                filePermissionMapper.updateById(existing);
            } else {
                FilePermission permission = new FilePermission();
                permission.setFileId(request.getFileId());
                permission.setUserId(request.getUserId());
                permission.setPermissionType(request.getPermissionType());
                permission.setGrantUserId(currentUserId);
                permission.setExpireTime(request.getExpireTime());
                filePermissionMapper.insert(permission);
            }
            
            if (logService != null) {
                logService.recordLog(currentUserId, "GRANT_PERMISSION",
                        String.format("授予用户%d文件%d的权限", request.getUserId(), request.getFileId()));
            }
        }
    }
    
    /**
     * 撤销文件权限
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revokeFilePermission(Long permissionId) {
        Long currentUserId = getCurrentUserId();
        
        FilePermission permission = filePermissionMapper.selectById(permissionId);
        if (permission == null) {
            throw new RuntimeException("权限记录不存在");
        }
        
        // 验证是否是部门管理员或授权人
        if (!isDeptAdmin(currentUserId) && !isSuperAdmin(currentUserId) && !permission.getGrantUserId().equals(currentUserId)) {
            throw new PermissionDeniedException("无权撤销此权限");
        }
        
        filePermissionMapper.deleteById(permissionId);
        
        if (logService != null) {
            String targetType = permission.getUserId() != null ? "用户" : "部门";
            Long targetId = permission.getUserId() != null ? permission.getUserId() : permission.getDeptId();
            logService.recordLog(currentUserId, "REVOKE_PERMISSION",
                    String.format("撤销%s%d的文件权限", targetType, targetId));
        }
    }
    
    /**
     * 更新权限过期时间
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePermissionExpire(Long permissionId, LocalDateTime expireTime) {
        Long currentUserId = getCurrentUserId();
        
        FilePermission permission = filePermissionMapper.selectById(permissionId);
        if (permission == null) {
            throw new RuntimeException("权限记录不存在");
        }
        
        if (!isDeptAdmin(currentUserId) && !isSuperAdmin(currentUserId) && !permission.getGrantUserId().equals(currentUserId)) {
            throw new PermissionDeniedException("无权修改此权限");
        }
        
        permission.setExpireTime(expireTime);
        filePermissionMapper.updateById(permission);
        
        if (logService != null) {
            logService.recordLog(currentUserId, "UPDATE_PERMISSION_EXPIRE",
                    String.format("更新权限过期时间为%s", expireTime));
        }
    }
    
    /**
     * 获取用户的文件权限列表
     */
    @Override
    public List<FilePermission> getUserFilePermissions(Long userId, Long fileId) {
        List<FilePermission> permissions = new ArrayList<>();
        
        // 获取用户个人权限
        List<FilePermission> userPerms = filePermissionMapper.selectByUserIdAndFileId(userId, fileId);
        if (userPerms != null) {
            permissions.addAll(userPerms);
        }
        
        // 获取用户所在部门的权限
        User user = userMapper.selectById(userId);
        if (user != null && user.getDeptId() != null) {
            FilePermission deptPerm = filePermissionMapper.selectByDeptAndFile(user.getDeptId(), fileId);
            if (deptPerm != null) {
                permissions.add(deptPerm);
            }
        }
        
        return permissions;
    }
    
    /**
     * 获取有权限访问文件的所有用户
     */
    @Override
    public List<User> getFileAuthorizedUsers(Long fileId) {
        Set<Long> userIds = new HashSet<>();
        
        // 1. 获取直接授权的用户
        List<FilePermission> userPermissions = filePermissionMapper.selectByFileId(fileId);
        for (FilePermission perm : userPermissions) {
            if (perm.getUserId() != null) {
                userIds.add(perm.getUserId());
            }
        }
        
        // 2. 获取授权部门的用户
        List<FilePermission> deptPermissions = filePermissionMapper.selectByFileId(fileId);
        for (FilePermission perm : deptPermissions) {
            if (perm.getDeptId() != null) {
                List<User> deptUsers = userMapper.selectList(
                    new LambdaQueryWrapper<User>().eq(User::getDeptId, perm.getDeptId()));
                for (User user : deptUsers) {
                    userIds.add(user.getId());
                }
            }
        }
        
        // 3. 添加文件上传者
        File file = fileMapper.selectById(fileId);
        if (file != null && file.getUploadUserId() != null) {
            userIds.add(file.getUploadUserId());
        }
        
        if (userIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        return userMapper.selectBatchIds(new ArrayList<>(userIds));
    }
    
    /**
     * 检查文件是否属于用户所在部门（支持多部门）
     */
    private boolean isFileOwnedByUserDept(File file, Long userDeptId) {
        if (userDeptId == null) {
            return false;
        }
        
        // 检查单个部门
        if (file.getDeptId() != null && file.getDeptId().equals(userDeptId)) {
            return true;
        }
        
        // 检查多部门
        if (file.getDeptIds() != null && !file.getDeptIds().isNull()) {
            if (file.getDeptIds().isArray()) {
                for (JsonNode node : file.getDeptIds()) {
                    if (node.asLong() == userDeptId) {
                        return true;
                    }
                }
            }
        }
        
        return false;
    }
    
    /**
     * 获取上级部门ID列表
     */
    private List<Long> getAncestorDeptIds(Long deptId) {
        List<Long> ancestorIds = new ArrayList<>();
        Department current = departmentMapper.selectById(deptId);
        while (current != null && current.getParentId() != null && current.getParentId() > 0) {
            ancestorIds.add(current.getParentId());
            current = departmentMapper.selectById(current.getParentId());
        }
        return ancestorIds;
    }
    
    /**
     * 检查是否为超级管理员
     */
    private boolean isSuperAdmin(Long userId) {
        List<Role> roles = userRoleMapper.selectRolesByUserId(userId);
        return roles.stream()
            .anyMatch(role -> "SUPER_ADMIN".equals(role.getRoleCode()));
    }
    
    /**
     * 检查是否为部门管理员
     */
    private boolean isDeptAdmin(Long userId) {
        List<Role> roles = userRoleMapper.selectRolesByUserId(userId);
        return roles.stream()
            .anyMatch(role -> "DEPT_ADMIN".equals(role.getRoleCode()));
    }
    
    /**
     * 获取当前登录用户 ID
     */
    private Long getCurrentUserId() {
        try {
            org.springframework.web.context.request.RequestAttributes attributes = 
                org.springframework.web.context.request.RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                jakarta.servlet.http.HttpServletRequest request = 
                    ((org.springframework.web.context.request.ServletRequestAttributes) attributes).getRequest();
                String token = request.getHeader("Authorization");
                if (token != null && token.startsWith("Bearer ")) {
                    // 需要通过 AuthService 验证 token
                }
            }
        } catch (Exception e) {
            // 忽略异常
        }
        return null;
    }
}