using Kompas.Mcp.Core.Query;

namespace Kompas.Mcp.Tests;

/// <summary>Разделы «паспорта» модели: разбор списка и фильтрация рендера.</summary>
[Trait("Category", "Unit")]
public sealed class ModelSectionsTests
{
    private static ModelDescription Sample() => new()
    {
        Name = "Деталь",
        DocumentTypeName = "деталь",
        IsEmpty = false,
        Box = new BoundingBox { MinX = 0, MinY = 0, MinZ = 0, MaxX = 40, MaxY = 20, MaxZ = 15 },
        Mass = new PartInfo { Volume = 12000, Mass = 0.0942, Area = 3400, CenterX = 20, CenterY = 10, CenterZ = 7.5 },
        Bodies = [new BodyInfo { Index = 0, IsSolid = true, FaceCount = 6 }],
        FaceTypes = ["plane", "plane", "cylinder"],
        EdgeTypes = ["line", "circle"],
        Features = [new FeatureInfo { Index = 0, Name = "Эскиз:1", Kind = "sketch", Detail = "" }],
        Imported = false,
        Variables = [new VariableInfo { Name = "width", Expression = "40", Value = 40, External = false, Information = false }],
    };

    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData("all")]
    [InlineData("box,mass,bodies,topology,tree,variables")]
    public void All_sections_by_default(string? spec)
        => Assert.Equal(InspectionText.ModelSections.All, InspectionText.ParseSections(spec));

    [Fact]
    public void Subset_is_parsed_case_and_separator_tolerant()
    {
        var parsed = InspectionText.ParseSections(" Box; mass ");

        Assert.Equal(InspectionText.ModelSections.Box | InspectionText.ModelSections.Mass, parsed);
    }

    [Fact]
    public void Unknown_section_lists_the_allowed_ones()
    {
        var ex = Assert.Throws<ArgumentException>(() => InspectionText.ParseSections("box,колбаса"));

        Assert.Contains("колбаса", ex.Message, StringComparison.Ordinal);
        Assert.Contains("topology", ex.Message, StringComparison.Ordinal);
    }

    [Fact]
    public void Render_keeps_only_requested_sections()
    {
        var text = InspectionText.Render(Sample(), InspectionText.ModelSections.Box | InspectionText.ModelSections.Mass);

        Assert.Contains("Габарит", text, StringComparison.Ordinal);
        Assert.Contains("МЦХ", text, StringComparison.Ordinal);
        Assert.DoesNotContain("Топология", text, StringComparison.Ordinal);
        Assert.DoesNotContain("Дерево построения", text, StringComparison.Ordinal);
        Assert.DoesNotContain("Переменные", text, StringComparison.Ordinal);
    }

    [Fact]
    public void Box_section_carries_coordinates_not_only_sizes()
    {
        // get_bounding_box слит в describe_model — координаты габарита не должны потеряться.
        var text = InspectionText.Render(Sample(), InspectionText.ModelSections.Box);

        Assert.Contains("40.00 × 20.00 × 15.00 мм", text, StringComparison.Ordinal);
        Assert.Contains("X 0.00…40.00", text, StringComparison.Ordinal);
        Assert.Contains("Z 0.00…15.00", text, StringComparison.Ordinal);
    }
}
