"""Тесты pravo_gov66_client — offline, без живой сети.

Покрывают: парсинг search-HTML (doc_id/title/url), парсинг страницы документа
(PDF-ссылка), fallback на ecp-вариант, отсутствие PDF.
"""

from __future__ import annotations

from app.services.scrapers.pravo_gov66_client import (
    _LAW_TYPE_POSTANOVLENIE,
    _extract_pdf_url,
    _parse_search_html,
)

# ── Фикстура HTML страницы поиска ─────────────────────────────────────────────
# Реальный фрагмент страницы https://www.pravo.gov66.ru/search/?q=изъятие+земельных+участков
# Содержит ссылки вида /NNNNN/ с заголовком постановления.
_SEARCH_HTML_FIXTURE = """
<!DOCTYPE html>
<html>
<head><title>Поиск</title></head>
<body>
<div class="search-results">
  <ul>
    <li class="result-item">
      <a href="/35496/">
        Об изъятии земельных участков для государственных нужд
        Свердловской области в целях реконструкции ул. Татищева
        в г. Екатеринбурге
      </a>
    </li>
    <li class="result-item">
      <a href="/34812/">
        О резервировании земельных участков для нужд Екатеринбург
      </a>
    </li>
    <li class="result-item">
      <!-- Ссылка на категорию, не документ — должна игнорироваться -->
      <a href="/category/law/">Категория</a>
    </li>
    <li class="result-item">
      <!-- Дубль doc_id 35496 — должен дедуплицироваться -->
      <a href="/35496/">Дубль</a>
    </li>
    <li class="result-item">
      <!-- Нечисловой id — не должен попасть -->
      <a href="/some-slug/">Текстовый slug</a>
    </li>
  </ul>
</div>
</body>
</html>
"""

# ── Фикстура HTML страницы документа с обычным PDF ────────────────────────────
_DOC_HTML_WITH_PDF = """
<!DOCTYPE html>
<html>
<body>
  <h1>Постановление № 509-ПП</h1>
  <p>
    Скачать документ:
    <a href="/media/pravo/509-ПП_ab1234cd.pdf">Скачать PDF</a>
  </p>
  <p>
    Подписанная версия:
    <a href="/media/pravo/ecp/509-ПП.pdf">Скачать подписанный PDF</a>
  </p>
</body>
</html>
"""

# ── Фикстура HTML страницы документа только с ecp PDF ─────────────────────────
_DOC_HTML_ECP_ONLY = """
<!DOCTYPE html>
<html>
<body>
  <h1>Постановление № 312-ПП</h1>
  <p>
    <a href="/media/pravo/ecp/312-ПП.pdf">Подписанный PDF</a>
  </p>
</body>
</html>
"""

# ── Фикстура HTML страницы документа без PDF ──────────────────────────────────
_DOC_HTML_NO_PDF = """
<!DOCTYPE html>
<html>
<body>
  <h1>Постановление без PDF</h1>
  <p>Текст постановления размещён ниже.</p>
</body>
</html>
"""


class TestLawTypeConstant:
    def test_postanovlenie_is_numeric_string(self) -> None:
        """Числовой код — сервер игнорирует текстовые значения типа «Постановление»."""
        assert _LAW_TYPE_POSTANOVLENIE == "1"
        assert _LAW_TYPE_POSTANOVLENIE.isdigit()


class TestParseSearchHtml:
    def test_extracts_doc_ids_and_titles(self) -> None:
        results = _parse_search_html(_SEARCH_HTML_FIXTURE)
        ids = [r["doc_id"] for r in results]
        assert "35496" in ids
        assert "34812" in ids

    def test_ignores_non_numeric_paths(self) -> None:
        results = _parse_search_html(_SEARCH_HTML_FIXTURE)
        ids = [r["doc_id"] for r in results]
        assert "some-slug" not in ids

    def test_deduplicates_doc_ids(self) -> None:
        results = _parse_search_html(_SEARCH_HTML_FIXTURE)
        ids = [r["doc_id"] for r in results]
        assert ids.count("35496") == 1

    def test_ignores_category_links(self) -> None:
        results = _parse_search_html(_SEARCH_HTML_FIXTURE)
        # /category/law/ не числовой id — не попадает.
        ids = [r["doc_id"] for r in results]
        assert len(ids) == 2

    def test_url_is_absolute(self) -> None:
        results = _parse_search_html(_SEARCH_HTML_FIXTURE)
        for r in results:
            assert r["url"].startswith("https://www.pravo.gov66.ru/")

    def test_title_extracted(self) -> None:
        results = _parse_search_html(_SEARCH_HTML_FIXTURE)
        doc = next(r for r in results if r["doc_id"] == "35496")
        assert "изъятии" in doc["title"].lower()

    def test_empty_html_returns_empty(self) -> None:
        assert _parse_search_html("") == []

    def test_html_no_doc_links_returns_empty(self) -> None:
        html = "<html><body><a href='/category/'>Cat</a></body></html>"
        assert _parse_search_html(html) == []


class TestExtractPdfUrl:
    def test_prefers_non_ecp_pdf(self) -> None:
        url = _extract_pdf_url(_DOC_HTML_WITH_PDF)
        assert url is not None
        assert "ecp" not in url
        assert url.endswith(".pdf")

    def test_non_ecp_pdf_is_absolute(self) -> None:
        url = _extract_pdf_url(_DOC_HTML_WITH_PDF)
        assert url is not None
        assert url.startswith("https://www.pravo.gov66.ru/media/pravo/")

    def test_falls_back_to_ecp_when_no_regular_pdf(self) -> None:
        url = _extract_pdf_url(_DOC_HTML_ECP_ONLY)
        assert url is not None
        assert "ecp" in url
        assert url.endswith(".pdf")

    def test_returns_none_when_no_pdf(self) -> None:
        url = _extract_pdf_url(_DOC_HTML_NO_PDF)
        assert url is None

    def test_ecp_fallback_is_absolute(self) -> None:
        url = _extract_pdf_url(_DOC_HTML_ECP_ONLY)
        assert url is not None
        assert url.startswith("https://www.pravo.gov66.ru/")
