"""Tests para pull_gsc_search_analytics (sin red ni credenciales)."""

import sys
import os

sys.path.insert(0, os.path.dirname(__file__))
from pull_gsc_search_analytics import pull_gsc_search_analytics


class _FakeQuery:
    """Simula el objeto que devuelve service.searchanalytics().query(...)."""

    def __init__(self, pages, calls_log):
        self._pages = pages
        self._calls_log = calls_log

    def execute(self):
        # Devuelve la pagina cuyo startRow coincide; si no existe, {} (sin rows).
        start_row = self._calls_log[-1]["startRow"]
        return self._pages.get(start_row, {})


class _FakeSearchAnalytics:
    def __init__(self, pages, calls_log):
        self._pages = pages
        self._calls_log = calls_log

    def query(self, siteUrl, body):  # noqa: N803 (firma de la API real)
        self._calls_log.append(
            {
                "siteUrl": siteUrl,
                "startRow": body["startRow"],
                "rowLimit": body["rowLimit"],
                "dimensions": body["dimensions"],
                "type": body["type"],
            }
        )
        return _FakeQuery(self._pages, self._calls_log)


class _FakeService:
    """Mock del service autenticado de GSC."""

    def __init__(self, pages):
        # pages: dict startRow -> response dict
        self._pages = pages
        self.calls_log = []

    def searchanalytics(self):
        return _FakeSearchAnalytics(self._pages, self.calls_log)


def _row(keys, clicks, impressions, ctr, position):
    return {
        "keys": keys,
        "clicks": clicks,
        "impressions": impressions,
        "ctr": ctr,
        "position": position,
    }


def test_aplanado_mapea_keys_a_nombres_de_dimension():
    # Una sola pagina con menos filas que row_limit => para en la primera.
    pages = {
        0: {
            "rows": [
                _row(["seo tips", "https://ej.com/a"], 5, 100, 0.05, 12.3),
            ]
        }
    }
    service = _FakeService(pages)
    result = pull_gsc_search_analytics(
        service,
        "sc-domain:ej.com",
        "2026-06-01",
        "2026-06-10",
        dimensions=["query", "page"],
        row_limit=2,
    )
    assert result == [
        {
            "query": "seo tips",
            "page": "https://ej.com/a",
            "clicks": 5,
            "impressions": 100,
            "ctr": 0.05,
            "position": 12.3,
        }
    ]


def test_paginacion_recorre_varias_paginas_y_para_en_pagina_corta():
    # row_limit=2: pagina 0 llena (2 filas), pagina 2 llena (2 filas),
    # pagina 4 corta (1 fila) => para tras la corta. 5 filas en total.
    pages = {
        0: {"rows": [_row(["q1", "p1"], 1, 10, 0.1, 1.0), _row(["q2", "p2"], 2, 20, 0.1, 2.0)]},
        2: {"rows": [_row(["q3", "p3"], 3, 30, 0.1, 3.0), _row(["q4", "p4"], 4, 40, 0.1, 4.0)]},
        4: {"rows": [_row(["q5", "p5"], 5, 50, 0.1, 5.0)]},
    }
    service = _FakeService(pages)
    result = pull_gsc_search_analytics(
        service,
        "https://ej.com/",
        "2026-06-01",
        "2026-06-10",
        dimensions=["query", "page"],
        row_limit=2,
    )
    assert len(result) == 5
    assert [r["query"] for r in result] == ["q1", "q2", "q3", "q4", "q5"]
    # Tres requests: startRow 0, 2 y 4 (la de startRow 4 fue corta => no pide 6).
    assert [c["startRow"] for c in service.calls_log] == [0, 2, 4]


def test_max_total_rows_recorta():
    pages = {
        0: {"rows": [_row(["q1", "p1"], 1, 10, 0.1, 1.0), _row(["q2", "p2"], 2, 20, 0.1, 2.0)]},
        2: {"rows": [_row(["q3", "p3"], 3, 30, 0.1, 3.0), _row(["q4", "p4"], 4, 40, 0.1, 4.0)]},
    }
    service = _FakeService(pages)
    result = pull_gsc_search_analytics(
        service,
        "sc-domain:ej.com",
        "2026-06-01",
        "2026-06-10",
        dimensions=["query", "page"],
        row_limit=2,
        max_total_rows=3,
    )
    assert len(result) == 3
    assert [r["query"] for r in result] == ["q1", "q2", "q3"]


def test_rows_ausente_retorna_lista_vacia():
    # Primera (y unica) pagina sin clave 'rows' => lista vacia, sin error.
    pages = {0: {"responseAggregationType": "byPage"}}
    service = _FakeService(pages)
    result = pull_gsc_search_analytics(
        service,
        "sc-domain:ej.com",
        "2026-06-01",
        "2026-06-10",
        dimensions=["query"],
        row_limit=2,
    )
    assert result == []


def test_dimension_unica_date():
    pages = {0: {"rows": [_row(["2026-06-01"], 7, 70, 0.1, 8.0)]}}
    service = _FakeService(pages)
    result = pull_gsc_search_analytics(
        service,
        "sc-domain:ej.com",
        "2026-06-01",
        "2026-06-01",
        dimensions=["date"],
        row_limit=2,
    )
    assert result == [
        {"date": "2026-06-01", "clicks": 7, "impressions": 70, "ctr": 0.1, "position": 8.0}
    ]
