using Kompas.Mcp.Core.Documents;
using Kompas.Mcp.Core.Drawings;

namespace Kompas.Mcp.Tests.Integration;

/// <summary>Интеграция: формат и ориентация листа чертежа (API7 ILayoutSheet.Format / ISheetFormat).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class DrawingSheetFormatTests : IntegrationTestBase
{
    private readonly DocumentService _docs;
    private readonly DrawingService _drawing;

    public DrawingSheetFormatTests(KompasFixture fx) : base(fx)
    {
        _docs = new DocumentService(fx.Session, fx.Dispatcher);
        _drawing = new DrawingService(fx.Session, fx.Dispatcher);
    }

    [Fact]
    public async Task A3_landscape()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            var r = await _drawing.SetSheetFormatAsync(PaperFormat.A3, landscape: true, width: 0, height: 0);
            Assert.Equal("A3", r.Format);
            Assert.InRange(r.Width, 419.5, 420.5);
            Assert.InRange(r.Height, 296.5, 297.5);
            Assert.True(r.Landscape);
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task A4_portrait()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            var r = await _drawing.SetSheetFormatAsync(PaperFormat.A4, landscape: false, width: 0, height: 0);
            Assert.Equal("A4", r.Format);
            Assert.InRange(r.Width, 209.5, 210.5);
            Assert.InRange(r.Height, 296.5, 297.5);
            Assert.False(r.Landscape);
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task A4_landscape_swaps_dimensions()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            var r = await _drawing.SetSheetFormatAsync(PaperFormat.A4, landscape: true, width: 0, height: 0);
            Assert.Equal("A4", r.Format);
            Assert.InRange(r.Width, 296.5, 297.5);  // своп: альбомная A4 = 297×210
            Assert.InRange(r.Height, 209.5, 210.5);
            Assert.True(r.Landscape);
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task User_landscape_dimensions_derive_orientation()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            // 500×300 (W>H) → КОМПАС выводит альбомную ориентацию (Landscape=true), W/H литеральны.
            var r = await _drawing.SetSheetFormatAsync(PaperFormat.User, landscape: false, width: 500, height: 300);
            Assert.Equal("User", r.Format);
            Assert.InRange(r.Width, 499.5, 500.5);
            Assert.InRange(r.Height, 299.5, 300.5);
            Assert.True(r.Landscape); // ориентация выведена из соотношения сторон (не из флага landscape=false)
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task User_portrait_dimensions_derive_orientation()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            // 300×500 (H>W) → книжная (Landscape=false).
            var r = await _drawing.SetSheetFormatAsync(PaperFormat.User, landscape: true, width: 300, height: 500);
            Assert.Equal("User", r.Format);
            Assert.InRange(r.Width, 299.5, 300.5);
            Assert.InRange(r.Height, 499.5, 500.5);
            Assert.False(r.Landscape); // landscape=true проигнорирован — ориентация из сторон
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task User_without_dimensions_throws()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() =>
                _drawing.SetSheetFormatAsync(PaperFormat.User, landscape: false, width: 0, height: 0));
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task Standard_with_dimensions_throws()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            await Assert.ThrowsAsync<ArgumentException>(() =>
                _drawing.SetSheetFormatAsync(PaperFormat.A3, landscape: false, width: 400, height: 0));
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task Nonexistent_sheet_throws()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            await Assert.ThrowsAsync<InvalidOperationException>(() =>
                _drawing.SetSheetFormatAsync(PaperFormat.A4, landscape: false, width: 0, height: 0, sheetNumber: 99));
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task Nonpositive_sheet_number_throws()
    {
        await _docs.CreateAsync(KompasDocumentType.Drawing);
        try
        {
            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() =>
                _drawing.SetSheetFormatAsync(PaperFormat.A4, landscape: false, width: 0, height: 0, sheetNumber: 0));
        }
        finally { await _docs.CloseAsync(save: false); }
    }

    [Fact]
    public async Task Active_document_not_drawing_throws()
    {
        await _docs.CreateAsync(KompasDocumentType.Part);
        try
        {
            await Assert.ThrowsAsync<InvalidOperationException>(() =>
                _drawing.SetSheetFormatAsync(PaperFormat.A4, landscape: false, width: 0, height: 0));
        }
        finally { await _docs.CloseAsync(save: false); }
    }
}
