import importlib.util
import unittest
from pathlib import Path


MODULE_PATH = Path(__file__).with_name("fetch_serpapi_trends.py")
SPEC = importlib.util.spec_from_file_location("fetch_serpapi_trends", MODULE_PATH)
assert SPEC and SPEC.loader
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)


class SerpApiTrendsCollectorTests(unittest.TestCase):
    def test_build_jobs_matches_preregistered_matrix(self) -> None:
        spec = {
            "periods": {"five_years": "five", "twelve_months": "twelve"},
            "groups": [
                {
                    "id": "worldwide",
                    "geo": "",
                    "hl": "en-US",
                    "items": [
                        {
                            "label": f"item-{index}",
                            "keyword": f"q-{index}",
                            "kind": "search_term",
                        }
                        for index in range(5)
                    ],
                    "fetch_geography": True,
                    "related_indices": [1, 3],
                },
                {
                    "id": "country",
                    "geo": "US",
                    "hl": "en-US",
                    "items": [
                        {"label": "one", "keyword": "one", "kind": "search_term"}
                    ],
                    "fetch_geography": False,
                    "related_indices": [],
                },
            ],
        }

        jobs = MODULE.build_jobs(spec)

        self.assertEqual(7, len(jobs))
        self.assertEqual(
            {"timeseries": 4, "geography": 1, "related_queries": 2},
            {
                stage: sum(job.stage == stage for job in jobs)
                for stage in {job.stage for job in jobs}
            },
        )

    def test_derive_timeseries_distinguishes_explicit_zero_from_missing(self) -> None:
        group = {
            "items": [
                {"label": "Alpha", "keyword": "Alpha", "kind": "search_term"},
                {"label": "Beta", "keyword": "Beta", "kind": "search_term"},
            ]
        }
        payload = {
            "interest_over_time": {
                "averages": [
                    {"query": "Alpha", "value": 25},
                    {"query": "Beta", "value": 0},
                ],
                "timeline_data": [
                    {
                        "date": "Jan 1-7, 2026",
                        "timestamp": "1767225600",
                        "values": [
                            {"query": "Alpha", "value": "50", "extracted_value": 50},
                            {"query": "Beta", "value": "0", "extracted_value": 0},
                        ],
                    },
                    {
                        "date": "Jan 8-14, 2026",
                        "timestamp": "1767830400",
                        "partial_data": True,
                        "values": [
                            {"query": "Alpha", "value": "25", "extracted_value": 25},
                            {"query": "Beta", "value": "0", "extracted_value": 0},
                        ],
                    },
                ],
            }
        }

        rows, summaries = MODULE.derive_timeseries(payload, group)

        self.assertEqual("true", rows[0]["has_data"])
        self.assertEqual("true", rows[1]["has_data"])
        self.assertEqual("true", rows[2]["is_partial"])
        self.assertEqual(50, summaries[0]["latest_complete_index"])
        self.assertEqual(1, summaries[0]["complete_points"])
        self.assertEqual(0, summaries[1]["nonzero_share"])

    def test_derive_geography_and_related_queries_use_provider_fields(self) -> None:
        group = {
            "items": [
                {"label": "Alpha", "keyword": "Alpha"},
                {"label": "Beta", "keyword": "Beta"},
            ]
        }
        geography = {
            "compared_breakdown_by_region": [
                {
                    "geo": "US",
                    "location": "United States",
                    "values": [
                        {"query": "Alpha", "extracted_value": 90},
                        {"query": "Beta", "extracted_value": 0},
                    ],
                }
            ]
        }
        related = {
            "related_queries": {
                "top": [
                    {
                        "query": "alpha game",
                        "extracted_value": 100,
                        "value": "100",
                        "link": "https://example.com/top",
                    }
                ],
                "rising": [
                    {
                        "query": "alpha online",
                        "extracted_value": 250,
                        "value": "+250%",
                        "link": "https://example.com/rising",
                    }
                ],
            }
        }

        geography_rows = MODULE.derive_geography(geography, group)
        related_rows = MODULE.derive_related_queries(related, "Alpha")

        self.assertEqual("US", geography_rows[0]["geo_code"])
        self.assertEqual("unknown", geography_rows[1]["has_data"])
        self.assertEqual(["top", "rising"], [row["metric"] for row in related_rows])
        self.assertEqual(250, related_rows[1]["value"])

    def test_redact_secret_removes_key_names_and_values_recursively(self) -> None:
        payload = {
            "api_key": "secret",
            "nested": [{"url": "https://example.com/?api_key=secret"}, "secret"],
        }

        redacted = MODULE.redact_secret(payload, "secret")

        self.assertNotIn("api_key", redacted)
        self.assertEqual(
            "https://example.com/?api_key=[REDACTED]", redacted["nested"][0]["url"]
        )
        self.assertEqual("[REDACTED]", redacted["nested"][1])

    def test_classify_payload_accepts_confirmed_no_results(self) -> None:
        no_results = {
            "search_metadata": {"status": "Success"},
            "error": "Google Trends hasn't returned any results for this query.",
        }

        self.assertEqual("ok_no_data", MODULE.classify_payload(no_results))


if __name__ == "__main__":
    unittest.main()
