using Books.Api.Domain.UserAccess;

namespace Books.Api.EventFlow.Repositories;

public interface IUserCompanyAccessRepository
{
    /// <summary>
    /// Get all companies a user has access to (active only).
    /// </summary>
    Task<IReadOnlyList<UserCompanyAccessDto>> GetByUserIdAsync(
        string userId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get all users with access to a company (active only).
    /// </summary>
    Task<IReadOnlyList<UserCompanyAccessDto>> GetByCompanyIdAsync(
        string companyId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Check if a user has access to a company and return their role.
    /// Returns null if no active access exists.
    /// </summary>
    Task<UserCompanyAccessDto?> GetAccessAsync(
        string userId,
        string companyId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Check if a user has at least the specified role for a company.
    /// </summary>
    Task<bool> HasAccessAsync(
        string userId,
        string companyId,
        CompanyRole minimumRole,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get access by aggregate ID.
    /// </summary>
    Task<UserCompanyAccessDto?> GetByIdAsync(
        string accessId,
        CancellationToken cancellationToken = default);
}

public record UserCompanyAccessDto(
    string Id,
    string UserId,
    string CompanyId,
    CompanyRole Role,
    string GrantedBy,
    DateTimeOffset GrantedAt,
    bool IsActive,
    DateTimeOffset? RevokedAt,
    string? RevokedBy);
