using FluentValidation.TestHelper;
using SIGCM2.Application.Roles.Create;

namespace SIGCM2.Application.Tests.Roles.Create;

public class CreateRolCommandValidatorTests
{
    private static CreateRolCommandValidator BuildValidator() => new();
    private static CreateRolCommand Valid() => new("cajero_senior", "Cajero Senior", "Cajero con permisos extendidos");

    // ── Happy path ─────────────────────────────────────────────────────────

    [Fact]
    public void Validate_Valid_NoErrors()
    {
        BuildValidator().TestValidate(Valid()).ShouldNotHaveAnyValidationErrors();
    }

    [Fact]
    public void Validate_NullDescripcion_IsValid()
    {
        BuildValidator().TestValidate(Valid() with { Descripcion = null }).ShouldNotHaveAnyValidationErrors();
    }

    // ── Codigo ─────────────────────────────────────────────────────────────

    [Fact]
    public void Validate_EmptyCodigo_HasError()
    {
        BuildValidator().TestValidate(Valid() with { Codigo = "" })
            .ShouldHaveValidationErrorFor(c => c.Codigo);
    }

    [Fact]
    public void Validate_CodigoTooShort_HasError()
    {
        BuildValidator().TestValidate(Valid() with { Codigo = "ab" })
            .ShouldHaveValidationErrorFor(c => c.Codigo);
    }

    [Fact]
    public void Validate_CodigoTooLong_HasError()
    {
        BuildValidator().TestValidate(Valid() with { Codigo = new string('a', 31) })
            .ShouldHaveValidationErrorFor(c => c.Codigo);
    }

    [Theory]
    [InlineData("abc")]              // boundary short
    [InlineData("cajero")]
    [InlineData("operador_ctacte")]
    [InlineData("jefe_publicidad")]
    [InlineData("a1b2")]
    public void Validate_CodigoValidFormats_NoError(string codigo)
    {
        BuildValidator().TestValidate(Valid() with { Codigo = codigo })
            .ShouldNotHaveValidationErrorFor(c => c.Codigo);
    }

    [Theory]
    [InlineData("Cajero")]           // uppercase
    [InlineData("1cajero")]          // starts with digit
    [InlineData("_cajero")]          // starts with underscore
    [InlineData("cajero senior")]    // space
    [InlineData("cajero-senior")]    // dash
    [InlineData("cajero.senior")]    // dot
    public void Validate_CodigoInvalidFormats_HasError(string codigo)
    {
        BuildValidator().TestValidate(Valid() with { Codigo = codigo })
            .ShouldHaveValidationErrorFor(c => c.Codigo);
    }

    // ── Nombre ─────────────────────────────────────────────────────────────

    [Fact]
    public void Validate_EmptyNombre_HasError()
    {
        BuildValidator().TestValidate(Valid() with { Nombre = "" })
            .ShouldHaveValidationErrorFor(c => c.Nombre);
    }

    [Fact]
    public void Validate_NombreTooLong_HasError()
    {
        BuildValidator().TestValidate(Valid() with { Nombre = new string('a', 61) })
            .ShouldHaveValidationErrorFor(c => c.Nombre);
    }

    // ── Descripcion ────────────────────────────────────────────────────────

    [Fact]
    public void Validate_DescripcionTooLong_HasError()
    {
        BuildValidator().TestValidate(Valid() with { Descripcion = new string('a', 251) })
            .ShouldHaveValidationErrorFor(c => c.Descripcion);
    }
}
