"""
Google Places API (New) – fetch review count per branch for KPI "Client Reviews".
Uses Place Details with field userRatingCount. Requires GOOGLE_PLACES_API_KEY and Places API enabled.
Stores per-branch, per-month totals so "reviews this month" = current_total - total_at_start_of_month.
"""
import json
import logging
import os
import time
from datetime import datetime
from pathlib import Path
from typing import Dict, Optional

import httpx

logger = logging.getLogger(__name__)

# Place IDs for each branch (Google Maps / Business)
BRANCH_PLACE_IDS: Dict[str, str] = {
    "Bunbury": "ChIJ-7ogLOr9MSoRfEBsFZnI60c",
    "Busselton": "ChIJDdqkItQ5LioRpIRiFbqFwN0",
    "Mandurah": "ChIJpWC8Ygh-MioR0NyK8YTa4As",
}

PLACES_API_BASE = "https://places.googleapis.com/v1/places"
CACHE_TTL_SECONDS = 6 * 60 * 60  # 6 hours
_cache: Optional[tuple] = None  # (timestamp, { branch: count })

_STORAGE_FILE: Optional[Path] = None


def _get_storage_path() -> Path:
    global _STORAGE_FILE
    if _STORAGE_FILE is None:
        _STORAGE_FILE = Path(__file__).resolve().parent.parent.parent / "data" / "google_review_totals.json"
    return _STORAGE_FILE


def _load_stored_totals() -> Dict[str, int]:
    """Load { "Branch_YYYY-MM": total } from disk."""
    path = _get_storage_path()
    if not path.exists():
        return {}
    try:
        with open(path, "r") as f:
            data = json.load(f)
        return data if isinstance(data, dict) else {}
    except Exception as e:
        logger.warning("Failed to load Google review totals: %s", e)
        return {}


def _save_stored_totals(data: Dict[str, int]) -> None:
    path = _get_storage_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    try:
        with open(path, "w") as f:
            json.dump(data, f, indent=2)
    except Exception as e:
        logger.warning("Failed to save Google review totals: %s", e)


def get_google_review_counts() -> Dict[str, int]:
    """
    Return { "Bunbury": n, "Busselton": n, "Mandurah": n } from Google Place Details.
    Cached for 6 hours. Returns zeros on missing key or API error.
    """
    global _cache
    api_key = (os.getenv("GOOGLE_PLACES_API_KEY") or "").strip()
    if not api_key:
        logger.debug("GOOGLE_PLACES_API_KEY not set – skipping Google review counts")
        return {b: 0 for b in BRANCH_PLACE_IDS}

    now = time.time()
    if _cache is not None:
        cached_at, data = _cache
        if now - cached_at < CACHE_TTL_SECONDS:
            return data

    result = {}
    for branch, place_id in BRANCH_PLACE_IDS.items():
        count = _fetch_place_review_count(api_key, place_id)
        result[branch] = count if count is not None else 0

    _cache = (now, result)
    logger.info("Google review counts cached: %s", result)
    return result


def get_google_review_counts_for_month(year: int, month: int) -> Dict[str, Dict[str, int]]:
    """
    Return per branch: { "total": all-time count, "reviews_this_month": count for the given month }.
    For the current month we fetch from API and persist end-of-month total.
    For past months we use stored totals only (reviews_this_month = stored[month] - stored[prev_month]).
    """
    api_key = (os.getenv("GOOGLE_PLACES_API_KEY") or "").strip()
    stored = _load_stored_totals()
    month_key = f"{year}-{month:02d}"
    prev_month = month - 1 if month > 1 else 12
    prev_year = year if month > 1 else year - 1
    prev_key = f"{prev_year}-{prev_month:02d}"
    today = datetime.now()
    is_current_month = year == today.year and month == today.month

    out: Dict[str, Dict[str, int]] = {}
    if is_current_month and api_key:
        # Fetch from API (use cache to avoid hammering)
        raw = get_google_review_counts()
        for branch in BRANCH_PLACE_IDS:
            current_total = raw.get(branch) or 0
            total_at_start = stored.get(f"{branch}_{prev_key}") or current_total
            reviews_this_month = max(0, current_total - total_at_start)
            out[branch] = {"total": current_total, "reviews_this_month": reviews_this_month}
            stored[f"{branch}_{month_key}"] = current_total
        _save_stored_totals(stored)
    else:
        for branch in BRANCH_PLACE_IDS:
            total = stored.get(f"{branch}_{month_key}") or 0
            total_at_start = stored.get(f"{branch}_{prev_key}") or total
            reviews_this_month = max(0, total - total_at_start)
            out[branch] = {"total": total, "reviews_this_month": reviews_this_month}
    return out


def _fetch_place_review_count(api_key: str, place_id: str) -> Optional[int]:
    """Call Place Details (New) for userRatingCount. Returns None on error."""
    url = f"{PLACES_API_BASE}/{place_id}"
    headers = {
        "X-Goog-Api-Key": api_key,
        "X-Goog-FieldMask": "userRatingCount",
    }
    try:
        with httpx.Client(timeout=10.0) as client:
            resp = client.get(url, headers=headers)
            if resp.status_code != 200:
                logger.warning("Places API %s for place %s: %s", resp.status_code, place_id[:16], resp.text[:200])
                return None
            data = resp.json()
            count = data.get("userRatingCount")
            if count is not None:
                return int(count)
            return 0
    except Exception as e:
        logger.warning("Places API error for place %s: %s", place_id[:16], e)
        return None


def invalidate_cache() -> None:
    """Clear cached review counts (e.g. after config change)."""
    global _cache
    _cache = None
