# 3rd party lib
from shapely import buffer
from shapely.geometry import Polygon, MultiPolygon

# Local lib
from ..beams import BeamType
from ..mill import Mill


def contour(shape: Polygon | MultiPolygon, mill: Mill, beam: BeamType) -> list:
    """Generates a scan path consisting of shrinkingcontours from edges to center."""

    beam_radius = beam.get_radius(units="nm")
    overlap = mill.get_overlap()
    step = 2 * beam_radius * (1 - overlap)

    contours = []

    def add_linestrings(geometry):
        if isinstance(geometry, Polygon):
            if not geometry.exterior.is_empty:
                contours.append(geometry.exterior)
            for interior in geometry.interiors:
                contours.append(interior)
        elif isinstance(geometry, MultiPolygon):
            for polygon in geometry.geoms:
                if not polygon.exterior.is_empty:
                    contours.append(polygon.exterior)
                for interior in polygon.interiors:
                    contours.append(interior)

    k = 0
    while True:
        current_offset = -beam_radius - k * step
        if k == 0:
            buffered = buffer(shape, current_offset, join_style="mitre")
        else:
            buffered = buffer(shape, current_offset, join_style="round", quad_segs=100)
        if buffered.is_empty:
            break
        add_linestrings(buffered)
        k += 1

    return contours


