"""Geometry extraction utilities."""

from __future__ import annotations

from qgis.core import QgsGeometry, QgsPointXY, QgsWkbTypes
from qgis.PyQt.QtCore import QCoreApplication


def extract_all_vertices(geometry: QgsGeometry) -> list[QgsPointXY]:
    """Extract all vertices from any QGIS geometry type.

    Args:
        geometry: The input QGIS geometry.

    Returns:
        A flat list of all vertices found in the geometry.

    """
    if not geometry or geometry.isNull():
        return []

    return [QgsPointXY(v) for v in geometry.vertices()]


def get_line_vertices(geometry: QgsGeometry) -> list[QgsPointXY]:
    """Extract vertices specifically from a line or multiline geometry.

    Args:
        geometry: A QGIS geometry of type `LineGeometry`.

    Returns:
        A flat list of vertices.

    Raises:
        ValueError: If the geometry is null, not a line, or contains no vertices.

    """
    if not geometry or geometry.isNull():
        raise ValueError(
            QCoreApplication.translate("GeometryExtraction", "Geometry is null or invalid")
        )

    if geometry.type() != QgsWkbTypes.LineGeometry:
        raise ValueError(f"Expected LineGeometry, got {geometry.type()}")

    vertices = extract_all_vertices(geometry)
    if not vertices:
        raise ValueError(
            QCoreApplication.translate("GeometryExtraction", "Line geometry has no vertices")
        )

    return vertices


def extract_lines_from_geometry(geometry: QgsGeometry) -> list[QgsGeometry]:
    """Extract individual LineString geometries from a (possibly Multi) geometry.

    If the input is a MultiLineString, it decomposes it into its constituent
    parts. If it's a single LineString, it returns it in a list.

    Args:
        geometry: Input geometry (LineString or MultiLineString).

    """
    geometries: list[QgsGeometry] = []
    if not geometry or geometry.isNull():
        return geometries

    # MultiLineString handling
    if geometry.isMultipart():
        for part in geometry.asGeometryCollection():
            geometries.append(QgsGeometry(part))
    else:
        geometries.append(QgsGeometry(geometry))
    return geometries
