import { kinks, unkinkPolygon } from '@turf/turf'
import type { Feature, Geometry, Polygon } from 'geojson'
import type { LassoToolsStore } from './provider/types'

export function getMaskValues({
  values,
}: {
  values?: LassoToolsStore['data'][number]['values']
}) {
  return Object.values(values ?? {}).filter((value) => value.type === 'mask')
}

/**
 * All lasso geometries (mask + draw). Used to feed the editable layer so draw
 * geometries render alongside masks; the GPU mask layer keeps using
 * {@link getMaskValues} so only `mask` geometries clip the data layers.
 */
export function getAllValues({
  values,
}: {
  values?: LassoToolsStore['data'][number]['values']
}) {
  return Object.values(values ?? {})
}

export interface RepairSelfIntersectionResult {
  geometry: Geometry
  repaired: boolean
}

/**
 * Detects self-intersections in a polygon (turf `kinks`) and, if found,
 * repairs it by splitting into simple polygons (turf `unkinkPolygon`) and
 * recombining them into a single `Polygon`/`MultiPolygon`. Non-polygon
 * geometries (e.g. lines, points) are returned unchanged.
 */
export function repairSelfIntersection(
  geometry: Geometry,
): RepairSelfIntersectionResult {
  if (geometry.type !== 'Polygon') {
    return { geometry, repaired: false }
  }

  const feature: Feature<Polygon> = {
    type: 'Feature',
    geometry,
    properties: {},
  }

  if (kinks(feature).features.length === 0) {
    return { geometry, repaired: false }
  }

  const coordinates = unkinkPolygon(feature).features.map(
    (f) => f.geometry.coordinates,
  )

  return {
    geometry:
      coordinates.length > 1
        ? { type: 'MultiPolygon', coordinates }
        : { type: 'Polygon', coordinates: coordinates[0]! },
    repaired: true,
  }
}
