// EN: Validators for Shop commands.
// VI: Validators cho các commands Shop.

using FluentValidation;
using MerchantService.API.Application.Commands.Shops;

namespace MerchantService.API.Application.Validations;

/// <summary>
/// EN: Validator for CreateShopCommand.
/// VI: Validator cho CreateShopCommand.
/// </summary>
public class CreateShopCommandValidator : AbstractValidator<CreateShopCommand>
{
    public CreateShopCommandValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty().WithMessage("Shop name is required")
            .MaximumLength(100).WithMessage("Shop name cannot exceed 100 characters");

        RuleFor(x => x.Slug)
            .NotEmpty().WithMessage("Slug is required")
            .MaximumLength(100).WithMessage("Slug cannot exceed 100 characters")
            .Matches(@"^[a-z0-9]+(?:-[a-z0-9]+)*$").WithMessage("Slug must contain only lowercase letters, numbers, and hyphens");

        RuleFor(x => x.Type)
            .NotEmpty().WithMessage("Shop type is required")
            .Must(BeValidShopType).WithMessage("Invalid shop type. Valid values: OnlineOnly, PhysicalOnly, Hybrid");

        RuleFor(x => x.Category)
            .NotEmpty().WithMessage("Business category is required");

        RuleFor(x => x.Description)
            .MaximumLength(2000).WithMessage("Description cannot exceed 2000 characters")
            .When(x => !string.IsNullOrEmpty(x.Description));

        RuleFor(x => x.Phone)
            .MaximumLength(20).WithMessage("Phone cannot exceed 20 characters")
            .When(x => !string.IsNullOrEmpty(x.Phone));

        RuleFor(x => x.Email)
            .EmailAddress().WithMessage("Invalid email format")
            .When(x => !string.IsNullOrEmpty(x.Email));

        RuleFor(x => x.Website)
            .MaximumLength(200).WithMessage("Website cannot exceed 200 characters")
            .When(x => !string.IsNullOrEmpty(x.Website));
    }

    private static bool BeValidShopType(string type)
    {
        var validTypes = new[] { "OnlineOnly", "PhysicalOnly", "Hybrid", "onlineonly", "physicalonly", "hybrid" };
        return validTypes.Contains(type);
    }
}

/// <summary>
/// EN: Validator for SetDefaultShopCommand.
/// VI: Validator cho SetDefaultShopCommand.
/// </summary>
public class SetDefaultShopCommandValidator : AbstractValidator<SetDefaultShopCommand>
{
    public SetDefaultShopCommandValidator()
    {
        RuleFor(x => x.MerchantId)
            .NotEmpty().WithMessage("Merchant ID is required / ID merchant là bắt buộc");

        RuleFor(x => x.ShopId)
            .NotEmpty().WithMessage("Shop ID is required / ID shop là bắt buộc");
    }
}

/// <summary>
/// EN: Validator for TransferShopCommand.
/// VI: Validator cho TransferShopCommand.
/// </summary>
public class TransferShopCommandValidator : AbstractValidator<TransferShopCommand>
{
    public TransferShopCommandValidator()
    {
        RuleFor(x => x.MerchantId)
            .NotEmpty().WithMessage("Merchant ID is required / ID merchant là bắt buộc");

        RuleFor(x => x.ShopId)
            .NotEmpty().WithMessage("Shop ID is required / ID shop là bắt buộc");

        RuleFor(x => x.NewMerchantId)
            .NotEmpty().WithMessage("New merchant ID is required / ID merchant mới là bắt buộc")
            .NotEqual(x => x.MerchantId).WithMessage("Cannot transfer shop to the same merchant / Không thể chuyển shop cho cùng merchant");

        RuleFor(x => x.Reason)
            .MaximumLength(500).WithMessage("Transfer reason cannot exceed 500 characters / Lý do chuyển không được vượt quá 500 ký tự")
            .When(x => !string.IsNullOrEmpty(x.Reason));
    }
}

/// <summary>
/// EN: Validator for AddShopBranchCommand.
/// VI: Validator cho AddShopBranchCommand.
/// </summary>
public class AddShopBranchCommandValidator : AbstractValidator<AddShopBranchCommand>
{
    public AddShopBranchCommandValidator()
    {
        RuleFor(x => x.ShopId)
            .NotEmpty().WithMessage("Shop ID is required");

        RuleFor(x => x.Name)
            .NotEmpty().WithMessage("Branch name is required")
            .MaximumLength(100).WithMessage("Branch name cannot exceed 100 characters");

        RuleFor(x => x.Code)
            .MaximumLength(20).WithMessage("Branch code cannot exceed 20 characters")
            .When(x => !string.IsNullOrEmpty(x.Code));

        RuleFor(x => x.Street)
            .NotEmpty().WithMessage("Street address is required")
            .MaximumLength(200).WithMessage("Street address cannot exceed 200 characters");

        RuleFor(x => x.District)
            .NotEmpty().WithMessage("District is required")
            .MaximumLength(100).WithMessage("District cannot exceed 100 characters");

        RuleFor(x => x.City)
            .NotEmpty().WithMessage("City is required")
            .MaximumLength(100).WithMessage("City cannot exceed 100 characters");

        RuleFor(x => x.Latitude)
            .InclusiveBetween(-90, 90).WithMessage("Latitude must be between -90 and 90")
            .When(x => x.Latitude.HasValue);

        RuleFor(x => x.Longitude)
            .InclusiveBetween(-180, 180).WithMessage("Longitude must be between -180 and 180")
            .When(x => x.Longitude.HasValue);

        RuleFor(x => x.Phone)
            .MaximumLength(20).WithMessage("Phone cannot exceed 20 characters")
            .When(x => !string.IsNullOrEmpty(x.Phone));
    }
}
