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

namespace Books.E2E.Tests.Tests.Orders;

/// <summary>
/// E2E tests for the Orders page (Ordrer).
/// Tests the order list view, filtering, and navigation.
///
/// Prerequisites:
/// - Backend running at E2E_BACKEND_URL (default: https://localhost:5001)
/// - Frontend running at E2E_FRONTEND_URL (default: http://localhost:3000)
/// - At least one company and customer must exist
/// </summary>
[Trait("Category", "E2E")]
public class OrdersPageTests : E2ETestBase
{
    public OrdersPageTests(
        E2ETestFixture fixture,
        PlaywrightFixture playwright)
        : base(fixture, playwright)
    {
    }

    [Fact]
    public async Task OrdersPage_LoadsSuccessfully()
    {
        // Arrange - Navigate to orders page
        await Page.GotoAsync($"{Config.FrontendUrl}/ordrer");

        // Act
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();

        // Assert
        (await ordersPage.IsTitleVisible()).Should().BeTrue("Orders page title should be visible");
    }

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

        // Act & Assert - Statistics should be visible
        var totalStat = await ordersPage.GetTotalOrdersStat();
        var draftsStat = await ordersPage.GetDraftsStat();
        var confirmedStat = await ordersPage.GetConfirmedStat();

        totalStat.Should().NotBeNullOrEmpty("Total orders stat should be visible");
        draftsStat.Should().NotBeNullOrEmpty("Drafts stat should be visible");
        confirmedStat.Should().NotBeNullOrEmpty("Confirmed stat should be visible");
    }

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

        // Act
        await ordersPage.ClickNewOrder();

        // Assert
        var modal = Page.Locator(".ant-modal:has-text('Opret ordre')");
        (await modal.IsVisibleAsync()).Should().BeTrue("New order modal should be visible");
    }

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

        // Act
        await ordersPage.SearchOrders("TEST-SEARCH-STRING-UNLIKELY-TO-EXIST");

        // Assert - Should show empty state or no matching orders
        var hasOrders = await ordersPage.GetOrderCount() > 0;
        var hasEmptyState = await ordersPage.IsEmptyStateVisible();

        // Either no orders match or empty state is shown
        (hasOrders || hasEmptyState).Should().BeTrue("Search should filter orders or show empty state");
    }

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

        // Act - Filter by draft status
        await ordersPage.FilterByStatus("Kladde");

        // Assert - Page should still function (filter applied)
        // We can't assert exact results without knowing test data
        (await ordersPage.IsTitleVisible()).Should().BeTrue("Page should remain functional after filtering");
    }

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

        // Act
        await ordersPage.SearchOrders("test search");
        await ordersPage.ClearSearch();

        // Assert - Search should be cleared
        var searchInput = Page.GetByPlaceholder("Soeg ordre...");
        var value = await searchInput.InputValueAsync();
        value.Should().BeEmpty("Search input should be cleared");
    }

    [Fact]
    public async Task OrdersPage_NavigationViaSidebar()
    {
        // Arrange - Start at dashboard
        await Page.GotoAsync(Config.FrontendUrl);
        await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);

        // Act - Navigate via sidebar
        var sidebar = new SidebarPage(Page);
        await sidebar.NavigateToOrders();

        // Assert
        var ordersPage = new OrdersPage(Page);
        await ordersPage.WaitForPageToLoad();
        (await ordersPage.IsTitleVisible()).Should().BeTrue("Should navigate to orders page via sidebar");
    }
}
