using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace StellaOps.Authority.Storage.Mongo.Documents;

/// <summary>
/// Represents a recorded login attempt for audit and lockout purposes.
/// </summary>
[BsonIgnoreExtraElements]
public sealed class AuthorityLoginAttemptDocument
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; } = ObjectId.GenerateNewId().ToString();

    [BsonElement("eventType")]
    public string EventType { get; set; } = "authority.unknown";

    [BsonElement("outcome")]
    public string Outcome { get; set; } = "unknown";

    [BsonElement("correlationId")]
    [BsonIgnoreIfNull]
    public string? CorrelationId { get; set; }

    [BsonElement("subjectId")]
    [BsonIgnoreIfNull]
    public string? SubjectId { get; set; }

    [BsonElement("username")]
    [BsonIgnoreIfNull]
    public string? Username { get; set; }

    [BsonElement("clientId")]
    [BsonIgnoreIfNull]
    public string? ClientId { get; set; }

    [BsonElement("plugin")]
    [BsonIgnoreIfNull]
    public string? Plugin { get; set; }

    [BsonElement("successful")]
    public bool Successful { get; set; }

    [BsonElement("scopes")]
    public List<string> Scopes { get; set; } = new();

    [BsonElement("reason")]
    [BsonIgnoreIfNull]
    public string? Reason { get; set; }

    [BsonElement("remoteAddress")]
    [BsonIgnoreIfNull]
    public string? RemoteAddress { get; set; }

    [BsonElement("properties")]
    public List<AuthorityLoginAttemptPropertyDocument> Properties { get; set; } = new();

    [BsonElement("occurredAt")]
    public DateTimeOffset OccurredAt { get; set; } = DateTimeOffset.UtcNow;
}

/// <summary>
/// Represents an additional classified property captured for an authority login attempt.
/// </summary>
[BsonIgnoreExtraElements]
public sealed class AuthorityLoginAttemptPropertyDocument
{
    [BsonElement("name")]
    public string Name { get; set; } = string.Empty;

    [BsonElement("value")]
    [BsonIgnoreIfNull]
    public string? Value { get; set; }

    [BsonElement("classification")]
    public string Classification { get; set; } = "none";
}
