package de.effigenix.application.usermanagement;

import de.effigenix.application.usermanagement.dto.UserDTO;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.security.AuthorizationPort;

/**
 * Use Case: Get a single user by ID.
 */
public class GetUser {

    private final UserRepository userRepository;
    private final AuthorizationPort authPort;

    public GetUser(UserRepository userRepository, AuthorizationPort authPort) {
        this.userRepository = userRepository;
        this.authPort = authPort;
    }

    public Result<UserError, UserDTO> execute(String userIdValue, ActorId performedBy) {
        // 0. Authorization
        if (!authPort.can(performedBy, UserManagementAction.USER_VIEW)) {
            return Result.failure(new UserError.Unauthorized("Not authorized to view users"));
        }

        UserId userId = UserId.of(userIdValue);
        return userRepository.findById(userId)
                .mapError(err -> (UserError) new UserError.RepositoryFailure(err.message()))
                .flatMap(opt -> opt
                        .map(user -> Result.<UserError, UserDTO>success(UserDTO.from(user)))
                        .orElse(Result.failure(new UserError.UserNotFound(userId))));
    }
}
