"""
Pregătire geometrii administrative — conversie din diverse formate
în GeoParquet optimizat pentru Data Hub.
"""
import os
from pathlib import Path

import geopandas as gpd
from rich.console import Console

console = Console()

# Mapping nivel → fișiere sursă (naming convention din administrative_boundaries)
LEVEL_FILES = {
    "region": {
        "full": "ro_admin_region_polygon.parquet",
        "simplified": "ro_admin_region_simplified_polygon.parquet",
    },
    "county": {
        "full": "ro_admin_county_polygon.parquet",
        "simplified": "ro_admin_county_simplified_polygon.parquet",
    },
    "lau": {
        "full": "ro_admin_lau_polygon.parquet",
        "simplified": "ro_admin_lau_simplified_polygon.parquet",
    },
}


def prepare_geometry(
    source_path: str,
    level: str,
    output_path: str,
    create_simplified: bool = False,
):
    """
    Citește un fișier de geometrii și îl salvează ca GeoParquet optimizat.
    """
    console.print(f"[blue]Citire:[/blue] {source_path}")

    # Detect format and read
    ext = Path(source_path).suffix.lower()
    if ext == ".parquet":
        gdf = gpd.read_parquet(source_path)
    elif ext == ".gpkg":
        gdf = gpd.read_file(source_path)
    elif ext in (".geojson", ".json"):
        gdf = gpd.read_file(source_path)
    elif ext == ".fgb":
        gdf = gpd.read_file(source_path)
    else:
        raise ValueError(f"Format nesuportat: {ext}")

    console.print(f"  → {len(gdf)} entități, CRS: {gdf.crs}")

    # Ensure EPSG:4326
    if gdf.crs and gdf.crs.to_epsg() != 4326:
        console.print(f"  → Reproiectare la EPSG:4326...")
        gdf = gdf.to_crs(epsg=4326)

    # Ensure natcode column exists (standardize join key)
    if "natcode" not in gdf.columns:
        # Try common alternatives
        for alt in ["NATCODE", "NatCode", "code", "CODE", "id", "ID"]:
            if alt in gdf.columns:
                gdf["natcode"] = gdf[alt]
                console.print(f"  → Coloana '{alt}' copiată în 'natcode'")
                break

    # Ensure name column exists
    if "name" not in gdf.columns:
        for alt in ["Name", "NAME", "DENUMIRE", "denumire", "Denumire"]:
            if alt in gdf.columns:
                gdf["name"] = gdf[alt]
                console.print(f"  → Coloana '{alt}' copiată în 'name'")
                break

    # Save as GeoParquet
    os.makedirs(os.path.dirname(output_path), exist_ok=True)
    gdf.to_parquet(output_path, index=False)
    file_size = os.path.getsize(output_path)
    console.print(
        f"[green]✓[/green] Salvat: {output_path} ({file_size / 1024 / 1024:.1f} MB)"
    )


def prepare_all_geometries(base_dir: str, output_dir: str):
    """
    Pregătește toate geometriile din directorul administrative_boundaries.
    """
    base = Path(base_dir)
    out = Path(output_dir)
    os.makedirs(out, exist_ok=True)

    for level, files in LEVEL_FILES.items():
        console.print(f"\n[bold cyan]═══ {level.upper()} ═══[/bold cyan]")

        # Full resolution
        full_src = base / level / files["full"]
        if full_src.exists():
            prepare_geometry(
                str(full_src),
                level,
                str(out / f"{level}.parquet"),
            )
        else:
            console.print(f"[yellow]⚠ Nu s-a găsit:[/yellow] {full_src}")

        # Simplified
        simp_src = base / level / files["simplified"]
        if simp_src.exists():
            prepare_geometry(
                str(simp_src),
                level,
                str(out / f"{level}_simplified.parquet"),
            )
        else:
            console.print(f"[yellow]⚠ Nu s-a găsit:[/yellow] {simp_src}")
