from fastapi import FastAPI, HTTPException, Query
from typing import Optional, List, Dict, Any
import logging
from urllib.parse import unquote

from .extractor import extract_place_data
from .scraper import scrape_google_maps, load_page_from_url

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

app = FastAPI(
    title="Google Maps Scraper API (Selenium + Proxies)",
    description="Scrape Google Maps using Selenium with DecoDo proxies",
    version="0.2.0",
)

@app.get("/")
def read_root():
    return {"message": "Google Maps Scraper API is running (with Selenium + Proxy)."}


################################################################################################
# 🚀 Scrape by Search Query (via Selenium + selenium-wire + DecoDo)
################################################################################################

@app.get("/scrape-get", response_model=List[Dict[str, Any]])
def run_scrape_get(
    query: str = Query(..., description="Search query for Google Maps."),
    max_places: Optional[int] = Query(None, description="Max number of places to scrape."),
    lang: str = Query("en", description="Language code (e.g., 'en')."),
    headless: bool = Query(True, description="Run headless browser."),
    lat: Optional[float] = Query(None, description="Latitude for centering search."),
    lng: Optional[float] = Query(None, description="Longitude for centering search."),
    max_distance_km: float = Query(30.0, description="Max distance in km from center point.")
):
    try:
        logging.info(f"Starting scrape for query: '{query}' using Selenium + Proxy")
        results = scrape_google_maps(
            query=query,
            max_places=max_places,
            lang=lang,
            headless=headless,
            lat=lat,
            lng=lng,
            max_distance_km=max_distance_km
        )
        return results
    except Exception as e:
        logging.error(f"Error in /scrape-get: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Error scraping query: {str(e)}")


################################################################################################
# 🌐 Scrape Direct Place URL (via Selenium + selenium-wire)
################################################################################################

from fastapi import Query, HTTPException
from typing import Optional
from urllib.parse import unquote
import logging

@app.get("/scrape-by-url")
async def scrape_by_url(
    map_url: str = Query(..., description="Google Maps CID URL (e.g., https://maps.google.com/maps?cid=...)"),
    lat: Optional[float] = Query(None),
    lng: Optional[float] = Query(None)
):
    try:
        decoded_url = unquote(map_url)
        logging.info(f"\n🌐 [SCRAPE] Starting scrape for URL: {decoded_url}")

        # Load the page and capture bandwidth
        result_obj = load_page_from_url(decoded_url)
        html_content = result_obj["html"]
        bandwidth_info = result_obj["bandwidth"]

        # Extract place data
        extracted_data = extract_place_data(html_content, google_map_url=decoded_url)

        if not extracted_data:
            logging.warning(f"[SCRAPE] No data extracted from URL: {decoded_url}")
            raise HTTPException(status_code=404, detail="No valid data extracted from the page.")

        # ✅ Print bandwidth info per place
        logging.info(f"🔍 [INFO] Scraped Place URL: {decoded_url}")
        logging.info(f"📶 Bandwidth Usage for this URL:")
        logging.info(f"   ⬆️ Sent: {bandwidth_info['sent_mb']} MB")
        logging.info(f"   ⬇️ Received: {bandwidth_info['received_mb']} MB")
        logging.info(f"   📊 Total: {bandwidth_info['total_mb']} MB\n")

        return {
            **extracted_data,
            "place_link": decoded_url,
            "bandwidth_used_mb": bandwidth_info["total_mb"],
            "bandwidth_details": bandwidth_info  # Optional detailed stats
        }

    except Exception as e:
        logging.error(f"[❌ ERROR] Failed to scrape {map_url}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Error scraping URL: {str(e)}")


################################################################################################
# 🧪 POST Endpoint (optional alternative to GET)
################################################################################################

@app.post("/scrape", response_model=List[Dict[str, Any]])
def run_scrape(
    query: str = Query(..., description="Search query for Google Maps."),
    max_places: Optional[int] = Query(None),
    lang: str = Query("en"),
    headless: bool = Query(True),
    lat: Optional[float] = Query(None),
    lng: Optional[float] = Query(None),
    max_distance_km: float = Query(30.0)
):
    try:
        logging.info(f"[POST SCRAPE] Query: {query}")
        results = scrape_google_maps(
            query=query,
            max_places=max_places,
            lang=lang,
            headless=headless,
            lat=lat,
            lng=lng,
            max_distance_km=max_distance_km
        )
        return results
    except Exception as e:
        logging.error(f"Error during POST scrape: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Error scraping: {str(e)}")
