#!/usr/bin/env python3
"""Gwenda vibe check: GR routes, nature reserves, cultural vibe for top properties."""
import json
import math
import time
import requests

OVERPASS_URL = "https://overpass-api.de/api/interpreter"


def haversine_km(lat1, lon1, lat2, lon2):
    R = 6371
    dlat, dlon = math.radians(lat2 - lat1), math.radians(lon2 - lon1)
    a = math.sin(dlat / 2) ** 2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2) ** 2
    return R * 2 * math.asin(math.sqrt(a))


def overpass(query):
    try:
        resp = requests.post(OVERPASS_URL, data={"data": query}, timeout=20)
        return resp.json().get("elements", [])
    except Exception:
        return []


def find_gr_routes(lat, lon, radius=50000):
    query = f"""[out:json][timeout:15];
    (
      relation["route"="hiking"]["ref"~"GR|E "](around:{radius},{lat},{lon});
      way["route"="hiking"]["ref"~"GR|E "](around:{radius},{lat},{lon});
    );
    out tags 20;"""
    els = overpass(query)
    routes = set()
    for el in els:
        ref = el.get("tags", {}).get("ref", "")
        name = el.get("tags", {}).get("name", "")
        if ref:
            routes.add(ref)
        elif name and "GR" in name.upper():
            routes.add(name[:40])
    return sorted(routes) if routes else ["none within 50km"]


def find_nature(lat, lon, radius=30000):
    query = f"""[out:json][timeout:15];
    (
      way["leisure"="nature_reserve"](around:{radius},{lat},{lon});
      relation["leisure"="nature_reserve"](around:{radius},{lat},{lon});
      relation["boundary"="national_park"](around:{radius},{lat},{lon});
      relation["boundary"="protected_area"](around:{radius},{lat},{lon});
    );
    out tags 10;"""
    els = overpass(query)
    names = set()
    for el in els:
        name = el.get("tags", {}).get("name", "")
        if name:
            names.add(name[:50])
    return sorted(names)[:5] if names else ["none within 30km"]


def find_walking_paths(lat, lon, radius=10000):
    query = f"""[out:json][timeout:10];
    way["highway"="path"]["sac_scale"](around:{radius},{lat},{lon});
    out count;"""
    els = overpass(query)
    # Count is in the tags of a count element
    for el in els:
        count = el.get("tags", {}).get("ways", el.get("tags", {}).get("total", 0))
        return int(count) if count else 0
    return 0


def find_organic_farms(lat, lon, radius=30000):
    query = f"""[out:json][timeout:10];
    (
      node["organic"="yes"](around:{radius},{lat},{lon});
      node["shop"="organic"](around:{radius},{lat},{lon});
      node["cuisine"="organic"](around:{radius},{lat},{lon});
    );
    out tags 5;"""
    els = overpass(query)
    names = []
    for el in els:
        name = el.get("tags", {}).get("name", "")
        if name:
            names.append(name)
    return names[:3] if names else ["none found"]


# Known cultural/alternative vibe data per region
VIBE_NOTES = {
    "Liguria": "Ligurian hinterland has alternative communities, back-to-land movement. "
               "Genoa has strong leftist tradition (dockworkers, anti-G8). "
               "Not touristy inland (coast is). Art/craft scene in hilltop villages.",
    "Le Marche": "Under-the-radar Italy. Eco-communities near Amandola/Monti Sibillini. "
                 "Less touristy than Tuscany/Umbria. Foreign settlers (Dutch, UK) doing agriturismo. "
                 "Progressive pockets but generally conservative rural.",
    "Valencia": "Inland Castellón mountains are wild and empty. Strong hiking culture. "
                "Alternative communities in Maestrazgo. Left-leaning Valencia city influence. "
                "Very few tourists inland. Rough limestone landscapes.",
    "Creuse": "La Creuse = France's emptiest department. Strong back-to-land tradition since 1970s. "
              "Neo-rural communities, organic farming, craft culture. Progressive/alternative enclaves. "
              "GR routes through Millevaches plateau. NOT touristy at all. Very cheap property.",
    "Orne": "Perche region: rolling green hills, artisan culture, Parisian weekenders. "
            "Organic farms, cider makers, horse country. Calmer than Normandy coast. "
            "More bourgeois-bohème than radical-left. Some tourism but low-key.",
}


def main():
    from store import load
    store = load()

    with open("cyber_prairie_shortlist.json") as f:
        data = json.load(f)

    top5 = data["shortlist"][:5]

    for i, e in enumerate(top5):
        p = store.get(e["url"], {})
        lat = float(p.get("lat") or 0)
        lon = float(p.get("lon") or 0)
        location = e.get("location", "?")
        region = e.get("vibe_region", "")
        price = e.get("price")
        price_str = f"EUR {price:,.0f}" if isinstance(price, (int, float)) else "?"

        # Detect region from location/title/url
        search_text = " ".join(filter(None, [location, e.get("title", ""), e.get("url", "")]))
        listing_region = region or "Unknown"

        # Match to VIBE_NOTES
        vibe_key = None
        for key in VIBE_NOTES:
            if key.lower() in search_text.lower() or key.lower() in listing_region.lower():
                vibe_key = key
                break

        # Also try matching from broader context
        if not vibe_key:
            if lat > 43 and lat < 45 and lon > 7 and lon < 10:
                vibe_key = "Liguria"
            elif lat > 42 and lat < 44 and lon > 12 and lon < 14:
                vibe_key = "Le Marche"
            elif lat > 39 and lat < 41 and lon > -1 and lon < 1:
                vibe_key = "Valencia"
            elif lat > 45 and lat < 47 and lon > 1.5 and lon < 3:
                vibe_key = "Creuse"
            elif lat > 48 and lat < 49 and lon > 0 and lon < 2:
                vibe_key = "Orne"

        print(f"\n{'=' * 65}")
        print(f"#{i+1}  {location}  |  {listing_region or vibe_key or '?'}  |  {price_str}  |  CP {e['cp_score']:.2f}")
        print(f"    {e['url']}")
        print(f"{'=' * 65}")

        # GR routes
        gr = find_gr_routes(lat, lon)
        print(f"  GR routes (50km):  {', '.join(gr)}")
        time.sleep(1.5)

        # Nature reserves
        nature = find_nature(lat, lon)
        print(f"  Nature reserves:   {', '.join(nature)}")
        time.sleep(1.5)

        # Walking paths density
        paths = find_walking_paths(lat, lon)
        print(f"  Walking paths:     {paths} marked paths within 10km")
        time.sleep(1.5)

        # Organic/alternative
        organic = find_organic_farms(lat, lon)
        print(f"  Organic/alt shops: {', '.join(organic)}")
        time.sleep(1.5)

        # Cultural vibe note
        if vibe_key and vibe_key in VIBE_NOTES:
            print(f"\n  GWENDA VIBE ({vibe_key}):")
            note = VIBE_NOTES[vibe_key]
            # Word wrap at 70 chars
            words = note.split()
            line = "    "
            for w in words:
                if len(line) + len(w) > 70:
                    print(line)
                    line = "    " + w
                else:
                    line += " " + w if line.strip() else w
            if line.strip():
                print(line)

        print()


if __name__ == "__main__":
    main()
