using FluentAssertions;
using SIGCM2.Domain.Exceptions;
using SIGCM2.Domain.Pricing.Exceptions;

namespace SIGCM2.Application.Tests.Domain.Pricing.Exceptions;

/// <summary>
/// PRC-001 — T2.1 Domain unit tests for Pricing exceptions.
/// Verifies constructor props, message content, and DomainException inheritance.
/// </summary>
public sealed class PricingExceptionTests
{
    // ── EmojiDetectedException ────────────────────────────────────────────────

    [Fact]
    public void EmojiDetectedException_SetsDetectedCodepoint()
    {
        var ex = new EmojiDetectedException(0x1F697); // 🚗

        ex.DetectedCodepoint.Should().Be(0x1F697);
    }

    [Fact]
    public void EmojiDetectedException_MessageContainsCodepoint()
    {
        var ex = new EmojiDetectedException(0x1F697);

        ex.Message.Should().NotBeNullOrWhiteSpace();
    }

    [Fact]
    public void EmojiDetectedException_InheritsFromDomainException()
    {
        var ex = new EmojiDetectedException(0x1F697);

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

    // ── WordCountValidationException ─────────────────────────────────────────

    [Fact]
    public void WordCountValidationException_SetsFieldAndReason()
    {
        var ex = new WordCountValidationException("rawText", "El texto supera el máximo de 2000 caracteres.");

        ex.Field.Should().Be("rawText");
        ex.Reason.Should().Be("El texto supera el máximo de 2000 caracteres.");
    }

    [Fact]
    public void WordCountValidationException_MessageContainsFieldAndReason()
    {
        var ex = new WordCountValidationException("rawText", "supera el máximo");

        ex.Message.Should().Contain("rawText");
        ex.Message.Should().Contain("supera el máximo");
    }

    [Fact]
    public void WordCountValidationException_InheritsFromDomainException()
    {
        var ex = new WordCountValidationException("field", "reason");

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

    // ── ChargeableCharConfigInvalidException ─────────────────────────────────

    [Fact]
    public void ChargeableCharConfigInvalidException_SetsFieldAndReason()
    {
        var ex = new ChargeableCharConfigInvalidException("PricePerUnit", "debe ser > 0");

        ex.Field.Should().Be("PricePerUnit");
        ex.Reason.Should().Be("debe ser > 0");
    }

    [Fact]
    public void ChargeableCharConfigInvalidException_MessageContainsFieldAndReason()
    {
        var ex = new ChargeableCharConfigInvalidException("Symbol", "no puede estar vacío");

        ex.Message.Should().Contain("Symbol");
        ex.Message.Should().Contain("no puede estar vacío");
    }

    [Fact]
    public void ChargeableCharConfigInvalidException_InheritsFromDomainException()
    {
        var ex = new ChargeableCharConfigInvalidException("field", "reason");

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

    // ── ChargeableCharConfigForwardOnlyException ──────────────────────────────

    [Fact]
    public void ChargeableCharConfigForwardOnlyException_SetsAllProperties()
    {
        var newVf    = new DateOnly(2026, 3, 1);
        var activeVf = new DateOnly(2026, 4, 1);

        var ex = new ChargeableCharConfigForwardOnlyException(
            productTypeId: 5, symbol: "$", newValidFrom: newVf, activeValidFrom: activeVf);

        ex.ProductTypeId.Should().Be(5);
        ex.Symbol.Should().Be("$");
        ex.NewValidFrom.Should().Be(newVf);
        ex.ActiveValidFrom.Should().Be(activeVf);
    }

    [Fact]
    public void ChargeableCharConfigForwardOnlyException_NullProductTypeId_IsAllowed()
    {
        var ex = new ChargeableCharConfigForwardOnlyException(
            productTypeId: null, symbol: "$",
            newValidFrom: new DateOnly(2026, 3, 1),
            activeValidFrom: new DateOnly(2026, 4, 1));

        ex.ProductTypeId.Should().BeNull();
    }

    [Fact]
    public void ChargeableCharConfigForwardOnlyException_MessageContainsKeyDates()
    {
        var newVf    = new DateOnly(2026, 3, 1);
        var activeVf = new DateOnly(2026, 4, 1);

        var ex = new ChargeableCharConfigForwardOnlyException(
            productTypeId: null, symbol: "$", newValidFrom: newVf, activeValidFrom: activeVf);

        ex.Message.Should().Contain("2026-03-01");
        ex.Message.Should().Contain("2026-04-01");
    }

    [Fact]
    public void ChargeableCharConfigForwardOnlyException_InheritsFromDomainException()
    {
        var ex = new ChargeableCharConfigForwardOnlyException(
            productTypeId: null, symbol: "$",
            newValidFrom: new DateOnly(2026, 3, 1),
            activeValidFrom: new DateOnly(2026, 4, 1));

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