"""
config.py
=========
Configurazione centrale della pipeline percorsi pedonali multi-source.

Tutti i path sono RELATIVI alla cartella `script/`.

Modifica questo file per:
  - aggiungere/rimuovere categorie POI
  - cambiare CRS metrico (default UTM 32N per Nord Italia)
  - regolare buffer area di download OSM
  - regolare le soglie di warning di snap
"""
import os

# -----------------------------------------------------------------------------
# PATH
# -----------------------------------------------------------------------------
PIPELINE_DIR = os.path.dirname(os.path.abspath(__file__))      # script/pipeline/
SCRIPT_DIR   = os.path.dirname(PIPELINE_DIR)                   # script/
DATA_DIR     = os.path.join(SCRIPT_DIR, "data")
OUTPUT_DIR   = os.path.join(SCRIPT_DIR, "output")
CACHE_DIR    = os.path.join(PIPELINE_DIR, "_cache")

os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(CACHE_DIR,  exist_ok=True)

# File sorgente con gli edifici di tutta Parma e i POI gia' organizzati
SOURCE_GPKG = os.path.join(DATA_DIR, "path_building_to_pois_all_parma.gpkg")

# Layer da SOURCE_GPKG che useremo
FOOTPRINTS_LAYER = "footprints_all"     # ~44k edifici di Parma (Polygon, EPSG:3857)
ORIGINS_LAYER    = "origin_points_all"  # baricentri gia' calcolati (Point, EPSG:3857)

# -----------------------------------------------------------------------------
# FILTRO QUARTIERE (San Leonardo)
# -----------------------------------------------------------------------------
# Se QUARTIERE_GPKG punta a un file esistente, la pipeline filtra:
#   - edifici (02_prepare_graph.py): tiene solo quelli il cui CENTROIDE cade
#                                    dentro il poligono del quartiere
#   - POI (03_compute_routes.py):    NESSUN FILTRO. Per scelta progettuale
#                                    (rev. 06/2026) i POI sono SEMPRE quelli
#                                    di tutta Parma, anche fuori San Leonardo.
#                                    Cosi' un edificio puo' agganciarsi al
#                                    POI piu' vicino in assoluto, anche se
#                                    sta in un altro quartiere.
# Mettere QUARTIERE_GPKG = None per disattivare anche il filtro edifici e
# tornare a "tutta Parma" sia per origini che per destinazioni.
# La cache OSM (osm_walk_parma.graphml) NON viene toccata: lasciamo l'intero
# grafo pedonale di Parma cosi' i percorsi che attraversano il bordo del
# quartiere restano corretti.
QUARTIERE_GPKG  = os.path.join(DATA_DIR, "parma_quartiere_san_leonardo.gpkg")
QUARTIERE_LAYER = "quartieri_vigenti_utmrer"
# DEPRECATO: non piu' usato (il filtro POI e' stato rimosso). Lasciato per
# retrocompatibilita' nel caso si voglia reintrodurre il filtro in futuro.
QUARTIERE_BUFFER_POI_M = 0.0

# -----------------------------------------------------------------------------
# CATEGORIE POI
# -----------------------------------------------------------------------------
# Ogni categoria genera 1 file output: output/routes_<categoria>.gpkg
#
# Tipi di "source":
#   - "gpkg_layer": il POI e' un layer dentro SOURCE_GPKG (gia' EPSG:3857)
#   - "csv":       file CSV in data/<nome>.csv con colonne lon,lat (WGS84)
#
# Per i Climate Shelter uso il CSV (al momento solo 2026).

POI_CATEGORIES = [
    # Layer gia' presenti in path_building_to_pois_all_parma.gpkg
    {"name": "cultural",          "source": "gpkg_layer", "layer": "cultural"},
    {"name": "drinking_fountain", "source": "gpkg_layer", "layer": "drinking_fountain"},
    {"name": "education",         "source": "gpkg_layer", "layer": "education"},
    {"name": "entertainment",     "source": "gpkg_layer", "layer": "entertainment"},
    {"name": "health",            "source": "gpkg_layer", "layer": "health"},
    {"name": "mobility",          "source": "gpkg_layer", "layer": "mobility"},
    {"name": "park",              "source": "gpkg_layer", "layer": "park"},

    # CSV (Climate Shelter 2026 - unisce indoor + outdoor)
    {"name": "clim_shel_2026",    "source": "csv", "csv": "clim_shel_2026.csv"},
]

# -----------------------------------------------------------------------------
# OSM
# -----------------------------------------------------------------------------
OSM_GRAPHML_FILE = os.path.join(CACHE_DIR, "osm_walk_parma.graphml")

# Tipo di rete OSM (pedonale: footway, path, residential, ecc.)
OSM_NETWORK_TYPE = "walk"

# Buffer in METRI attorno al bbox degli edifici per garantire copertura ai bordi.
# 500 m e' generoso per una citta' come Parma.
OSM_BUFFER_M = 500.0

# -----------------------------------------------------------------------------
# CRS
# -----------------------------------------------------------------------------
# CRS metrico per Dijkstra (UTM zona 32N copre il Nord Italia con precisione cm)
METRIC_CRS = "EPSG:32632"

# CRS di output GPKG (coerente con dashboard e embed_percorsi.py)
OUTPUT_CRS = "EPSG:3857"

# -----------------------------------------------------------------------------
# DIJKSTRA / SNAP
# -----------------------------------------------------------------------------
# Avviso se un edificio/POI dista piu' di SNAP_WARN_DIST m dal piu' vicino arco OSM
SNAP_WARN_DIST_M = 100.0

# Cutoff opzionale per multi-source Dijkstra (None = nessun limite).
# Se imposti es. 3000, gli edifici che distano > 3 km dal POI piu' vicino non
# avranno un percorso. Per categorie con pochi POI (drinking_fountain in zone
# periferiche) e' meglio lasciare None.
DIJKSTRA_CUTOFF_M = None

# -----------------------------------------------------------------------------
# HELPERS
# -----------------------------------------------------------------------------
def log(msg, prefix="--"):
    """Logging uniforme con timestamp."""
    from datetime import datetime
    print(f"[{datetime.now():%H:%M:%S}] {prefix} {msg}", flush=True)


# -----------------------------------------------------------------------------
# Helper: caricamento poligono quartiere (cache statica)
# -----------------------------------------------------------------------------
_QUART_CACHE = {"loaded": False, "geom_metric": None}

def load_quartiere_polygon():
    """Restituisce la geometria UNIONE del quartiere in CRS METRIC_CRS.

    - Se QUARTIERE_GPKG e' None o il file non esiste, restituisce None
      (la pipeline gira su tutta Parma come prima).
    - La geometria viene cachata in memoria al primo caricamento.
    """
    if _QUART_CACHE["loaded"]:
        return _QUART_CACHE["geom_metric"]

    if QUARTIERE_GPKG is None or not os.path.exists(QUARTIERE_GPKG):
        _QUART_CACHE["loaded"] = True
        _QUART_CACHE["geom_metric"] = None
        return None

    # Import qui per non appesantire l'import di config
    import geopandas as gpd
    from shapely.ops import unary_union

    g = gpd.read_file(QUARTIERE_GPKG, layer=QUARTIERE_LAYER).to_crs(METRIC_CRS)
    poly = unary_union(g.geometry.values)
    _QUART_CACHE["loaded"] = True
    _QUART_CACHE["geom_metric"] = poly
    log(f"Quartiere caricato da {os.path.basename(QUARTIERE_GPKG)} "
        f"(layer={QUARTIERE_LAYER}): bounds={tuple(round(b,1) for b in poly.bounds)}")
    return poly
