// EN: Validators for Wallet commands (deposit, withdraw, create wallet, exchange).
// VI: Validators cho cac commands Wallet (nap tien, rut tien, tao vi, quy doi).

using FluentValidation;
using WalletService.API.Application.Commands;

namespace WalletService.API.Application.Validations;

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

        RuleFor(x => x.Currency)
            .NotEmpty()
            .WithMessage("Currency is required / Tien te la bat buoc")
            .MaximumLength(10)
            .WithMessage("Currency code must not exceed 10 characters / Ma tien te khong vuot qua 10 ky tu");
    }
}

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

        RuleFor(x => x.Amount)
            .GreaterThan(0)
            .WithMessage("Amount must be greater than zero / So tien phai lon hon 0")
            .LessThanOrEqualTo(1_000_000_000m)
            .WithMessage("Amount exceeds maximum limit / So tien vuot qua gioi han toi da");

        RuleFor(x => x.Description)
            .NotEmpty()
            .WithMessage("Description is required / Mo ta la bat buoc")
            .MaximumLength(500)
            .WithMessage("Description must not exceed 500 characters / Mo ta khong vuot qua 500 ky tu");

        RuleFor(x => x.ReferenceId)
            .MaximumLength(100)
            .WithMessage("Reference ID must not exceed 100 characters / Ma tham chieu khong vuot qua 100 ky tu")
            .When(x => x.ReferenceId != null);
    }
}

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

        RuleFor(x => x.Amount)
            .GreaterThan(0)
            .WithMessage("Amount must be greater than zero / So tien phai lon hon 0")
            .LessThanOrEqualTo(1_000_000_000m)
            .WithMessage("Amount exceeds maximum limit / So tien vuot qua gioi han toi da");

        RuleFor(x => x.Description)
            .NotEmpty()
            .WithMessage("Description is required / Mo ta la bat buoc")
            .MaximumLength(500)
            .WithMessage("Description must not exceed 500 characters / Mo ta khong vuot qua 500 ky tu");

        RuleFor(x => x.ReferenceId)
            .MaximumLength(100)
            .WithMessage("Reference ID must not exceed 100 characters / Ma tham chieu khong vuot qua 100 ky tu")
            .When(x => x.ReferenceId != null);
    }
}

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

        RuleFor(x => x.FromAmount)
            .GreaterThan(0)
            .WithMessage("From amount must be greater than zero / So tien quy doi phai lon hon 0");

        RuleFor(x => x.FromCurrencyTypeId)
            .GreaterThan(0)
            .WithMessage("From currency type is required / Loai tien nguon la bat buoc");

        RuleFor(x => x.ToCurrencyTypeId)
            .GreaterThan(0)
            .WithMessage("To currency type is required / Loai tien dich la bat buoc")
            .NotEqual(x => x.FromCurrencyTypeId)
            .WithMessage("Cannot exchange to same currency type / Khong the quy doi cung loai tien te");

        RuleFor(x => x.CustomRate)
            .GreaterThan(0)
            .WithMessage("Custom rate must be greater than zero / Ty gia tuy chinh phai lon hon 0")
            .When(x => x.CustomRate.HasValue);
    }
}
