"""Chrome UX Report (CrUX) API Service.

Pobiera field data (dane od realnych użytkowników Chrome) dla stron internetowych.
Uzupełnia lab data z PageSpeed Insights o metryki z rzeczywistego ruchu.

API: https://chromeuxreport.googleapis.com/v1/records:queryRecord
Free tier: 150 requests/minute
"""

import os
import logging
import requests

logger = logging.getLogger(__name__)


class CrUXService:
    """Service for Chrome UX Report API."""

    BASE_URL = 'https://chromeuxreport.googleapis.com/v1/records:queryRecord'

    def __init__(self, api_key: str = None):
        self.api_key = api_key or os.environ.get('GOOGLE_PLACES_API_KEY')
        if not self.api_key:
            logger.warning("CrUX API key not configured (GOOGLE_PLACES_API_KEY)")

    def get_field_data(self, url: str) -> dict | None:
        """Fetch CrUX field data for a URL.

        Args:
            url: Website URL (e.g., 'https://example.com')

        Returns:
            Dict with field metrics or None if no data available.
            Many small/local business sites won't have CrUX data.
        """
        if not self.api_key:
            return None

        try:
            # Try origin-level first (more likely to have data)
            response = requests.post(
                f"{self.BASE_URL}?key={self.api_key}",
                json={'origin': url.rstrip('/')},
                timeout=10
            )

            if response.status_code == 404:
                # No CrUX data for this origin (common for small sites)
                return None

            if response.status_code != 200:
                logger.warning(f"CrUX API error {response.status_code} for {url}")
                return None

            data = response.json()
            record = data.get('record', {})
            metrics = record.get('metrics', {})

            result = {}

            # Extract each metric's p75 value
            metric_mapping = {
                'largest_contentful_paint': 'crux_lcp_ms',
                'interaction_to_next_paint': 'crux_inp_ms',
                'cumulative_layout_shift': 'crux_cls',
                'first_contentful_paint': 'crux_fcp_ms',
                'time_to_first_byte': 'crux_ttfb_ms',
            }

            for api_name, our_name in metric_mapping.items():
                metric = metrics.get(api_name, {})
                percentiles = metric.get('percentiles', {})
                p75 = percentiles.get('p75')
                if p75 is not None:
                    # CLS is reported as decimal (e.g., 0.15), others in ms
                    if 'layout_shift' in api_name:
                        result[our_name] = round(float(p75), 3)
                    else:
                        result[our_name] = int(p75)

                # Also extract histogram category distribution
                histogram = metric.get('histogram', [])
                if histogram and len(histogram) >= 3:
                    total = sum(h.get('density', 0) for h in histogram)
                    if total > 0:
                        good_pct = round(histogram[0].get('density', 0) * 100, 1)
                        result[f'{our_name}_good_pct'] = good_pct

            # Collection period
            collection_period = record.get('collectionPeriod', {})
            if collection_period:
                last_date = collection_period.get('lastDate', {})
                if last_date:
                    result['crux_period_end'] = f"{last_date.get('year')}-{last_date.get('month'):02d}-{last_date.get('day'):02d}"

            return result if result else None

        except requests.exceptions.Timeout:
            logger.warning(f"CrUX API timeout for {url}")
            return None
        except Exception as e:
            logger.warning(f"CrUX API error for {url}: {e}")
            return None
