"""alpha_shape_concave_hull — Concave hull via Delaunay alpha-shape filtering."""

from __future__ import annotations


def alpha_shape_concave_hull(
    points: list[tuple[float, float]],
    alpha: float,
) -> "shapely.geometry.base.BaseGeometry | None":
    """Compute the alpha-shape (concave hull) of a 2-D point set.

    Performs a Delaunay triangulation over the input points, then keeps only
    those triangles whose circumscribed circle radius is <= alpha. The
    remaining triangles are merged via unary_union.

    Args:
        points: List of (x, y) coordinate pairs. Must have >= 4 elements.
        alpha: Alpha parameter controlling concavity (smaller = more concave).
               Triangles with circumradius > alpha are discarded.

    Returns:
        A shapely geometry (Polygon, MultiPolygon, or GeometryCollection)
        representing the alpha-shape, or None if len(points) < 4 or no
        triangles survive the alpha filter (shapely is required).
    """
    if len(points) < 4:
        return None

    try:
        import numpy as np
        from shapely.geometry import MultiPoint
        from shapely.ops import triangulate, unary_union
    except ImportError:
        return None

    mp = MultiPoint(points)
    triangles = triangulate(mp)

    valid = []
    for tri in triangles:
        coords = list(tri.exterior.coords)
        a_pt = np.array(coords[0])
        b_pt = np.array(coords[1])
        c_pt = np.array(coords[2])

        # Circumradius via the formula R = (abc) / (4 * Area)
        ab = np.linalg.norm(b_pt - a_pt)
        bc = np.linalg.norm(c_pt - b_pt)
        ca = np.linalg.norm(a_pt - c_pt)

        # Area via cross product
        area = abs(
            (b_pt[0] - a_pt[0]) * (c_pt[1] - a_pt[1])
            - (c_pt[0] - a_pt[0]) * (b_pt[1] - a_pt[1])
        ) / 2.0

        if area == 0:
            continue

        circumradius = (ab * bc * ca) / (4.0 * area)
        if circumradius <= alpha:
            valid.append(tri)

    if not valid:
        return None

    return unary_union(valid)
