using Microsoft.Playwright;

namespace Books.E2E.Tests.Pages;

/// <summary>
/// Page object for the Invoices page (Fakturaer).
/// </summary>
public class InvoicesPage : BasePage
{
    private readonly ILocator _pageTitle;
    private readonly ILocator _newInvoiceButton;
    private readonly ILocator _searchInput;
    private readonly ILocator _statusFilter;
    private readonly ILocator _invoicesTable;
    private readonly ILocator _loadingSpinner;
    private readonly ILocator _emptyState;

    // Statistics
    private readonly ILocator _totalInvoicesStat;
    private readonly ILocator _draftsStat;
    private readonly ILocator _sentStat;
    private readonly ILocator _paidStat;

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

        _totalInvoicesStat = page.Locator(".ant-statistic:has-text('Fakturaer i alt')");
        _draftsStat = page.Locator(".ant-statistic:has-text('Kladder')");
        _sentStat = page.Locator(".ant-statistic:has-text('Sendt')");
        _paidStat = page.Locator(".ant-statistic:has-text('Betalt')");
    }

    /// <summary>
    /// Waits for the Invoices page to load completely.
    /// </summary>
    public async Task WaitForPageToLoad()
    {
        await _pageTitle.WaitForAsync(new() { Timeout = 10000 });
        await WaitForNetworkIdleAsync();
        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 faktura" button to create a new invoice.
    /// </summary>
    public async Task ClickNewInvoice()
    {
        await _newInvoiceButton.ClickAsync();
        await Page.Locator(".ant-modal, .ant-drawer").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Searches for invoices by text.
    /// </summary>
    public async Task SearchInvoices(string searchText)
    {
        await _searchInput.ClearAsync();
        await _searchInput.FillAsync(searchText);
        await Task.Delay(300);
    }

    /// <summary>
    /// Filters invoices 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 invoices displayed in the table.
    /// </summary>
    public async Task<int> GetInvoiceCount()
    {
        var rows = _invoicesTable.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 invoices table is visible.
    /// </summary>
    public async Task<bool> IsTableVisible()
    {
        return await _invoicesTable.IsVisibleAsync();
    }

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

    /// <summary>
    /// Views an invoice by its invoice number.
    /// </summary>
    public async Task ViewInvoice(string invoiceNumber)
    {
        var row = _invoicesTable.Locator($"tr:has-text('{invoiceNumber}')");
        var viewButton = row.Locator("button").First;
        await viewButton.ClickAsync();
        await Page.Locator(".ant-drawer").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Gets the total invoices statistic value.
    /// </summary>
    public async Task<string?> GetTotalInvoicesStat()
    {
        var value = _totalInvoicesStat.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();
    }
}
