"""
Dissolve UWB-Wahlbezirke zu Briefwahlbezirken (BWB).
Benötigt: pip install geopandas

Ausführen: python dissolve_bwb.py
"""
import json
import geopandas as gpd
from shapely.geometry import Polygon, MultiPolygon
from pathlib import Path

base = Path(__file__).parent.parent

# Einlesen
uwb = gpd.read_file(base / "data" / "wahlbezirke.geojson")

# In UTM Zone 33N umprojizieren für metrisch korrekten Buffer
uwb = uwb.set_crs("EPSG:4326").to_crs("EPSG:25833")

# Geometrien reparieren + Buffer schließt kleine Lücken
uwb["geometry"] = uwb["geometry"].buffer(1.5).buffer(-1.5)

# UWBs pro BWB sammeln (für die Properties)
bwb_uwbs = uwb.groupby("BWB")["UWB"].apply(sorted).to_dict()

# Dissolve nach BWB, BEZ und AWK beibehalten (sind innerhalb BWB eindeutig)
bwb = uwb.dissolve(by="BWB", as_index=False)[["BWB", "BEZ", "AWK", "geometry"]]
bwb = bwb.sort_values("BWB").reset_index(drop=True)

# UWBs-Liste als Property anhängen
bwb["UWBs"] = bwb["BWB"].map(bwb_uwbs)

# Geometrien vereinfachen
bwb["geometry"] = bwb["geometry"].simplify(2, preserve_topology=True)

# Zurück nach WGS84
bwb = bwb.to_crs("EPSG:4326")

# Löcher entfernen
def remove_holes(geom):
    if geom.geom_type == "Polygon":
        return Polygon(geom.exterior)
    elif geom.geom_type == "MultiPolygon":
        return MultiPolygon([Polygon(p.exterior) for p in geom.geoms])
    return geom

bwb["geometry"] = bwb["geometry"].apply(remove_holes)

# Als GeoJSON speichern (UWBs-Liste manuell einbauen, da geopandas Listen-Properties manchmal serialisiert)
gdf_dict = json.loads(bwb.to_json())
for feat in gdf_dict["features"]:
    bwb_code = feat["properties"]["BWB"]
    feat["properties"]["UWBs"] = list(bwb_uwbs[bwb_code])

out = base / "data" / "briefwahlbezirke.geojson"
with open(out, "w", encoding="utf-8") as f:
    json.dump(gdf_dict, f, ensure_ascii=False, separators=(",", ":"))

print(f"Gespeichert: {out}  ({len(bwb)} Features)")
print(f"Enthaltene UWBs: {sum(len(v) for v in bwb_uwbs.values())}")
