"""
Tests de selectores del compositor de mensajes WhatsApp Web 2026
"""

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


CHAT_INPUT_BOX_SELECTORS = [
    "//div[contains(@class, 'lexical-rich-text-input')]//div[@contenteditable='true']",
    "//div[@contenteditable='true' and @role='textbox']",
    "//div[@aria-placeholder='Escribe un mensaje']",
    "//div[@aria-placeholder='Type a message']",
    "//div[@title='Type a message']",
]

ATTACH_BUTTON_SELECTORS = [
    "//button[@aria-label='Adjuntar']",
    "//span[@data-icon='plus-rounded']",
    "css=span[data-icon='plus-rounded']",
]

EMOJI_BUTTON_SELECTORS = [
    "//button[@aria-label='Emojis, GIF, Stickers']",
    "//span[@data-icon='sticker-smiley']",
]

VOICE_MESSAGE_BUTTON_SELECTORS = [
    "//button[@aria-label='Mensaje de voz']",
    "//button[@aria-label='Voice message']",
    "//span[@data-icon='mic-outlined']",
]


class TestChatInputBoxLocators:
    """Testea TODOS los selectores de CHAT_INPUT_BOX"""

    @pytest.mark.parametrize("selector", CHAT_INPUT_BOX_SELECTORS)
    @pytest.mark.asyncio
    async def test_chat_input_box_selector_exists(self, page: Page, selector: str):
        """Cada selector de CHAT_INPUT_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_chat_input_box_is_editable(self, page: Page):
        """El campo de mensaje debe ser editable"""
        chat_input = await page.query_selector(CHAT_INPUT_BOX_SELECTORS[0])
        if chat_input:
            await chat_input.click()
            await chat_input.type("test", delay=30)
            text = await chat_input.inner_text()
            assert "test" in text.lower(), "El input no acepta texto"


class TestAttachButtonLocators:
    """Testea TODOS los selectores de ATTACH_BUTTON"""

    @pytest.mark.parametrize("selector", ATTACH_BUTTON_SELECTORS)
    @pytest.mark.asyncio
    async def test_attach_button_selector_exists(self, page: Page, selector: str):
        """Cada selector de ATTACH_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_attach_button_is_clickable(self, page: Page):
        """El botón de adjuntar debe ser clickeable"""
        attach_btn = await page.query_selector(ATTACH_BUTTON_SELECTORS[0])
        if attach_btn:
            is_clickable = await attach_btn.is_visible()
            assert is_clickable, "El botón de adjuntar no es clickeable"


class TestEmojiButtonLocators:
    """Testea TODOS los selectores de EMOJI_BUTTON"""

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


class TestVoiceMessageButtonLocators:
    """Testea TODOS los selectores de VOICE_MESSAGE_BUTTON"""

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


class TestSendButtonLocator:
    """Tests para el botón de enviar"""

    @pytest.mark.asyncio
    async def test_send_button_exists(self, page: Page):
        """El botón de enviar existe"""
        send_btn = await page.query_selector(
            "css=span[data-icon='wds-ic-send-filled'], css=span[data-icon='send']"
        )
        assert send_btn is not None, "No se encontró el botón de enviar"

    @pytest.mark.asyncio
    async def test_send_button_is_disabled_when_empty(self, page: Page):
        """El botón de enviar está deshabilitado cuando no hay mensaje"""
        chat_input = await page.query_selector(CHAT_INPUT_BOX_SELECTORS[0])

        if chat_input:
            await chat_input.click()
            await chat_input.fill("")

            send_btn = await page.query_selector(
                "css=span[data-icon='wds-ic-send-filled']"
            )

            if send_btn:
                is_disabled = await send_btn.get_attribute("aria-disabled")
                assert is_disabled == "true", "El botón debería estar deshabilitado"


class TestFileInputLocator:
    """Tests para el input de archivos"""

    @pytest.mark.asyncio
    async def test_file_input_exists(self, page: Page):
        """El input de archivos existe"""
        file_input = await page.query_selector("css=input[type='file']")
        assert file_input is not None, "No se encontró input[type='file']"


class TestComposerFunctionality:
    """Tests de funcionalidad del compositor"""

    @pytest.mark.asyncio
    async def test_type_message_in_composer(self, page: Page):
        """Se puede escribir un mensaje en el compositor"""
        chat_input = await page.query_selector(CHAT_INPUT_BOX_SELECTORS[0])

        if chat_input:
            await chat_input.click()
            test_message = f"Test message {uuid.uuid4().hex[:8]}"
            await chat_input.fill(test_message)

            text = await chat_input.inner_text()
            assert test_message in text, "El mensaje no se escribió correctamente"

    @pytest.mark.asyncio
    async def test_send_message_press_enter(self, page: Page):
        """Presionar Enter envía el mensaje"""
        chat_input = await page.query_selector(CHAT_INPUT_BOX_SELECTORS[0])

        if chat_input:
            await chat_input.click()
            await chat_input.fill("")
            await chat_input.type("test", delay=30)
            await page.keyboard.press("Enter")

            await page.wait_for_timeout(2000)

            messages = await page.query_selector_all(".//div[@data-pre-plain-text]")

            assert len(messages) > 0, "No se envió el mensaje"

    @pytest.mark.asyncio
    async def test_message_appears_in_chat(self, page: Page):
        """El mensaje aparece en el chat después de enviarlo"""
        chat_input = await page.query_selector(CHAT_INPUT_BOX_SELECTORS[0])

        if chat_input:
            test_msg = f"Auto test {uuid.uuid4().hex[:6]}"
            await chat_input.fill(test_msg)
            await page.keyboard.press("Enter")

            await page.wait_for_timeout(2000)

            last_message = await page.query_selector_all(
                ".//span[@data-testid='selectable-text']"
            )

            if last_message:
                text = await last_message[-1].inner_text()
                assert test_msg in text, "El mensaje no apareció en el chat"

            await page.wait_for_timeout(500)
