using Microsoft.Playwright;

namespace Books.E2E.Tests.Pages;

/// <summary>
/// Page object for the Orders page (Ordrer).
/// </summary>
public class OrdersPage : BasePage
{
    // Locators
    private readonly ILocator _pageTitle;
    private readonly ILocator _newOrderButton;
    private readonly ILocator _searchInput;
    private readonly ILocator _statusFilter;
    private readonly ILocator _ordersTable;
    private readonly ILocator _loadingSpinner;
    private readonly ILocator _emptyState;

    // Statistics locators
    private readonly ILocator _totalOrdersStat;
    private readonly ILocator _draftsStat;
    private readonly ILocator _confirmedStat;
    private readonly ILocator _totalValueStat;

    public OrdersPage(IPage page) : base(page)
    {
        _pageTitle = page.Locator("h4:has-text('Ordrer')");
        _newOrderButton = page.GetByRole(AriaRole.Button, new() { Name = "Ny ordre" });
        _searchInput = page.GetByPlaceholder("Soeg ordre...");
        _statusFilter = page.Locator(".ant-select").First;
        _ordersTable = page.Locator(".ant-table");
        _loadingSpinner = page.Locator(".ant-spin");
        _emptyState = page.Locator("[class*='empty-state'], .ant-empty");

        // Stats cards - by their title text
        _totalOrdersStat = page.Locator(".ant-statistic:has-text('Ordrer i alt')");
        _draftsStat = page.Locator(".ant-statistic:has-text('Kladder')");
        _confirmedStat = page.Locator(".ant-statistic:has-text('Bekraeftede')");
        _totalValueStat = page.Locator(".ant-statistic:has-text('Samlet vaerdi')");
    }

    /// <summary>
    /// Waits for the Orders page to load completely.
    /// </summary>
    public async Task WaitForPageToLoad()
    {
        await _pageTitle.WaitForAsync(new() { Timeout = 10000 });
        await WaitForNetworkIdleAsync();
        // Wait for loading spinner to disappear
        await _loadingSpinner.WaitForAsync(new() { State = WaitForSelectorState.Hidden, Timeout = 10000 });
    }

    /// <summary>
    /// Checks if the page title is visible.
    /// </summary>
    public async Task<bool> IsTitleVisible()
    {
        return await _pageTitle.IsVisibleAsync();
    }

    /// <summary>
    /// Clicks the "Ny ordre" button to create a new order.
    /// </summary>
    public async Task ClickNewOrder()
    {
        await _newOrderButton.ClickAsync();
        // Wait for modal to appear
        await Page.Locator(".ant-modal").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Searches for orders by text.
    /// </summary>
    public async Task SearchOrders(string searchText)
    {
        await _searchInput.ClearAsync();
        await _searchInput.FillAsync(searchText);
        // Wait for filtering to complete
        await Task.Delay(300);
    }

    /// <summary>
    /// Clears the search input.
    /// </summary>
    public async Task ClearSearch()
    {
        var clearButton = _searchInput.Locator("..").Locator(".ant-input-clear-icon");
        if (await clearButton.IsVisibleAsync())
        {
            await clearButton.ClickAsync();
        }
        else
        {
            await _searchInput.ClearAsync();
        }
    }

    /// <summary>
    /// Filters orders by status.
    /// </summary>
    public async Task FilterByStatus(string status)
    {
        await _statusFilter.ClickAsync();
        await Page.Locator($".ant-select-item-option:has-text('{status}')").ClickAsync();
        await Task.Delay(300);
    }

    /// <summary>
    /// Gets the number of orders displayed in the table.
    /// </summary>
    public async Task<int> GetOrderCount()
    {
        var rows = _ordersTable.Locator("tbody tr.ant-table-row");
        return await rows.CountAsync();
    }

    /// <summary>
    /// Checks if the empty state is visible.
    /// </summary>
    public async Task<bool> IsEmptyStateVisible()
    {
        return await _emptyState.IsVisibleAsync();
    }

    /// <summary>
    /// Checks if the orders table is visible.
    /// </summary>
    public async Task<bool> IsTableVisible()
    {
        return await _ordersTable.IsVisibleAsync();
    }

    /// <summary>
    /// Clicks the view button for an order by its order number.
    /// </summary>
    public async Task ViewOrder(string orderNumber)
    {
        var row = _ordersTable.Locator($"tr:has-text('{orderNumber}')");
        var viewButton = row.Locator("button").First;
        await viewButton.ClickAsync();
        // Wait for drawer to open
        await Page.Locator(".ant-drawer").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Gets all order numbers from the table.
    /// </summary>
    public async Task<IReadOnlyList<string>> GetOrderNumbers()
    {
        var cells = _ordersTable.Locator("tbody tr.ant-table-row td:nth-child(1) code");
        return await cells.AllTextContentsAsync();
    }

    /// <summary>
    /// Gets the total orders statistic value.
    /// </summary>
    public async Task<string?> GetTotalOrdersStat()
    {
        var value = _totalOrdersStat.Locator(".ant-statistic-content-value");
        return await value.TextContentAsync();
    }

    /// <summary>
    /// Gets the drafts statistic value.
    /// </summary>
    public async Task<string?> GetDraftsStat()
    {
        var value = _draftsStat.Locator(".ant-statistic-content-value");
        return await value.TextContentAsync();
    }

    /// <summary>
    /// Gets the confirmed orders statistic value.
    /// </summary>
    public async Task<string?> GetConfirmedStat()
    {
        var value = _confirmedStat.Locator(".ant-statistic-content-value");
        return await value.TextContentAsync();
    }

    /// <summary>
    /// Gets the total value statistic.
    /// </summary>
    public async Task<string?> GetTotalValueStat()
    {
        var value = _totalValueStat.Locator(".ant-statistic-content-value");
        return await value.TextContentAsync();
    }
}
