using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace StellaOps.Authority.Plugin.Standard.Storage;

internal sealed class StandardUserDocument
{
    [BsonId]
    public ObjectId Id { get; set; }

    [BsonElement("subjectId")]
    public string SubjectId { get; set; } = Guid.NewGuid().ToString("N");

    [BsonElement("username")]
    public string Username { get; set; } = string.Empty;

    [BsonElement("normalizedUsername")]
    public string NormalizedUsername { get; set; } = string.Empty;

    [BsonElement("passwordHash")]
    public string PasswordHash { get; set; } = string.Empty;

    [BsonElement("displayName")]
    [BsonIgnoreIfNull]
    public string? DisplayName { get; set; }

    [BsonElement("email")]
    [BsonIgnoreIfNull]
    public string? Email { get; set; }

    [BsonElement("requirePasswordReset")]
    public bool RequirePasswordReset { get; set; }

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

    [BsonElement("attributes")]
    public Dictionary<string, string?> Attributes { get; set; } = new(StringComparer.OrdinalIgnoreCase);

    [BsonElement("lockout")]
    public StandardLockoutState Lockout { get; set; } = new();

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

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

internal sealed class StandardLockoutState
{
    [BsonElement("failedAttempts")]
    public int FailedAttempts { get; set; }

    [BsonElement("lockoutEnd")]
    [BsonIgnoreIfNull]
    public DateTimeOffset? LockoutEnd { get; set; }

    [BsonElement("lastFailure")]
    [BsonIgnoreIfNull]
    public DateTimeOffset? LastFailure { get; set; }
}
