"""Evidence-based pagination tests; no URL guessing."""

from __future__ import annotations

from bs4 import BeautifulSoup

from app.services.pagination import PaginationEngine


class PatternAdapter:
    next_page_selectors = ("a.more",)

    def __init__(self, next_url: str | None = None, *, explode: bool = False) -> None:
        self._next_url = next_url
        self._explode = explode

    def get_next_page_url(self, soup: BeautifulSoup, current_url: str) -> str | None:
        if self._explode:
            raise RuntimeError("broken adapter")
        return self._next_url


def detect(html: str, url: str = "https://example.com/list", adapter=None):
    return PaginationEngine().detect(BeautifulSoup(html, "html.parser"), url, adapter)


def test_rel_next_link_element() -> None:
    decision = detect(
        '<html><head><link rel="next" href="/list?page=2"></head></html>'
    )
    assert decision.url == "https://example.com/list?page=2"
    assert decision.strategy == "rel_next"


def test_rel_next_anchor_element() -> None:
    decision = detect('<a rel="next" href="page2">Next</a>')
    assert decision.url == "https://example.com/page2"
    assert decision.strategy == "rel_next"


def test_rel_next_self_is_ignored() -> None:
    decision = detect('<a rel="next" href="/list#section">Next</a>')
    assert decision.url is None
    assert decision.strategy == "none"


def test_disabled_rel_next_is_ignored() -> None:
    decision = detect('<a rel="next" class="next disabled" href="/list?page=2">Next</a>')
    assert decision.url is None


def test_javascript_next_is_ignored() -> None:
    decision = detect('<a rel="next" href="javascript:void(0)">Next</a>')
    assert decision.url is None


def test_adapter_specific_next_selector() -> None:
    decision = detect('<a class="more" href="/page/2">More</a>', adapter=PatternAdapter())
    assert decision.url == "https://example.com/page/2"
    assert decision.strategy == "adapter_next"


def test_adapter_url_pattern() -> None:
    decision = detect("<html></html>", adapter=PatternAdapter("/page/2"))
    assert decision.url == "https://example.com/page/2"
    assert decision.strategy == "adapter_pattern"


def test_broken_adapter_pattern_is_ignored() -> None:
    decision = detect("<html></html>", adapter=PatternAdapter(explode=True))
    assert decision.url is None


def test_generic_next_ui_inside_pagination_container() -> None:
    html = '<nav aria-label="pagination"><a href="/page/2">Next</a></nav>'
    decision = detect(html)
    assert decision.url == "https://example.com/page/2"
    assert decision.strategy == "next_ui"


def test_generic_next_ui_persian_label() -> None:
    html = '<div class="pagination"><a href="/page/2">صفحه بعد</a></div>'
    decision = detect(html)
    assert decision.url == "https://example.com/page/2"
    assert decision.strategy == "next_ui"


def test_aria_label_next_outside_container() -> None:
    html = '<a aria-label="Next" href="/page/2">→</a>'
    decision = detect(html)
    assert decision.url == "https://example.com/page/2"
    assert decision.strategy == "next_aria"


def test_numbered_pagination_with_active_page() -> None:
    html = """
    <nav class="pagination">
      <a href="/page/1">1</a>
      <span class="active">2</span>
      <a href="/page/3">3</a>
      <a href="/page/4">4</a>
    </nav>
    """
    decision = detect(html)
    assert decision.url == "https://example.com/page/3"
    assert decision.strategy == "numbered"
    assert decision.evidence == "3"


def test_numbered_pagination_requires_visible_current_page() -> None:
    html = """
    <nav class="pagination">
      <a href="/page/2">2</a>
      <a href="/page/3">3</a>
    </nav>
    """
    assert detect(html).url is None


def test_query_parameters_are_never_guessed() -> None:
    html = '<div class="cards"><a href="?page=2">2</a></div>'
    assert detect(html).url is None


def test_disabled_number_is_skipped() -> None:
    html = """
    <nav class="pagination">
      <span class="active">2</span>
      <a class="disabled" href="/page/3">3</a>
    </nav>
    """
    assert detect(html).url is None


def test_first_evidence_wins() -> None:
    html = """
    <html><head><link rel="next" href="/canonical-next"></head>
    <body><nav class="pagination"><a href="/ui-next">Next</a></nav></body></html>
    """
    decision = detect(html)
    assert decision.url == "https://example.com/canonical-next"
    assert decision.strategy == "rel_next"
