import geopandas as gpd
import pandas as pd


def _dms_to_decimal(dms: pd.Series) -> pd.Series:
    """Convert DMS strings like '48-36-00.360N' or '124-53-59.640W' to decimal degrees.

    Format: DD-MM-SS.SSSH where H is N/S/E/W. Southern/Western hemispheres become negative.
    """
    # Split into 4 columns: degrees, minutes, seconds+hemisphere
    parts = dms.str.extract(r"^(\d+)-(\d+)-([\d.]+)([NSEW])$")
    parts.columns = ["d", "m", "s", "h"]

    decimal = parts["d"].astype(float) + parts["m"].astype(float) / 60 + parts["s"].astype(float) / 3600
    # Flip sign for southern/western hemispheres
    decimal = decimal.where(parts["h"].isin(["N", "E"]), -decimal)
    return decimal


def parse_file(
    path: str,
    parse_contributor: bool = False,
    crs: str = "EPSG:4326",
) -> gpd.GeoDataFrame:
    """Read a NONNA-10 bathymetry file into a GeoDataFrame.

    The file is tab-separated with columns: Lat (DMS), Long (DMS), Depth (m), Contributor.
    The contributor field is pipe-separated (source|version|?|start_date|end_date).

    Parameters
    ----------
    path : str
        Path to the NONNA-10 .txt file.
    parse_contributor : bool, default True
        If True, split the Contributor field into its 5 sub-fields.
    crs : str, default "EPSG:4326"
        CRS to assign. NONNA-10 coordinates are WGS84.

    Returns
    -------
    geopandas.GeoDataFrame
        Point geometries with columns: depth_m, lat, lon, and (optionally) contributor fields.
    """
    df = pd.read_csv(path, sep="\t", dtype=str)  # read as strings, parse numerics ourselves

    # Normalize column names (file uses 'Lat (DMS)', 'Long (DMS)', etc.)
    df.columns = [c.strip() for c in df.columns]

    lat = _dms_to_decimal(df["Lat (DMS)"])
    lon = _dms_to_decimal(df["Long (DMS)"])
    depth = df["Depth (m)"].astype(float)

    out = pd.DataFrame({"lat": lat, "lon": lon, "depth_m": depth})

    if parse_contributor and "Contributor" in df.columns:
        contrib = df["Contributor"].str.split("|", expand=True)
        # NONNA-10 contributor: source_id | version | ? | start_date (YYYYMMDD) | end_date (YYYYMMDD)
        names = ["source_id", "version", "flag", "start_date", "end_date"]
        for i, name in enumerate(names[: contrib.shape[1]]):
            out[name] = contrib[i]

    gdf = gpd.GeoDataFrame(
        out,
        geometry=gpd.points_from_xy(out["lon"], out["lat"]),
        crs=crs,
    )
    return gdf


if __name__ == "__main__":
    import sys

    gdf = read_nonna10(sys.argv[1])
    print(gdf.head())
    print(f"\n{len(gdf):,} points")
    print(f"Bounds: {gdf.total_bounds}")
    print(f"Depth range: {gdf['depth_m'].min():.2f} to {gdf['depth_m'].max():.2f} m")