using Microsoft.Playwright;

namespace Books.E2E.Tests.Pages;

/// <summary>
/// Page object for the Order detail drawer.
/// </summary>
public class OrderDrawerPage : BasePage
{
    private readonly ILocator _drawer;
    private readonly ILocator _drawerTitle;
    private readonly ILocator _closeButton;

    // Action buttons
    private readonly ILocator _addLineButton;
    private readonly ILocator _confirmButton;
    private readonly ILocator _createInvoiceButton;
    private readonly ILocator _cancelButton;

    // Content sections
    private readonly ILocator _customerDescription;
    private readonly ILocator _linesList;
    private readonly ILocator _noLinesAlert;

    // Totals
    private readonly ILocator _totalAmount;

    public OrderDrawerPage(IPage page) : base(page)
    {
        _drawer = page.Locator(".ant-drawer");
        _drawerTitle = _drawer.Locator(".ant-drawer-title");
        _closeButton = _drawer.Locator(".ant-drawer-close");

        _addLineButton = _drawer.GetByRole(AriaRole.Button, new() { Name = "Tilfoej linje" });
        _confirmButton = _drawer.GetByRole(AriaRole.Button, new() { Name = "Bekraeft" });
        _createInvoiceButton = _drawer.GetByRole(AriaRole.Button, new() { Name = "Opret faktura" });
        _cancelButton = _drawer.GetByRole(AriaRole.Button, new() { Name = "Annuller" });

        _customerDescription = _drawer.Locator(".ant-descriptions-item:has-text('Kunde')");
        _linesList = _drawer.Locator(".ant-list");
        _noLinesAlert = _drawer.Locator(".ant-alert:has-text('Ingen linjer')");

        _totalAmount = _drawer.Locator("text=Total:").Locator("..");
    }

    /// <summary>
    /// Waits for the drawer to be visible.
    /// </summary>
    public async Task WaitForDrawerToOpen()
    {
        await _drawer.WaitForAsync(new() { State = WaitForSelectorState.Visible, Timeout = 5000 });
        await WaitForNetworkIdleAsync();
    }

    /// <summary>
    /// Closes the drawer.
    /// </summary>
    public async Task CloseDrawer()
    {
        await _closeButton.ClickAsync();
        await _drawer.WaitForAsync(new() { State = WaitForSelectorState.Hidden, Timeout = 5000 });
    }

    /// <summary>
    /// Gets the order number from the drawer title.
    /// </summary>
    public async Task<string?> GetOrderNumber()
    {
        var title = await _drawerTitle.TextContentAsync();
        // Extract order number from "Ordre ORD-XXXXX"
        return title?.Replace("Ordre ", "").Trim();
    }

    /// <summary>
    /// Gets the order status tag text.
    /// </summary>
    public async Task<string?> GetOrderStatus()
    {
        var statusTag = _drawerTitle.Locator(".ant-tag");
        return await statusTag.TextContentAsync();
    }

    /// <summary>
    /// Gets the customer name from the description.
    /// </summary>
    public async Task<string?> GetCustomerName()
    {
        var customerValue = _drawer.Locator(".ant-descriptions-item:has(.ant-descriptions-item-label:text('Kunde')) .ant-descriptions-item-content");
        return await customerValue.TextContentAsync();
    }

    /// <summary>
    /// Checks if the "Add Line" button is visible.
    /// </summary>
    public async Task<bool> IsAddLineButtonVisible()
    {
        return await _addLineButton.IsVisibleAsync();
    }

    /// <summary>
    /// Checks if the "Confirm" button is visible.
    /// </summary>
    public async Task<bool> IsConfirmButtonVisible()
    {
        return await _confirmButton.IsVisibleAsync();
    }

    /// <summary>
    /// Checks if the "Create Invoice" button is visible.
    /// </summary>
    public async Task<bool> IsCreateInvoiceButtonVisible()
    {
        return await _createInvoiceButton.IsVisibleAsync();
    }

    /// <summary>
    /// Checks if the "Cancel" button is visible.
    /// </summary>
    public async Task<bool> IsCancelButtonVisible()
    {
        return await _cancelButton.IsVisibleAsync();
    }

    /// <summary>
    /// Clicks the "Add Line" button to open the add line modal.
    /// </summary>
    public async Task ClickAddLine()
    {
        await _addLineButton.ClickAsync();
        await Page.Locator(".ant-modal:has-text('Tilfoej linje')").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Clicks the "Confirm" button to confirm the order.
    /// </summary>
    public async Task ClickConfirm()
    {
        await _confirmButton.ClickAsync();
        await WaitForNetworkIdleAsync();
    }

    /// <summary>
    /// Clicks the "Create Invoice" button.
    /// </summary>
    public async Task ClickCreateInvoice()
    {
        await _createInvoiceButton.ClickAsync();
        await Page.Locator(".ant-modal:has-text('Opret faktura')").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Clicks the "Cancel" button to open the cancel modal.
    /// </summary>
    public async Task ClickCancel()
    {
        await _cancelButton.ClickAsync();
        await Page.Locator(".ant-modal:has-text('Annuller ordre')").WaitForAsync(new() { Timeout = 5000 });
    }

    /// <summary>
    /// Gets the number of order lines.
    /// </summary>
    public async Task<int> GetLineCount()
    {
        var lines = _linesList.Locator(".ant-list-item");
        return await lines.CountAsync();
    }

    /// <summary>
    /// Checks if the "no lines" alert is visible.
    /// </summary>
    public async Task<bool> IsNoLinesAlertVisible()
    {
        return await _noLinesAlert.IsVisibleAsync();
    }

    /// <summary>
    /// Gets all line descriptions.
    /// </summary>
    public async Task<IReadOnlyList<string>> GetLineDescriptions()
    {
        var titles = _linesList.Locator(".ant-list-item-meta-title");
        return await titles.AllTextContentsAsync();
    }

    /// <summary>
    /// Checks if a line is marked as invoiced.
    /// </summary>
    public async Task<bool> IsLineInvoiced(string description)
    {
        var line = _linesList.Locator($".ant-list-item:has-text('{description}')");
        var invoicedTag = line.Locator(".ant-tag:has-text('Faktureret')");
        return await invoicedTag.IsVisibleAsync();
    }

    /// <summary>
    /// Gets the total amount from the drawer.
    /// </summary>
    public async Task<string?> GetTotalAmount()
    {
        return await _totalAmount.TextContentAsync();
    }
}
