import type { GeoJsonPolygon } from "./api-types";

/** Shoelace formula — approximate polygon area in hectares (WGS84, local flat). */
export function polygonAreaHa(geoJson: GeoJsonPolygon): number | null {
  const ring = geoJson.coordinates?.[0];
  if (!ring || ring.length < 4) return null;

  const lat0 =
    ring.reduce((sum, c) => sum + (c[1] ?? 0), 0) / ring.length;
  const mPerDegLat = 111_320;
  const mPerDegLng = 111_320 * Math.cos((lat0 * Math.PI) / 180);

  let areaM2 = 0;
  for (let i = 0; i < ring.length - 1; i++) {
    const [lng1, lat1] = ring[i]!;
    const [lng2, lat2] = ring[i + 1]!;
    const x1 = lng1 * mPerDegLng;
    const y1 = lat1 * mPerDegLat;
    const x2 = lng2 * mPerDegLng;
    const y2 = lat2 * mPerDegLat;
    areaM2 += x1 * y2 - x2 * y1;
  }
  return Math.abs(areaM2) / 2 / 10_000;
}

export function parseGeoJsonPolygon(raw: string): GeoJsonPolygon | null {
  try {
    const parsed = JSON.parse(raw) as { type?: string; coordinates?: number[][][] };
    if (parsed.type === "Polygon" && Array.isArray(parsed.coordinates)) {
      return { type: "Polygon", coordinates: parsed.coordinates };
    }
    return null;
  } catch {
    return null;
  }
}

/** Build a closed ring from "lat,lng" pairs (one per line). */
export function coordinatePairsToPolygon(pairs: string): GeoJsonPolygon | null {
  const ring: number[][] = [];
  for (const line of pairs.split("\n")) {
    const trimmed = line.trim();
    if (!trimmed) continue;
    const parts = trimmed.split(/[,\s]+/).map(Number);
    if (parts.length < 2 || parts.some((n) => Number.isNaN(n))) continue;
    const [lat, lng] = parts;
    ring.push([lng!, lat!]);
  }
  if (ring.length < 3) return null;
  const first = ring[0]!;
  const last = ring[ring.length - 1]!;
  if (first[0] !== last[0] || first[1] !== last[1]) {
    ring.push([...first]);
  }
  return { type: "Polygon", coordinates: [ring] };
}
