// EN: Validators for Storage commands (upload, delete, share, admin).
// VI: Validators cho cac commands Storage (upload, xoa, chia se, admin).

using FluentValidation;
using StorageService.API.Application.Commands;
using StorageService.API.Application.Commands.Admin;
using StorageService.API.Application.Commands.FileShare;

namespace StorageService.API.Application.Validations;

/// <summary>
/// EN: Validator for UploadFileCommand.
/// VI: Validator cho UploadFileCommand.
/// </summary>
public class UploadFileCommandValidator : AbstractValidator<UploadFileCommand>
{
    private static readonly long MaxFileSizeBytes = 500L * 1024 * 1024; // 500 MB

    public UploadFileCommandValidator()
    {
        RuleFor(x => x.FileName)
            .NotEmpty()
            .WithMessage("File name is required / Ten file la bat buoc")
            .MaximumLength(255)
            .WithMessage("File name must not exceed 255 characters / Ten file khong vuot qua 255 ky tu")
            .Must(name => !name.Contains("..") && !name.Contains('/') && !name.Contains('\\'))
            .WithMessage("File name contains invalid characters / Ten file chua ky tu khong hop le");

        RuleFor(x => x.ContentType)
            .NotEmpty()
            .WithMessage("Content type is required / Content type la bat buoc")
            .MaximumLength(100)
            .WithMessage("Content type must not exceed 100 characters / Content type khong vuot qua 100 ky tu");

        RuleFor(x => x.FileSizeBytes)
            .GreaterThan(0)
            .WithMessage("File size must be greater than zero / Kich thuoc file phai lon hon 0")
            .LessThanOrEqualTo(MaxFileSizeBytes)
            .WithMessage("File size exceeds maximum limit of 500 MB / Kich thuoc file vuot qua gioi han 500 MB");

        RuleFor(x => x.UserId)
            .NotEmpty()
            .WithMessage("User ID is required / User ID la bat buoc")
            .MaximumLength(128)
            .WithMessage("User ID must not exceed 128 characters / User ID khong vuot qua 128 ky tu");

        RuleFor(x => x.TenantId)
            .MaximumLength(128)
            .WithMessage("Tenant ID must not exceed 128 characters / Tenant ID khong vuot qua 128 ky tu")
            .When(x => x.TenantId != null);
    }
}

/// <summary>
/// EN: Validator for SignUploadCommand.
/// VI: Validator cho SignUploadCommand.
/// </summary>
public class SignUploadCommandValidator : AbstractValidator<SignUploadCommand>
{
    private static readonly long MaxFileSizeBytes = 500L * 1024 * 1024; // 500 MB

    public SignUploadCommandValidator()
    {
        RuleFor(x => x.UserId)
            .NotEmpty()
            .WithMessage("User ID is required / User ID la bat buoc")
            .MaximumLength(128)
            .WithMessage("User ID must not exceed 128 characters / User ID khong vuot qua 128 ky tu");

        RuleFor(x => x.FileName)
            .NotEmpty()
            .WithMessage("File name is required / Ten file la bat buoc")
            .MaximumLength(255)
            .WithMessage("File name must not exceed 255 characters / Ten file khong vuot qua 255 ky tu")
            .Must(name => !name.Contains("..") && !name.Contains('/') && !name.Contains('\\'))
            .WithMessage("File name contains invalid characters / Ten file chua ky tu khong hop le");

        RuleFor(x => x.ContentType)
            .NotEmpty()
            .WithMessage("Content type is required / Content type la bat buoc")
            .MaximumLength(100)
            .WithMessage("Content type must not exceed 100 characters / Content type khong vuot qua 100 ky tu");

        RuleFor(x => x.FileSizeBytes)
            .GreaterThan(0)
            .WithMessage("File size must be greater than zero / Kich thuoc file phai lon hon 0")
            .LessThanOrEqualTo(MaxFileSizeBytes)
            .WithMessage("File size exceeds maximum limit of 500 MB / Kich thuoc file vuot qua gioi han 500 MB");

        RuleFor(x => x.TenantId)
            .MaximumLength(128)
            .WithMessage("Tenant ID must not exceed 128 characters / Tenant ID khong vuot qua 128 ky tu")
            .When(x => x.TenantId != null);
    }
}

