using Microsoft.Playwright;

namespace Books.E2E.Tests.Pages.Modals;

/// <summary>
/// Page object for the Create Order modal.
/// </summary>
public class CreateOrderModalPage : BasePage
{
    private readonly ILocator _modal;
    private readonly ILocator _customerSelect;
    private readonly ILocator _orderDatePicker;
    private readonly ILocator _expectedDeliveryDatePicker;
    private readonly ILocator _referenceInput;
    private readonly ILocator _notesInput;
    private readonly ILocator _submitButton;
    private readonly ILocator _cancelButton;

    public CreateOrderModalPage(IPage page) : base(page)
    {
        _modal = page.Locator(".ant-modal:has-text('Opret ordre')");
        _customerSelect = _modal.Locator(".ant-form-item:has-text('Kunde') .ant-select");
        _orderDatePicker = _modal.Locator(".ant-form-item:has-text('Ordredato') .ant-picker");
        _expectedDeliveryDatePicker = _modal.Locator(".ant-form-item:has-text('Forventet levering') .ant-picker");
        _referenceInput = _modal.Locator("input#reference, input[id*='reference']").First;
        _notesInput = _modal.Locator("textarea");
        _submitButton = _modal.GetByRole(AriaRole.Button, new() { Name = "Opret" });
        _cancelButton = _modal.GetByRole(AriaRole.Button, new() { Name = "Annuller" });
    }

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

    /// <summary>
    /// Selects a customer by searching for their name or number.
    /// </summary>
    public async Task SelectCustomer(string customerSearchText)
    {
        await _customerSelect.ClickAsync();

        // Wait for dropdown to appear
        var dropdown = Page.Locator(".ant-select-dropdown:visible");
        await dropdown.WaitForAsync(new() { Timeout = 5000 });

        // Type to search
        await Page.Keyboard.TypeAsync(customerSearchText);
        await Task.Delay(300); // Wait for search filtering

        // Click the first matching option
        var option = dropdown.Locator($".ant-select-item-option").First;
        await option.ClickAsync();
    }

    /// <summary>
    /// Sets the order date.
    /// </summary>
    public async Task SetOrderDate(DateTime date)
    {
        await _orderDatePicker.ClickAsync();
        // Clear and type the date
        await Page.Keyboard.PressAsync("Control+a");
        await Page.Keyboard.TypeAsync(date.ToString("dd-MM-yyyy"));
        await Page.Keyboard.PressAsync("Enter");
    }

    /// <summary>
    /// Sets the expected delivery date.
    /// </summary>
    public async Task SetExpectedDeliveryDate(DateTime date)
    {
        await _expectedDeliveryDatePicker.ClickAsync();
        await Page.Keyboard.PressAsync("Control+a");
        await Page.Keyboard.TypeAsync(date.ToString("dd-MM-yyyy"));
        await Page.Keyboard.PressAsync("Enter");
    }

    /// <summary>
    /// Enters a reference.
    /// </summary>
    public async Task EnterReference(string reference)
    {
        await _referenceInput.ClearAsync();
        await _referenceInput.FillAsync(reference);
    }

    /// <summary>
    /// Enters notes.
    /// </summary>
    public async Task EnterNotes(string notes)
    {
        await _notesInput.ClearAsync();
        await _notesInput.FillAsync(notes);
    }

    /// <summary>
    /// Submits the form to create the order.
    /// </summary>
    public async Task Submit()
    {
        await _submitButton.ClickAsync();
        // Wait for modal to close or show error
        await Task.WhenAny(
            _modal.WaitForAsync(new() { State = WaitForSelectorState.Hidden, Timeout = 10000 }),
            Page.Locator(".ant-form-item-explain-error").WaitForAsync(new() { Timeout = 10000 })
        );
    }

    /// <summary>
    /// Cancels and closes the modal.
    /// </summary>
    public async Task Cancel()
    {
        await _cancelButton.ClickAsync();
        await _modal.WaitForAsync(new() { State = WaitForSelectorState.Hidden, Timeout = 5000 });
    }

    /// <summary>
    /// Checks if there are validation errors.
    /// </summary>
    public async Task<bool> HasValidationErrors()
    {
        return await _modal.Locator(".ant-form-item-explain-error").IsVisibleAsync();
    }

    /// <summary>
    /// Gets all validation error messages.
    /// </summary>
    public async Task<IReadOnlyList<string>> GetValidationErrors()
    {
        return await _modal.Locator(".ant-form-item-explain-error").AllTextContentsAsync();
    }

    /// <summary>
    /// Checks if the modal is visible.
    /// </summary>
    public async Task<bool> IsVisible()
    {
        return await _modal.IsVisibleAsync();
    }
}
