using IamService.Domain.SeedWork;

namespace IamService.Domain.AggregatesModel.OrganizationAggregate;

/// <summary>
/// EN: Organization settings value object containing organization-level configurations.
/// VI: Value object cấu hình tổ chức chứa các thiết lập cấp tổ chức.
/// </summary>
public class OrganizationSettings : ValueObject
{
    /// <summary>
    /// EN: Whether new users can self-register to this organization.
    /// VI: Cho phép người dùng mới tự đăng ký vào tổ chức này.
    /// </summary>
    public bool AllowUserRegistration { get; }

    /// <summary>
    /// EN: Whether email verification is required for new users.
    /// VI: Yêu cầu xác thực email cho người dùng mới.
    /// </summary>
    public bool RequireEmailVerification { get; }

    /// <summary>
    /// EN: Whether 2FA is required for all users.
    /// VI: Yêu cầu 2FA cho tất cả người dùng.
    /// </summary>
    public bool Require2FA { get; }

    /// <summary>
    /// EN: Maximum number of users allowed in this organization.
    /// VI: Số lượng người dùng tối đa được phép trong tổ chức.
    /// </summary>
    public int MaxUsersLimit { get; }

    /// <summary>
    /// EN: Custom domain for the organization (e.g., auth.company.com).
    /// VI: Tên miền tùy chỉnh cho tổ chức (ví dụ: auth.company.com).
    /// </summary>
    public string? CustomDomain { get; }

    /// <summary>
    /// EN: Session timeout in minutes.
    /// VI: Thời gian hết hạn phiên tính bằng phút.
    /// </summary>
    public int SessionTimeoutMinutes { get; }

    /// <summary>
    /// EN: Private constructor for EF Core.
    /// VI: Constructor private cho EF Core.
    /// </summary>
    private OrganizationSettings()
    {
    }

    /// <summary>
    /// EN: Create organization settings with specified values.
    /// VI: Tạo cấu hình tổ chức với các giá trị được chỉ định.
    /// </summary>
    public OrganizationSettings(
        bool allowUserRegistration = true,
        bool requireEmailVerification = true,
        bool require2FA = false,
        int maxUsersLimit = 100,
        string? customDomain = null,
        int sessionTimeoutMinutes = 60)
    {
        if (maxUsersLimit < 0)
            throw new ArgumentException("Max users limit cannot be negative", nameof(maxUsersLimit));
        if (sessionTimeoutMinutes < 1)
            throw new ArgumentException("Session timeout must be at least 1 minute", nameof(sessionTimeoutMinutes));

        AllowUserRegistration = allowUserRegistration;
        RequireEmailVerification = requireEmailVerification;
        Require2FA = require2FA;
        MaxUsersLimit = maxUsersLimit;
        CustomDomain = customDomain;
        SessionTimeoutMinutes = sessionTimeoutMinutes;
    }

    /// <summary>
    /// EN: Create default organization settings.
    /// VI: Tạo cấu hình tổ chức mặc định.
    /// </summary>
    public static OrganizationSettings Default => new(
        allowUserRegistration: true,
        requireEmailVerification: true,
        require2FA: false,
        maxUsersLimit: 100,
        customDomain: null,
        sessionTimeoutMinutes: 60
    );

    /// <summary>
    /// EN: Create enterprise organization settings with stricter security.
    /// VI: Tạo cấu hình tổ chức enterprise với bảo mật nghiêm ngặt hơn.
    /// </summary>
    public static OrganizationSettings Enterprise => new(
        allowUserRegistration: false,
        requireEmailVerification: true,
        require2FA: true,
        maxUsersLimit: 1000,
        customDomain: null,
        sessionTimeoutMinutes: 30
    );

    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return AllowUserRegistration;
        yield return RequireEmailVerification;
        yield return Require2FA;
        yield return MaxUsersLimit;
        yield return CustomDomain;
        yield return SessionTimeoutMinutes;
    }
}