/// <summary>
/// EN: Validator for ConfirmUploadCommand.
/// VI: Validator cho ConfirmUploadCommand.
/// </summary>
public class ConfirmUploadCommandValidator : AbstractValidator<ConfirmUploadCommand>
{
    public ConfirmUploadCommandValidator()
    {
        RuleFor(x => x.UserId)
            .NotEmpty()
            .WithMessage("User ID is required / User ID la bat buoc")
            .MaximumLength(128)
            .WithMessage("User ID must not exceed 128 characters / User ID khong vuot qua 128 ky tu");

        RuleFor(x => x.ObjectKey)
            .NotEmpty()
            .WithMessage("Object key is required / Object key la bat buoc")
            .MaximumLength(1024)
            .WithMessage("Object key must not exceed 1024 characters / Object key khong vuot qua 1024 ky tu");

        RuleFor(x => x.FileName)
            .NotEmpty()
            .WithMessage("File name is required / Ten file la bat buoc")
            .MaximumLength(255)
            .WithMessage("File name must not exceed 255 characters / Ten file khong vuot qua 255 ky tu");

        RuleFor(x => x.ContentType)
            .NotEmpty()
            .WithMessage("Content type is required / Content type la bat buoc")
            .MaximumLength(100)
            .WithMessage("Content type must not exceed 100 characters / Content type khong vuot qua 100 ky tu");

        RuleFor(x => x.FileSizeBytes)
            .GreaterThan(0)
            .WithMessage("File size must be greater than zero / Kich thuoc file phai lon hon 0");
    }
}

/// <summary>
/// EN: Validator for DeleteFileCommand.
/// VI: Validator cho DeleteFileCommand.
/// </summary>
public class DeleteFileCommandValidator : AbstractValidator<DeleteFileCommand>
{
    public DeleteFileCommandValidator()
    {
        RuleFor(x => x.FileId)
            .NotEmpty()
            .WithMessage("File ID is required / File ID la bat buoc");

        RuleFor(x => x.UserId)
            .NotEmpty()
            .WithMessage("User ID is required / User ID la bat buoc")
            .MaximumLength(128)
            .WithMessage("User ID must not exceed 128 characters / User ID khong vuot qua 128 ky tu");
    }
}

/// <summary>
/// EN: Validator for CreateFileShareCommand.
/// VI: Validator cho CreateFileShareCommand.
/// </summary>
public class CreateFileShareCommandValidator : AbstractValidator<CreateFileShareCommand>
{
    public CreateFileShareCommandValidator()
    {
        RuleFor(x => x.FileId)
            .NotEmpty()
            .WithMessage("File ID is required / File ID la bat buoc");

        RuleFor(x => x.UserId)
            .NotEmpty()
            .WithMessage("User ID is required / User ID la bat buoc")
            .MaximumLength(128)
            .WithMessage("User ID must not exceed 128 characters / User ID khong vuot qua 128 ky tu");

        RuleFor(x => x.SharedWith)
            .MaximumLength(256)
            .WithMessage("Shared with must not exceed 256 characters / Chia se voi khong vuot qua 256 ky tu")
            .When(x => x.SharedWith != null);

        RuleFor(x => x.Password)
            .MinimumLength(4)
            .WithMessage("Password must be at least 4 characters / Mat khau phai it nhat 4 ky tu")
            .MaximumLength(100)
            .WithMessage("Password must not exceed 100 characters / Mat khau khong vuot qua 100 ky tu")
            .When(x => x.Password != null);

        RuleFor(x => x.MaxDownloads)
            .GreaterThan(0)
            .WithMessage("Max downloads must be greater than zero / So luot tai toi da phai lon hon 0")
            .LessThanOrEqualTo(10000)
            .WithMessage("Max downloads must not exceed 10000 / So luot tai toi da khong vuot qua 10000")
            .When(x => x.MaxDownloads.HasValue);

        RuleFor(x => x.ExpiresAt)
            .GreaterThan(DateTime.UtcNow)
            .WithMessage("Expiration time must be in the future / Thoi gian het han phai trong tuong lai")
            .When(x => x.ExpiresAt.HasValue);
    }
}

/// <summary>
/// EN: Validator for UpdateUserQuotaCommand.
/// VI: Validator cho UpdateUserQuotaCommand.
/// </summary>
public class UpdateUserQuotaCommandValidator : AbstractValidator<UpdateUserQuotaCommand>
{
    public UpdateUserQuotaCommandValidator()
    {
        RuleFor(x => x.TargetUserId)
            .NotEmpty()
            .WithMessage("Target user ID is required / User ID muc tieu la bat buoc")
            .MaximumLength(128)
            .WithMessage("Target user ID must not exceed 128 characters / User ID muc tieu khong vuot qua 128 ky tu");

        RuleFor(x => x.MaxStorageBytes)
            .GreaterThan(0)
            .WithMessage("Max storage must be greater than zero / Dung luong toi da phai lon hon 0");

        RuleFor(x => x.MaxFileCount)
            .GreaterThan(0)
            .WithMessage("Max file count must be greater than zero / So file toi da phai lon hon 0");

        RuleFor(x => x.QuotaTier)
            .MaximumLength(50)
            .WithMessage("Quota tier must not exceed 50 characters / Goi quota khong vuot qua 50 ky tu")
            .When(x => x.QuotaTier != null);
    }
}
