// EN: Validators for FnB Engine commands (sessions, tables, tickets, reservations).
// VI: Validators cho cac commands FnB Engine (phien, ban, phieu bep, dat cho).

using FluentValidation;
using FnbEngine.API.Application.Commands;

namespace FnbEngine.API.Application.Validations;

/// <summary>
/// EN: Validator for OpenSessionCommand.
/// VI: Validator cho OpenSessionCommand.
/// </summary>
public class OpenSessionCommandValidator : AbstractValidator<OpenSessionCommand>
{
    public OpenSessionCommandValidator()
    {
        RuleFor(x => x.TableId)
            .NotEmpty()
            .WithMessage("Table ID is required / Table ID la bat buoc");

        RuleFor(x => x.ShopId)
            .NotEmpty()
            .WithMessage("Shop ID is required / Shop ID la bat buoc");

        RuleFor(x => x.GuestCount)
            .GreaterThan(0)
            .WithMessage("Guest count must be greater than zero / So khach phai lon hon 0")
            .LessThanOrEqualTo(100)
            .WithMessage("Guest count must not exceed 100 / So khach khong vuot qua 100");
    }
}

/// <summary>
/// EN: Validator for CloseSessionCommand.
/// VI: Validator cho CloseSessionCommand.
/// </summary>
public class CloseSessionCommandValidator : AbstractValidator<CloseSessionCommand>
{
    public CloseSessionCommandValidator()
    {
        RuleFor(x => x.SessionId)
            .NotEmpty()
            .WithMessage("Session ID is required / Session ID la bat buoc");
    }
}

/// <summary>
/// EN: Validator for ChangeTableStatusCommand.
/// VI: Validator cho ChangeTableStatusCommand.
/// </summary>
public class ChangeTableStatusCommandValidator : AbstractValidator<ChangeTableStatusCommand>
{
    private static readonly string[] ValidStatuses = ["Available", "Occupied", "Cleaning", "Reserved", "OutOfService"];

    public ChangeTableStatusCommandValidator()
    {
        RuleFor(x => x.TableId)
            .NotEmpty()
            .WithMessage("Table ID is required / Table ID la bat buoc");

        RuleFor(x => x.Status)
            .NotEmpty()
            .WithMessage("Status is required / Trang thai la bat buoc")
            .MaximumLength(50)
            .WithMessage("Status must not exceed 50 characters / Trang thai khong vuot qua 50 ky tu")
            .Must(s => ValidStatuses.Contains(s))
            .WithMessage("Invalid status. Valid values: Available, Occupied, Cleaning, Reserved, OutOfService / Trang thai khong hop le");
    }
}

/// <summary>
/// EN: Validator for UpdateTableCommand.
/// VI: Validator cho UpdateTableCommand.
/// </summary>
public class UpdateTableCommandValidator : AbstractValidator<UpdateTableCommand>
{
    public UpdateTableCommandValidator()
    {
        RuleFor(x => x.TableId)
            .NotEmpty()
            .WithMessage("Table ID is required / Table ID la bat buoc");

        RuleFor(x => x.Capacity)
            .GreaterThan(0)
            .WithMessage("Capacity must be greater than zero / Suc chua phai lon hon 0")
            .When(x => x.Capacity.HasValue);

        RuleFor(x => x.Zone)
            .MaximumLength(100)
            .WithMessage("Zone must not exceed 100 characters / Khu vuc khong vuot qua 100 ky tu")
            .When(x => x.Zone != null);

        RuleFor(x => x.HourlyRate)
            .GreaterThanOrEqualTo(0)
            .WithMessage("Hourly rate must not be negative / Gia theo gio khong duoc am")
            .When(x => x.HourlyRate.HasValue);
    }
}

/// <summary>
/// EN: Validator for UpdateTicketStatusCommand.
/// VI: Validator cho UpdateTicketStatusCommand.
/// </summary>
public class UpdateTicketStatusCommandValidator : AbstractValidator<UpdateTicketStatusCommand>
{
    private static readonly string[] ValidStatuses = ["Pending", "InProgress", "Ready", "Served", "Cancelled"];

    public UpdateTicketStatusCommandValidator()
    {
        RuleFor(x => x.TicketId)
            .NotEmpty()
            .WithMessage("Ticket ID is required / Ticket ID la bat buoc");

        RuleFor(x => x.Status)
            .NotEmpty()
            .WithMessage("Status is required / Trang thai la bat buoc")
            .MaximumLength(50)
            .WithMessage("Status must not exceed 50 characters / Trang thai khong vuot qua 50 ky tu")
            .Must(s => ValidStatuses.Contains(s))
            .WithMessage("Invalid status. Valid values: Pending, InProgress, Ready, Served, Cancelled / Trang thai khong hop le");
    }
}

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

        RuleFor(x => x.GuestName)
            .NotEmpty()
            .WithMessage("Guest name is required / Ten khach la bat buoc")
            .MaximumLength(200)
            .WithMessage("Guest name must not exceed 200 characters / Ten khach khong vuot qua 200 ky tu");

        RuleFor(x => x.PartySize)
            .GreaterThan(0)
            .WithMessage("Party size must be greater than zero / So nguoi phai lon hon 0")
            .LessThanOrEqualTo(100)
            .WithMessage("Party size must not exceed 100 / So nguoi khong vuot qua 100");

        RuleFor(x => x.ReservationTime)
            .GreaterThan(DateTime.UtcNow.AddMinutes(-5))
            .WithMessage("Reservation time must be in the future / Thoi gian dat cho phai trong tuong lai");

        RuleFor(x => x.Phone)
            .MaximumLength(20)
            .WithMessage("Phone must not exceed 20 characters / So dien thoai khong vuot qua 20 ky tu")
            .Matches(@"^[\d\+\-\(\)\s]+$")
            .WithMessage("Invalid phone format / Dinh dang so dien thoai khong hop le")
            .When(x => x.Phone != null);

        RuleFor(x => x.Note)
            .MaximumLength(1000)
            .WithMessage("Note must not exceed 1000 characters / Ghi chu khong vuot qua 1000 ky tu")
            .When(x => x.Note != null);
    }
}

/// <summary>
/// EN: Validator for CreateKitchenTicketCommand.
/// VI: Validator cho CreateKitchenTicketCommand.
/// </summary>
public class CreateKitchenTicketCommandValidator : AbstractValidator<CreateKitchenTicketCommand>
{
    public CreateKitchenTicketCommandValidator()
    {
        RuleFor(x => x.SessionId)
            .NotEmpty()
            .WithMessage("Session ID is required / Session ID la bat buoc");

        RuleFor(x => x.OrderItemId)
            .NotEmpty()
            .WithMessage("Order item ID is required / Order item ID la bat buoc");

        RuleFor(x => x.ItemName)
            .NotEmpty()
            .WithMessage("Item name is required / Ten mon la bat buoc")
            .MaximumLength(200)
            .WithMessage("Item name must not exceed 200 characters / Ten mon khong vuot qua 200 ky tu");

        RuleFor(x => x.Station)
            .MaximumLength(100)
            .WithMessage("Station must not exceed 100 characters / Tram bep khong vuot qua 100 ky tu")
            .When(x => x.Station != null);

        RuleFor(x => x.Priority)
            .InclusiveBetween(0, 10)
            .WithMessage("Priority must be between 0 and 10 / Do uu tien phai tu 0 den 10");

        RuleFor(x => x.Quantity)
            .GreaterThan(0)
            .WithMessage("Quantity must be greater than zero / So luong phai lon hon 0");
    }
}
