#!/usr/bin/env python3
"""
Pobiera propozycje słów kluczowych z Google Ads Keyword Planner
(KeywordPlanIdeaService.GenerateKeywordIdeas): średni miesięczny wolumen,
poziom konkurencji oraz widełki stawek CPC top-of-page.

Idee słów kluczowych są darmowe (nie generują kosztów kliknięć).
Wymaga jedynie poprawnego konta klienta pod managerem do uwierzytelnienia API.

Użycie:
    python scripts/reports/fetch_keyword_ideas.py --keywords "sesja buduarowa,fotograf kobiet kraków"
    python scripts/reports/fetch_keyword_ideas.py --keywords "coaching dla kobiet" --location 2616 --language 1045
    python scripts/reports/fetch_keyword_ideas.py --keywords "..." --output out.json

Domyślnie: język polski (1045), geolokalizacja Polska (2616), sieć Google Search.
"""

import argparse
import io
import json
import os
import sys
from pathlib import Path

if __name__ == "__main__":
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")

ROOT = Path(__file__).parent.parent.parent
sys.path.insert(0, str(ROOT))
from src.gads_v2.config import load_env
from src.gads_v2.google_ads import get_google_ads_client

load_env(ROOT / ".env")

# Stałe Google Ads (kryteria geo/język):
# https://developers.google.com/google-ads/api/reference/data/geotargets
GEO_POLAND = "2616"
GEO_KRAKOW = "1011969"
LANG_POLISH = "1030"  # zweryfikowane przez API (language_constant.code = 'pl')

def _default_customer_id():
    """Konto klienta pod managerem do uwierzytelnienia zapytania.

    Idee są darmowe — konto służy tylko jako kontekst API. Kolejność:
    1) KEYWORD_IDEAS_CUSTOMER_ID z .env, 2) pierwszy klient z config/clients.toml.
    """
    env = os.environ.get("KEYWORD_IDEAS_CUSTOMER_ID")
    if env:
        return env
    import tomllib
    toml_path = ROOT / "config" / "clients.toml"
    if toml_path.exists():
        data = tomllib.loads(toml_path.read_text(encoding="utf-8"))
        for cfg in data.get("clients", {}).values():
            cid = cfg.get("google_ads_customer_id")
            if cid:
                return cid
    raise RuntimeError(
        "Brak customer_id — ustaw KEYWORD_IDEAS_CUSTOMER_ID w .env "
        "albo dodaj klienta z google_ads_customer_id do config/clients.toml."
    )


def fetch_keyword_ideas(keywords, customer_id=None, location_ids=None, language_id=LANG_POLISH):
    """Zwraca listę propozycji słów kluczowych z metrykami planera.

    Ustawienie języka (polski = 1030) jest kluczowe — bez niego API nie
    rozszerza fraz seed o powiązane propozycje.
    """
    client = get_google_ads_client()
    customer_id = (customer_id or _default_customer_id()).replace("-", "")
    location_ids = location_ids or [GEO_POLAND]

    googleads_service = client.get_service("GoogleAdsService")
    idea_service = client.get_service("KeywordPlanIdeaService")

    request = client.get_type("GenerateKeywordIdeasRequest")
    request.customer_id = customer_id
    if language_id:
        request.language = googleads_service.language_constant_path(language_id)
    request.geo_target_constants.extend(
        googleads_service.geo_target_constant_path(g) for g in location_ids
    )
    request.include_adult_keywords = True  # branża fotografii zmysłowej/buduar
    request.keyword_plan_network = (
        client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH
    )
    request.keyword_seed.keywords.extend(keywords)

    response = idea_service.generate_keyword_ideas(request=request)

    results = []
    for idea in response:
        m = idea.keyword_idea_metrics
        results.append({
            "keyword": idea.text,
            "avg_monthly_searches": m.avg_monthly_searches or 0,
            "competition": m.competition.name if m.competition else "UNKNOWN",
            "competition_index": m.competition_index or 0,
            "low_top_bid_pln": round((m.low_top_of_page_bid_micros or 0) / 1_000_000, 2),
            "high_top_bid_pln": round((m.high_top_of_page_bid_micros or 0) / 1_000_000, 2),
        })

    results.sort(key=lambda x: x["avg_monthly_searches"], reverse=True)
    return results


def main():
    parser = argparse.ArgumentParser(description="Pobierz propozycje słów kluczowych z Google Ads Keyword Planner")
    parser.add_argument("--keywords", required=True, help="Frazy seed rozdzielone przecinkami")
    parser.add_argument("--customer-id", help="ID konta klienta (domyślnie z KEYWORD_IDEAS_CUSTOMER_ID)")
    parser.add_argument("--location", default=GEO_POLAND, help="ID geo (domyślnie 2616 = Polska; 1011969 = Kraków)")
    parser.add_argument("--language", default=LANG_POLISH, help="ID języka (domyślnie 1030 = polski)")
    parser.add_argument("--output", help="Zapisz wynik JSON do pliku")
    args = parser.parse_args()

    keywords = [k.strip() for k in args.keywords.split(",") if k.strip()]
    location_ids = [g.strip() for g in args.location.split(",") if g.strip()]

    try:
        results = fetch_keyword_ideas(
            keywords,
            customer_id=args.customer_id,
            location_ids=location_ids,
            language_id=args.language,
        )
    except Exception as exc:  # GoogleAdsException — wypisz szczegóły walidacji
        errors = getattr(getattr(exc, "failure", None), "errors", None)
        if errors:
            for e in errors:
                loc = ".".join(fp.field_name for fp in e.location.field_path_elements)
                print(f"BŁĄD: {e.error_code} | pole: {loc} | {e.message}")
            sys.exit(1)
        raise

    payload = {
        "seed_keywords": keywords,
        "location_ids": location_ids,
        "language_id": args.language,
        "count": len(results),
        "ideas": results,
    }

    text = json.dumps(payload, indent=2, ensure_ascii=False)
    if args.output:
        Path(args.output).write_text(text, encoding="utf-8")
        print(f"Zapisano {len(results)} propozycji do {args.output}")
    else:
        print(text)


if __name__ == "__main__":
    main()
