using FluentValidation;
using IamService.API.Application.Commands.UserProfiles;

namespace IamService.API.Application.Validations;

/// <summary>
/// EN: Validator for UpdateUserProfileCommand.
/// VI: Validator cho UpdateUserProfileCommand.
/// </summary>
public class UpdateUserProfileCommandValidator : AbstractValidator<UpdateUserProfileCommand>
{
    public UpdateUserProfileCommandValidator()
    {
        RuleFor(x => x.UserId)
            .NotEmpty().WithMessage("User ID is required");

        RuleFor(x => x.Bio)
            .MaximumLength(2000).WithMessage("Bio cannot exceed 2000 characters")
            .When(x => x.Bio != null);

        RuleFor(x => x.Timezone)
            .MaximumLength(50).WithMessage("Timezone cannot exceed 50 characters")
            .Matches(@"^[A-Za-z_/]+$").WithMessage("Invalid timezone format (use IANA format like 'Asia/Ho_Chi_Minh')")
            .When(x => x.Timezone != null);

        RuleFor(x => x.Locale)
            .MaximumLength(10).WithMessage("Locale cannot exceed 10 characters")
            .Matches(@"^[a-z]{2}(-[A-Z]{2})?$").WithMessage("Invalid locale format (use format like 'en-US' or 'vi-VN')")
            .When(x => x.Locale != null);

        RuleFor(x => x.AvatarUrl)
            .MaximumLength(500).WithMessage("Avatar URL cannot exceed 500 characters")
            .Must(url => url == null || Uri.TryCreate(url, UriKind.Absolute, out _))
            .WithMessage("Avatar URL must be a valid URL")
            .When(x => x.AvatarUrl != null);
    }
}

/// <summary>
/// EN: Validator for SetProfileAttributeCommand.
/// VI: Validator cho SetProfileAttributeCommand.
/// </summary>
public class SetProfileAttributeCommandValidator : AbstractValidator<SetProfileAttributeCommand>
{
    private static readonly string[] ValidValueTypes = ["String", "Number", "Boolean", "Date", "Json"];

    public SetProfileAttributeCommandValidator()
    {
        RuleFor(x => x.UserId)
            .NotEmpty().WithMessage("User ID is required");

        RuleFor(x => x.Key)
            .NotEmpty().WithMessage("Attribute key is required")
            .MaximumLength(100).WithMessage("Key cannot exceed 100 characters")
            .Matches(@"^[a-z][a-z0-9_\.]*$").WithMessage("Key must start with lowercase letter and contain only lowercase letters, numbers, underscores, and dots");

        RuleFor(x => x.Value)
            .NotEmpty().WithMessage("Attribute value is required")
            .MaximumLength(4000).WithMessage("Value cannot exceed 4000 characters");

        RuleFor(x => x.ValueType)
            .NotEmpty().WithMessage("Value type is required")
            .Must(t => ValidValueTypes.Contains(t))
            .WithMessage($"Value type must be one of: {string.Join(", ", ValidValueTypes)}");
    }
}
