using System;
using System.Collections.Generic;
using StellaOps.Authority.Storage.Mongo.Documents;

namespace StellaOps.Authority.Storage.Mongo.Stores;

public interface IAuthorityTokenStore
{
    ValueTask InsertAsync(AuthorityTokenDocument document, CancellationToken cancellationToken);

    ValueTask<AuthorityTokenDocument?> FindByTokenIdAsync(string tokenId, CancellationToken cancellationToken);

    ValueTask<AuthorityTokenDocument?> FindByReferenceIdAsync(string referenceId, CancellationToken cancellationToken);

    ValueTask UpdateStatusAsync(
        string tokenId,
        string status,
        DateTimeOffset? revokedAt,
        string? reason,
        string? reasonDescription,
        IReadOnlyDictionary<string, string?>? metadata,
        CancellationToken cancellationToken);

    ValueTask<long> DeleteExpiredAsync(DateTimeOffset threshold, CancellationToken cancellationToken);

    ValueTask<TokenUsageUpdateResult> RecordUsageAsync(string tokenId, string? remoteAddress, string? userAgent, DateTimeOffset observedAt, CancellationToken cancellationToken);

    ValueTask<IReadOnlyList<AuthorityTokenDocument>> ListRevokedAsync(DateTimeOffset? issuedAfter, CancellationToken cancellationToken);
}

public enum TokenUsageUpdateStatus
{
    Recorded,
    SuspectedReplay,
    MissingMetadata,
    NotFound
}

public sealed record TokenUsageUpdateResult(TokenUsageUpdateStatus Status, string? RemoteAddress, string? UserAgent);
