namespace Domain.Entities;

/// <summary>
/// Represents a system user for authentication and authorization.
/// </summary>
public class User
{
    public int Id { get; private set; }
    public string Username { get; private set; } = string.Empty;
    public string PasswordHash { get; private set; } = string.Empty;
    public string RecoveryCodeHash { get; private set; } = string.Empty;
    public string Role { get; private set; } = UserRoles.Student;
    public int? StudentId { get; private set; }
    public DateTime CreatedAt { get; private set; }
    public DateTime? LastLoginAt { get; private set; }

    // Navigation property
    public Student? Student { get; private set; }

    private User() { }

    public static User Create(string username, string passwordHash, string recoveryCodeHash, string role, int? studentId = null)
    {
        if (string.IsNullOrWhiteSpace(username))
            throw new ArgumentException("Username cannot be empty", nameof(username));

        if (string.IsNullOrWhiteSpace(passwordHash))
            throw new ArgumentException("Password hash cannot be empty", nameof(passwordHash));

        if (!UserRoles.IsValid(role))
            throw new ArgumentException($"Invalid role: {role}", nameof(role));

        return new User
        {
            Username = username.ToLowerInvariant(),
            PasswordHash = passwordHash,
            RecoveryCodeHash = recoveryCodeHash,
            Role = role,
            StudentId = studentId,
            CreatedAt = DateTime.UtcNow
        };
    }

    public void UpdatePassword(string newPasswordHash)
    {
        if (string.IsNullOrWhiteSpace(newPasswordHash))
            throw new ArgumentException("Password hash cannot be empty", nameof(newPasswordHash));
        PasswordHash = newPasswordHash;
    }

    public void UpdateLastLogin()
    {
        LastLoginAt = DateTime.UtcNow;
    }

    public bool IsAdmin => Role == UserRoles.Admin;
    public bool IsStudent => Role == UserRoles.Student;
}

/// <summary>
/// Constants for user roles.
/// </summary>
public static class UserRoles
{
    public const string Admin = "Admin";
    public const string Student = "Student";

    public static bool IsValid(string role) =>
        role == Admin || role == Student;
}
