"""
Tres reglas que valen para toda la aplicación, no para una pantalla.

Las tres nacieron del mismo modal: uno se abría con un globo de ayuda tapando su
propio contenido, otro cortaba una dirección contra el borde, y el chip que las
muestra dejaba que cada llamador decidiera si recortaba o no. Ninguna es un
defecto de la vista donde se vio: son de las piezas que las trece vistas
comparten, y por eso se defienden acá y una sola vez.
"""

import re

import pytest

from tests.frontend.harness import needs_frontend, render, resolve

CODE_CHIP = '@/components/CodeChip'

pytestmark = needs_frontend

LONG_URL = 'https://www.ejemplo.test/una-direccion-larguisima-que-no-entra-en-ningun-lado'

REQUESTS = {
    'plain': render(CODE_CHIP, 'CodeChip', value=LONG_URL),
    'with_copy': render(CODE_CHIP, 'CodeChip', value=LONG_URL, copy=True),
    # Un llamador que intenta soltarle el freno. La pieza tiene que ganar.
    'widened': render(CODE_CHIP, 'CodeChip', value=LONG_URL, className='max-w-none text-wrap'),
}


@pytest.fixture(scope='module')
def screen() -> dict:
    return resolve(REQUESTS)


class TestACodeChipAlwaysFitsWhereItIsPut:
    """
    El tope de ancho del chip no es negociable por quien lo usa.

    Una dirección larga estira el contenedor que la tenga —una celda, una
    tarjeta, un panel— y empuja fuera de la vista lo que esté al lado. Que cada
    llamador decidiera si recortar convertía una regla de la aplicación en un
    detalle que se olvida, y ya se había olvidado.
    """

    def test_it_carries_its_own_width_cap_and_truncation(self, screen):
        assert 'max-w-100' in screen['plain']
        assert 'truncate' in screen['plain']

    def test_a_caller_cannot_take_the_cap_off(self, screen):
        """
        El caso real: alguien pasó `max-w-none` para que una lista se viera
        entera y la dirección se comió el ancho del panel.
        """
        assert 'max-w-none' not in screen['widened'], 'Un llamador pudo sacarle el tope.'
        assert 'max-w-100' in screen['widened']
        assert 'truncate' in screen['widened']

    def test_the_whole_value_stays_reachable(self, screen):
        """
        Recortar la vista no puede recortar el dato: sigue entero en `title`, y
        con `copy` se lo lleva completo quien lo necesita.
        """
        assert f'title="{LONG_URL}"' in screen['plain']
        assert LONG_URL in screen['with_copy']


class TestADialogDoesNotGrabFocusOnOpen:
    """
    Radix enfoca el primer control al abrir, y eso no siempre es lo que hace
    falta.

    En un formulario sirve: el primer control es el campo que hay que llenar. En
    un diálogo que se abre para leer algo, deja un anillo de foco sobre lo
    primero que haya y —si ese algo dispara un globo— **abre el globo solo**,
    tapando el contenido antes de que nadie haya tocado nada. Es exactamente lo
    que pasaba al abrir el cupo del lote.

    La pieza vive en un portal, así que de un dibujo estático no sale nada: lo
    que se verifica es que la regla esté escrita en la primitiva y no en cada
    pantalla, que es lo que la hace global.
    """

    def source(self) -> str:
        from tests.frontend.harness import HERE

        path = HERE.parent.parent / 'frontend' / 'components' / 'ui' / 'dialog.tsx'
        return path.read_text(encoding='utf-8')

    def test_the_primitive_stops_the_automatic_focus(self):
        body = self.source()

        assert 'onOpenAutoFocus' in body, 'La primitiva dejó de frenar el foco automático.'
        assert 'preventDefault' in body

    def test_the_panel_takes_the_focus_instead_of_nobody(self):
        """
        Frenar el autofoco sin poner el foco en ningún lado deja el diálogo fuera
        del teclado: el Tab seguiría recorriendo la página de atrás y el Esc no
        cerraría. El foco va al panel, que para eso lleva `tabIndex`.
        """
        body = self.source()

        assert 'tabIndex={-1}' in body
        assert re.search(r'panel\.focus\(\)', body), 'Nadie recibe el foco al abrir.'

    def test_a_dialog_that_needs_a_field_focused_can_still_ask_for_it(self):
        """
        La regla es un valor por omisión, no una prohibición: `onOpenAutoFocus`
        se declara antes de `{...props}`, así que un formulario que quiera
        enfocar su primer campo lo pide y gana.
        """
        body = self.source()
        stop = body.index('onOpenAutoFocus')
        spread = body.index('{...props}', stop)

        assert stop < spread, 'El valor por omisión quedó después de las props y ya no se puede pisar.'
