"""Тесты для POST /admin/scrape/ekburg-permits.

Проверяет:
- валидный запрос без year → scope all_years_2022_2026, task_id в ответе
- валидный запрос с year=2026 → scope year_2026
- year < 2022 или > 2030 → 422
- отсутствие X-Admin-Token → 401/503
"""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest
from fastapi.testclient import TestClient

from app.main import app

ADMIN_TOKEN = "test-admin-token"
ADMIN_HEADERS = {"X-Admin-Token": ADMIN_TOKEN}
ENDPOINT = "/api/v1/admin/scrape/ekburg-permits"


def _mock_task(task_id: str = "fake-task-id-123") -> MagicMock:
    result = MagicMock()
    result.id = task_id
    return result


@patch("app.core.config.settings.scrape_admin_token", ADMIN_TOKEN)
def test_trigger_refresh_all_returns_task_id() -> None:
    """POST без year → refresh_all queued, scope=all_years_2022_2026."""
    mock_result = _mock_task("task-all-001")

    with (
        patch("app.workers.tasks.ekburg_permits_sync.refresh_all") as mock_refresh_all,
        patch("app.workers.tasks.ekburg_permits_sync.refresh_year"),
    ):
        mock_refresh_all.apply_async.return_value = mock_result
        client = TestClient(app)
        response = client.post(ENDPOINT, json={}, headers=ADMIN_HEADERS)

    assert response.status_code == 200, response.text
    body = response.json()
    assert body["task_id"] == "task-all-001"
    assert body["scope"] == "all_years_2022_2026"
    assert "queued_at" in body


@patch("app.core.config.settings.scrape_admin_token", ADMIN_TOKEN)
def test_trigger_refresh_year_returns_task_id() -> None:
    """POST year=2026 → refresh_year queued, scope=year_2026."""
    mock_result = _mock_task("task-year-002")

    with (
        patch("app.workers.tasks.ekburg_permits_sync.refresh_year") as mock_refresh_year,
        patch("app.workers.tasks.ekburg_permits_sync.refresh_all"),
    ):
        mock_refresh_year.apply_async.return_value = mock_result
        client = TestClient(app)
        response = client.post(ENDPOINT, json={"year": 2026}, headers=ADMIN_HEADERS)

    assert response.status_code == 200, response.text
    body = response.json()
    assert body["task_id"] == "task-year-002"
    assert body["scope"] == "year_2026"


@pytest.mark.parametrize("bad_year", [2021, 2031, 1999, 9999])
@patch("app.core.config.settings.scrape_admin_token", ADMIN_TOKEN)
def test_trigger_invalid_year_returns_422(bad_year: int) -> None:
    """year вне диапазона [2022, 2030] → 422 Unprocessable Entity."""
    client = TestClient(app)
    response = client.post(ENDPOINT, json={"year": bad_year}, headers=ADMIN_HEADERS)
    assert response.status_code == 422, f"year={bad_year} должен возвращать 422"


@pytest.mark.skip(
    reason=(
        "X-Admin-Token gate удалён в #437 (refactor(security): убрать X-Admin-Token — "
        "Caddy basic_auth + RBAC middleware достаточны). trigger_ekburg_permits больше не "
        "несёт verify_admin_token dependency; защита — на уровне Caddy/RBAC. В test-mode "
        "RBAC bypass'ится (CI-rehab 1/3), поэтому 401/503 здесь больше недостижим без "
        "реверта security-решения #437. Тест проверял удалённое поведение."
    )
)
def test_trigger_no_token_returns_401_or_503() -> None:
    """Без X-Admin-Token → 401 или 503 (устарело: токен-гейт удалён в #437)."""
    client = TestClient(app)
    response = client.post(ENDPOINT, json={})
    assert response.status_code in (401, 503), response.text
