using Extrudex.API.DTOs.Printers;
using FluentValidation;

namespace Extrudex.API.Validators;

/// <summary>
/// Validation rules for creating a Printer.
/// </summary>
public class CreatePrinterRequestValidator : AbstractValidator<CreatePrinterRequest>
{
    private static readonly string[] ValidPrinterTypes = { "Fdm", "Resin" };
    private static readonly string[] ValidConnectionTypes = { "Mqtt", "Moonraker" };

    public CreatePrinterRequestValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty().WithMessage("Printer name is required.")
            .MaximumLength(100).WithMessage("Printer name must not exceed 100 characters.");

        RuleFor(x => x.Manufacturer)
            .NotEmpty().WithMessage("Manufacturer is required.")
            .MaximumLength(100).WithMessage("Manufacturer must not exceed 100 characters.");

        RuleFor(x => x.Model)
            .NotEmpty().WithMessage("Model is required.")
            .MaximumLength(100).WithMessage("Model must not exceed 100 characters.");

        RuleFor(x => x.PrinterType)
            .Must(x => ValidPrinterTypes.Contains(x, StringComparer.OrdinalIgnoreCase))
            .WithMessage("PrinterType must be 'Fdm' or 'Resin'.");

        RuleFor(x => x.ConnectionType)
            .Must(x => ValidConnectionTypes.Contains(x, StringComparer.OrdinalIgnoreCase))
            .WithMessage("ConnectionType must be 'Mqtt' or 'Moonraker'.");

        RuleFor(x => x.HostnameOrIp)
            .NotEmpty().WithMessage("HostnameOrIp is required.")
            .MaximumLength(255).WithMessage("HostnameOrIp must not exceed 255 characters.");

        RuleFor(x => x.Port)
            .InclusiveBetween(1, 65535).WithMessage("Port must be between 1 and 65535.");
    }
}

/// <summary>
/// Validation rules for updating a Printer.
/// </summary>
public class UpdatePrinterRequestValidator : AbstractValidator<UpdatePrinterRequest>
{
    private static readonly string[] ValidPrinterTypes = { "Fdm", "Resin" };
    private static readonly string[] ValidConnectionTypes = { "Mqtt", "Moonraker" };

    public UpdatePrinterRequestValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty().WithMessage("Printer name is required.")
            .MaximumLength(100).WithMessage("Printer name must not exceed 100 characters.");

        RuleFor(x => x.Manufacturer)
            .NotEmpty().WithMessage("Manufacturer is required.")
            .MaximumLength(100).WithMessage("Manufacturer must not exceed 100 characters.");

        RuleFor(x => x.Model)
            .NotEmpty().WithMessage("Model is required.")
            .MaximumLength(100).WithMessage("Model must not exceed 100 characters.");

        RuleFor(x => x.PrinterType)
            .Must(x => ValidPrinterTypes.Contains(x, StringComparer.OrdinalIgnoreCase))
            .WithMessage("PrinterType must be 'Fdm' or 'Resin'.");

        RuleFor(x => x.ConnectionType)
            .Must(x => ValidConnectionTypes.Contains(x, StringComparer.OrdinalIgnoreCase))
            .WithMessage("ConnectionType must be 'Mqtt' or 'Moonraker'.");

        RuleFor(x => x.HostnameOrIp)
            .NotEmpty().WithMessage("HostnameOrIp is required.")
            .MaximumLength(255).WithMessage("HostnameOrIp must not exceed 255 characters.");

        RuleFor(x => x.Port)
            .InclusiveBetween(1, 65535).WithMessage("Port must be between 1 and 65535.");
    }
}