using FluentAssertions;
using SIGCM2.Domain.Exceptions;

namespace SIGCM2.Application.Tests.Domain.Rubros;

public class RubroExceptionsTests
{
    // ── RubroNotFoundException ───────────────────────────────────────────────

    [Fact]
    public void RubroNotFoundException_ContainsId()
    {
        var ex = new RubroNotFoundException(42);

        ex.Id.Should().Be(42);
        ex.Message.Should().Contain("42");
    }

    [Fact]
    public void RubroNotFoundException_InheritsFromDomainException()
    {
        var ex = new RubroNotFoundException(1);

        ex.Should().BeAssignableTo<DomainException>();
    }

    // ── RubroNombreDuplicadoEnPadreException ─────────────────────────────────

    [Fact]
    public void RubroNombreDuplicadoEnPadreException_ContainsNombreAndParentId()
    {
        var ex = new RubroNombreDuplicadoEnPadreException("Autos", parentId: 5);

        ex.Nombre.Should().Be("Autos");
        ex.ParentId.Should().Be(5);
        ex.Message.Should().Contain("Autos");
    }

    [Fact]
    public void RubroNombreDuplicadoEnPadreException_WithNullParent_IsValid()
    {
        var ex = new RubroNombreDuplicadoEnPadreException("Autos", parentId: null);

        ex.Nombre.Should().Be("Autos");
        ex.ParentId.Should().BeNull();
    }

    [Fact]
    public void RubroNombreDuplicadoEnPadreException_InheritsFromDomainException()
    {
        var ex = new RubroNombreDuplicadoEnPadreException("x", null);

        ex.Should().BeAssignableTo<DomainException>();
    }

    // ── RubroMaxDepthExceededException ───────────────────────────────────────

    [Fact]
    public void RubroMaxDepthExceededException_ContainsDepthInfo()
    {
        var ex = new RubroMaxDepthExceededException(intentada: 11, max: 10);

        ex.Intentada.Should().Be(11);
        ex.Max.Should().Be(10);
        ex.Message.Should().Contain("11");
        ex.Message.Should().Contain("10");
    }

    [Fact]
    public void RubroMaxDepthExceededException_InheritsFromDomainException()
    {
        var ex = new RubroMaxDepthExceededException(11, 10);

        ex.Should().BeAssignableTo<DomainException>();
    }

    // ── RubroCycleDetectedException ──────────────────────────────────────────

    [Fact]
    public void RubroCycleDetectedException_ContainsRubroIdAndIntendedParentId()
    {
        var ex = new RubroCycleDetectedException(rubroId: 5, nuevoParentId: 10);

        ex.RubroId.Should().Be(5);
        ex.NuevoParentId.Should().Be(10);
        ex.Message.Should().Contain("5");
        ex.Message.Should().Contain("10");
    }

    [Fact]
    public void RubroCycleDetectedException_InheritsFromDomainException()
    {
        var ex = new RubroCycleDetectedException(1, 2);

        ex.Should().BeAssignableTo<DomainException>();
    }

    // ── RubroTieneHijosActivosException ─────────────────────────────────────

    [Fact]
    public void RubroTieneHijosActivosException_ContainsIdAndCount()
    {
        var ex = new RubroTieneHijosActivosException(id: 7, count: 3);

        ex.Id.Should().Be(7);
        ex.Count.Should().Be(3);
        ex.Message.Should().Contain("3");
        ex.Message.Should().Contain("subrubros");
    }

    [Fact]
    public void RubroTieneHijosActivosException_InheritsFromDomainException()
    {
        var ex = new RubroTieneHijosActivosException(1, 2);

        ex.Should().BeAssignableTo<DomainException>();
    }

    // ── RubroPadreInactivoException ──────────────────────────────────────────

    [Fact]
    public void RubroPadreInactivoException_ContainsParentId()
    {
        var ex = new RubroPadreInactivoException(parentId: 9);

        ex.ParentId.Should().Be(9);
        ex.Message.Should().Contain("9");
    }

    [Fact]
    public void RubroPadreInactivoException_InheritsFromDomainException()
    {
        var ex = new RubroPadreInactivoException(1);

        ex.Should().BeAssignableTo<DomainException>();
    }
}
