"""
Tests de selectores de búsqueda WhatsApp Web 2026
"""

import pytest
from playwright.async_api import Page
from whatsplay.constants import locator as loc


SEARCH_BUTTON_SELECTORS = [
    "//span[.//title[text()='ic-search']]",
    "//span[@aria-hidden='true']//svg//title[text()='ic-search']/parent::svg/parent::span",
    "//input[@role='textbox' and contains(@aria-label, 'Buscar')]",
    "//input[@placeholder='Buscar un chat o iniciar uno nuevo']",
    "css=button[aria-label='Search'], button[aria-label='Buscar']",
    "//button[@aria-label='Search' or @aria-label='Buscar']",
    "//div[@aria-label='Search input textbox']",
    "//span[@data-icon='search']/parent::button",
]

SEARCH_TEXT_BOX_SELECTORS = [
    "//input[@role='textbox' and contains(@aria-label, 'Buscar')]",
    "//input[@placeholder='Buscar un chat o iniciar uno nuevo']",
    "//input[@aria-label='Buscar un chat o iniciar uno nuevo']",
    "//div[@contenteditable='true' and @role='textbox']",
    "//div[@role='textbox'][@contenteditable='true']",
    "//div[contains(@class, '_13NKt')]",
]


class TestSearchButtonLocators:
    """Testea TODOS los selectores de SEARCH_BUTTON"""

    @pytest.mark.parametrize("selector", SEARCH_BUTTON_SELECTORS)
    @pytest.mark.asyncio
    async def test_search_button_selector_exists(self, page: Page, selector: str):
        """Cada selector de SEARCH_BUTTON debe encontrar un elemento"""
        element = await page.query_selector(selector)
        assert element is not None, f"Selector no encontró elemento: {selector}"

    @pytest.mark.asyncio
    async def test_search_button_is_visible(self, page: Page):
        """El botón de búsqueda debe ser visible"""
        element = await page.query_selector(SEARCH_BUTTON_SELECTORS[0])
        if element:
            is_visible = await element.is_visible()
            assert is_visible, "El botón de búsqueda no es visible"


class TestSearchTextBoxLocators:
    """Testea TODOS los selectores de SEARCH_TEXT_BOX"""

    @pytest.mark.parametrize("selector", SEARCH_TEXT_BOX_SELECTORS)
    @pytest.mark.asyncio
    async def test_search_textbox_selector_exists(self, page: Page, selector: str):
        """Cada selector de SEARCH_TEXT_BOX debe encontrar un elemento"""
        element = await page.query_selector(selector)
        assert element is not None, f"Selector no encontró elemento: {selector}"

    @pytest.mark.asyncio
    async def test_search_input_is_focusable(self, page: Page):
        """El input de búsqueda debe poder recibir foco"""
        search_input = await page.query_selector(
            "//input[@role='textbox' and contains(@aria-label, 'Buscar')]"
        )
        if search_input:
            await search_input.click()
            is_focused = await page.evaluate(
                "el => document.activeElement === el",
                await search_input.evaluate_handle("el => el"),
            )
            assert is_focused, "El input de búsqueda no recibió foco"


class TestSearchFunctionality:
    """Tests de funcionalidad de búsqueda"""

    @pytest.mark.asyncio
    async def test_keyboard_shortcut_opens_search(self, page: Page, clean_search):
        """Presionar Ctrl+Alt+/ abre el campo de búsqueda"""
        await page.keyboard.press("Control+Alt+/")
        await page.wait_for_timeout(500)

        search_input = await page.query_selector(
            "//input[@role='textbox' and contains(@aria-label, 'Buscar')]"
        )
        assert search_input is not None, "Ctrl+Alt+/ no abrió la búsqueda"

    @pytest.mark.asyncio
    async def test_search_returns_chat_results(self, page: Page, clean_search):
        """Buscar un contacto devuelve resultados de chats"""
        search_input = await page.query_selector(
            "//input[@role='textbox' and contains(@aria-label, 'Buscar')]"
        )

        await search_input.fill("")
        await search_input.type("Mama", delay=50)
        await page.wait_for_timeout(1500)

        results_container = await page.query_selector(
            "//div[@aria-label='Resultados de la búsqueda.'] | //div[@role='grid']"
        )
        assert results_container is not None, "No se encontró contenedor de resultados"

    @pytest.mark.asyncio
    async def test_search_result_item_structure(self, page: Page, clean_search):
        """Los resultados de búsqueda tienen estructura válida"""
        search_input = await page.query_selector(
            "//input[@role='textbox' and contains(@aria-label, 'Buscar')]"
        )

        await search_input.type("a", delay=50)
        await page.wait_for_timeout(1500)

        rows = await page.query_selector_all("//div[@role='row']")
        assert len(rows) > 0, "No se encontraron filas de resultados"


class TestSearchResultLocators:
    """Tests para selectores de resultados de búsqueda"""

    @pytest.mark.asyncio
    async def test_search_result_container_exists(self, page: Page, clean_search):
        """El contenedor de resultados existe"""
        search_input = await page.query_selector(
            "//input[@role='textbox' and contains(@aria-label, 'Buscar')]"
        )
        await search_input.type("test", delay=50)
        await page.wait_for_timeout(1000)

        container = await page.query_selector(
            "//div[@aria-label='Resultados de la búsqueda.'] | "
            "//div[@role='grid' and ancestor::div[@id='pane-side']]"
        )
        assert container is not None, "No se encontró contenedor de resultados"

    @pytest.mark.asyncio
    async def test_search_item_has_components(self, page: Page, clean_search):
        """Los items de resultado tienen los componentes necesarios"""
        search_input = await page.query_selector(
            "//input[@role='textbox' and contains(@aria-label, 'Buscar')]"
        )
        await search_input.type("a", delay=50)
        await page.wait_for_timeout(1500)

        items = await page.query_selector_all(loc.SEARCH_ITEM)

        if len(items) > 0:
            first_item = items[0]
            components = await first_item.query_selector_all(".//div[@role='gridcell']")
            assert len(components) >= 2, "El ítem no tiene suficientes componentes"
