import alphashape
import geopandas as gpd
from shapely.geometry import Polygon

from ..plotting import subplots, show

def concave_hull(coords, alpha, plot=True):
    """
    Generate a concave hull (alphashape) from a set of coordinates.
    Parameters:
    - coords: List of (x, y) tuples representing the points.
    - alpha: Alpha parameter controlling the concavity. Smaller values result in a more detailed hull, while larger values produce a more convex hull.
    - plot: Boolean indicating whether to display the plot of the hull.
    Returns:
    - A shapely geometry representing the concave hull.
    """
    hull = alphashape.alphashape(coords, alpha)
    if plot:
        hull_gdf = gpd.GeoDataFrame(geometry=[hull])
        fig, ax = subplots(figwidth=10, figheight=10)
        ax.scatter(
            [x for x, y in coords],
            [y for x, y in coords],
            s=1, color="steelblue", alpha=0.5, zorder=1
        )

        # Alphashape
        hull_gdf.plot(ax=ax, facecolor="none", edgecolor="crimson", linewidth=2, linestyle="--", zorder=2)
        show()

    return hull


def bbox2shp(xmin, xmax, ymin, ymax, output_fname, epsg=4326):
    """
    Create a shapefile representing a bounding box.
    Parameters:
    - xmin, xmax, ymin, ymax: Coordinates defining the bounding box.
    - output_fname: Path to the output shapefile.
    """
    bbox = Polygon([
        (xmin, ymin),
        (xmin, ymax),
        (xmax, ymax),
        (xmax, ymin),
        (xmin, ymin)
    ])
    gdf = gpd.GeoDataFrame(geometry=[bbox], crs=f"EPSG:{epsg}")
    gdf.to_file(output_fname)