/**
 * Conversión de geometría GeoJSON a coordenadas de react-native-maps.
 * GeoJSON usa [lng, lat]; react-native-maps usa { latitude, longitude }.
 */
export interface LatLng {
  latitude: number;
  longitude: number;
}

export interface ShapeSet {
  points: LatLng[];
  lines: LatLng[][];
  polygons: LatLng[][];
}

function toLatLng(pos: unknown): LatLng | null {
  if (Array.isArray(pos) && pos.length >= 2 && typeof pos[0] === 'number' && typeof pos[1] === 'number') {
    return { longitude: pos[0], latitude: pos[1] };
  }
  return null;
}

function ring(coords: unknown): LatLng[] {
  if (!Array.isArray(coords)) return [];
  return coords.map(toLatLng).filter((c): c is LatLng => c !== null);
}

/** Aplana una geometría GeoJSON a conjuntos de puntos/líneas/polígonos. */
export function geometryToShapes(geometry: unknown): ShapeSet {
  const out: ShapeSet = { points: [], lines: [], polygons: [] };
  const g = geometry as { type?: string; coordinates?: unknown } | null;
  if (!g || !g.type) return out;

  switch (g.type) {
    case 'Point': {
      const p = toLatLng(g.coordinates);
      if (p) out.points.push(p);
      break;
    }
    case 'MultiPoint':
      out.points.push(...ring(g.coordinates));
      break;
    case 'LineString':
      out.lines.push(ring(g.coordinates));
      break;
    case 'MultiLineString':
      if (Array.isArray(g.coordinates)) g.coordinates.forEach((l) => out.lines.push(ring(l)));
      break;
    case 'Polygon':
      // Solo el anillo exterior (índice 0).
      if (Array.isArray(g.coordinates) && g.coordinates[0]) out.polygons.push(ring(g.coordinates[0]));
      break;
    case 'MultiPolygon':
      if (Array.isArray(g.coordinates)) {
        g.coordinates.forEach((poly) => {
          if (Array.isArray(poly) && poly[0]) out.polygons.push(ring(poly[0]));
        });
      }
      break;
    default:
      break;
  }
  return out;
}

/** Calcula una región que englobe todas las coordenadas (para el encuadre inicial). */
export function regionFor(all: LatLng[]): {
  latitude: number;
  longitude: number;
  latitudeDelta: number;
  longitudeDelta: number;
} | null {
  if (all.length === 0) return null;
  let minLat = all[0].latitude;
  let maxLat = all[0].latitude;
  let minLng = all[0].longitude;
  let maxLng = all[0].longitude;
  for (const c of all) {
    minLat = Math.min(minLat, c.latitude);
    maxLat = Math.max(maxLat, c.latitude);
    minLng = Math.min(minLng, c.longitude);
    maxLng = Math.max(maxLng, c.longitude);
  }
  const latitudeDelta = Math.max((maxLat - minLat) * 1.4, 0.01);
  const longitudeDelta = Math.max((maxLng - minLng) * 1.4, 0.01);
  return {
    latitude: (minLat + maxLat) / 2,
    longitude: (minLng + maxLng) / 2,
    latitudeDelta,
    longitudeDelta,
  };
}
