using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants;
using ColaFlow.Modules.Identity.Domain.Aggregates.Users;

namespace ColaFlow.Modules.Identity.Domain.Repositories;

/// <summary>
/// Repository interface for User aggregate
/// </summary>
public interface IUserRepository
{
    /// <summary>
    /// Get user by ID
    /// </summary>
    Task<User?> GetByIdAsync(UserId userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Get user by Guid ID
    /// </summary>
    Task<User?> GetByIdAsync(Guid userId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Get multiple users by their IDs
    /// </summary>
    Task<IReadOnlyList<User>> GetByIdsAsync(
        IEnumerable<Guid> userIds,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Get user by email within a tenant
    /// </summary>
    Task<User?> GetByEmailAsync(TenantId tenantId, Email email, CancellationToken cancellationToken = default);

    /// <summary>
    /// Get user by external SSO ID within a tenant
    /// </summary>
    Task<User?> GetByExternalIdAsync(
        TenantId tenantId,
        AuthenticationProvider provider,
        string externalUserId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Check if an email already exists within a tenant
    /// </summary>
    Task<bool> ExistsByEmailAsync(TenantId tenantId, Email email, CancellationToken cancellationToken = default);

    /// <summary>
    /// Get all users for a tenant
    /// </summary>
    Task<IReadOnlyList<User>> GetAllByTenantAsync(TenantId tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Get active users count for a tenant
    /// </summary>
    Task<int> GetActiveUsersCountAsync(TenantId tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Add a new user
    /// </summary>
    Task AddAsync(User user, CancellationToken cancellationToken = default);

    /// <summary>
    /// Update an existing user
    /// </summary>
    Task UpdateAsync(User user, CancellationToken cancellationToken = default);

    /// <summary>
    /// Delete a user (hard delete)
    /// </summary>
    Task DeleteAsync(User user, CancellationToken cancellationToken = default);
}
