using Books.E2E.Tests.Infrastructure;
using Books.E2E.Tests.Pages;
using Books.E2E.Tests.Pages.Modals;
using Books.E2E.Tests.TestData;

namespace Books.E2E.Tests.Tests.Orders;

/// <summary>
/// E2E tests for order line management.
/// Tests adding, viewing, and managing order lines.
///
/// Prerequisites:
/// - Backend and frontend running
/// - At least one company and customer exist
/// - Ability to create orders
/// </summary>
[Trait("Category", "E2E")]
public class OrderLineTests : E2ETestBase
{
    public OrderLineTests(
        E2ETestFixture fixture,
        PlaywrightFixture playwright)
        : base(fixture, playwright)
    {
    }

    [Fact]
    public async Task AddOrderLine_WithValidData_AddsLineSuccessfully()
    {
        // Arrange - Create a new order first
        await Page.GotoAsync($"{Config.FrontendUrl}/ordrer");
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();

        // Create order
        await ordersPage.ClickNewOrder();
        var createModal = new CreateOrderModalPage(Page);
        await createModal.WaitForModalToOpen();
        await createModal.SelectCustomer("");
        await createModal.Submit();

        // Wait for drawer
        var drawer = new OrderDrawerPage(Page);
        await drawer.WaitForDrawerToOpen();

        // Verify no lines initially
        (await drawer.IsNoLinesAlertVisible()).Should().BeTrue("New order should have no lines");

        // Act - Add a line
        await drawer.ClickAddLine();

        var addLineModal = new AddOrderLineModalPage(Page);
        await addLineModal.WaitForModalToOpen();

        var description = TestDataGenerator.GenerateOrderLineDescription();
        var quantity = TestDataGenerator.GenerateQuantity(1, 10);
        var unitPrice = TestDataGenerator.GenerateUnitPrice(500m, 2000m);

        await addLineModal.FillBasicLine(description, quantity, unitPrice);
        await addLineModal.Submit();

        // Assert
        await Task.Delay(500); // Wait for drawer to update
        var lineCount = await drawer.GetLineCount();
        lineCount.Should().BeGreaterThan(0, "Order should have at least one line after adding");

        var lineDescriptions = await drawer.GetLineDescriptions();
        lineDescriptions.Should().Contain(d => d.Contains(description), "Added line description should be visible");
    }

    [Fact]
    public async Task AddOrderLine_WithAllFields_AddsLineCorrectly()
    {
        // Arrange - Create a new order first
        await Page.GotoAsync($"{Config.FrontendUrl}/ordrer");
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();

        await ordersPage.ClickNewOrder();
        var createModal = new CreateOrderModalPage(Page);
        await createModal.WaitForModalToOpen();
        await createModal.SelectCustomer("");
        await createModal.Submit();

        var drawer = new OrderDrawerPage(Page);
        await drawer.WaitForDrawerToOpen();

        // Act - Add a line with all fields
        await drawer.ClickAddLine();

        var addLineModal = new AddOrderLineModalPage(Page);
        await addLineModal.WaitForModalToOpen();

        var description = "Konsulentbistand premium";
        await addLineModal.FillCompleteLine(
            description: description,
            quantity: 8,
            unit: "timer",
            unitPrice: 1250.00m,
            discountPercent: 10m,
            vatCode: "S25"
        );
        await addLineModal.Submit();

        // Assert
        await Task.Delay(500);
        var lineDescriptions = await drawer.GetLineDescriptions();
        lineDescriptions.Should().Contain(d => d.Contains(description));
    }

    [Fact]
    public async Task AddOrderLine_WithoutDescription_ShowsValidationError()
    {
        // Arrange
        await Page.GotoAsync($"{Config.FrontendUrl}/ordrer");
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();

        await ordersPage.ClickNewOrder();
        var createModal = new CreateOrderModalPage(Page);
        await createModal.WaitForModalToOpen();
        await createModal.SelectCustomer("");
        await createModal.Submit();

        var drawer = new OrderDrawerPage(Page);
        await drawer.WaitForDrawerToOpen();

        // Act - Try to add line without description
        await drawer.ClickAddLine();

        var addLineModal = new AddOrderLineModalPage(Page);
        await addLineModal.WaitForModalToOpen();

        // Only fill quantity and price, not description
        await addLineModal.EnterQuantity(1);
        await addLineModal.EnterUnitPrice(100m);
        await addLineModal.Submit();

        // Assert
        (await addLineModal.HasValidationErrors()).Should().BeTrue("Should show validation error for missing description");
    }

    [Fact]
    public async Task AddOrderLine_CanCancelModal()
    {
        // Arrange
        await Page.GotoAsync($"{Config.FrontendUrl}/ordrer");
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();

        await ordersPage.ClickNewOrder();
        var createModal = new CreateOrderModalPage(Page);
        await createModal.WaitForModalToOpen();
        await createModal.SelectCustomer("");
        await createModal.Submit();

        var drawer = new OrderDrawerPage(Page);
        await drawer.WaitForDrawerToOpen();

        // Act
        await drawer.ClickAddLine();
        var addLineModal = new AddOrderLineModalPage(Page);
        await addLineModal.WaitForModalToOpen();

        await addLineModal.EnterDescription("This should not be saved");
        await addLineModal.Cancel();

        // Assert
        (await addLineModal.IsVisible()).Should().BeFalse("Modal should be closed after cancel");
        (await drawer.IsNoLinesAlertVisible()).Should().BeTrue("No lines should be added after cancel");
    }

    [Fact]
    public async Task AddMultipleOrderLines_DisplaysAllLines()
    {
        // Arrange
        await Page.GotoAsync($"{Config.FrontendUrl}/ordrer");
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();

        await ordersPage.ClickNewOrder();
        var createModal = new CreateOrderModalPage(Page);
        await createModal.WaitForModalToOpen();
        await createModal.SelectCustomer("");
        await createModal.Submit();

        var drawer = new OrderDrawerPage(Page);
        await drawer.WaitForDrawerToOpen();

        // Act - Add multiple lines
        var lineDescriptions = new[] { "Linje 1 - Analyse", "Linje 2 - Design", "Linje 3 - Udvikling" };

        foreach (var desc in lineDescriptions)
        {
            await drawer.ClickAddLine();
            var addLineModal = new AddOrderLineModalPage(Page);
            await addLineModal.WaitForModalToOpen();
            await addLineModal.FillBasicLine(desc, 1, 1000m);
            await addLineModal.Submit();
            await Task.Delay(300); // Wait for modal to close and drawer to update
        }

        // Assert
        var lineCount = await drawer.GetLineCount();
        lineCount.Should().Be(3, "Order should have 3 lines");

        var displayedDescriptions = await drawer.GetLineDescriptions();
        foreach (var desc in lineDescriptions)
        {
            displayedDescriptions.Should().Contain(d => d.Contains(desc), $"Line '{desc}' should be visible");
        }
    }
}
