import * as turf from '@turf/turf';
import { Feature, MultiPolygon, Polygon } from 'geojson';
import { decode, encode } from "@googlemaps/polyline-codec";
import IGCParser, { IGCFile } from 'igc-parser';
import { simplify } from './douglaspeucker';

/*
const arrvol = [
  { lat: 45.5, lon: 5.5 },
  { lat: 45.6, lon: 5.7 },
  { lat: 45.7, lon: 5.9 }
];

// conversion en GeoJSON LineString
const line = turf.lineString(
  arrvol.map(p => [p.lon, p.lat])
);

// buffer en kilomètres (ex: 2 km)
const buffered = turf.buffer(line, 2, { units: 'kilometers' });

console.log(buffered);
if (buffered) {
  const encoded = encodePolygon(buffered);
  console.log(encoded);
  const decoded = decodePolygon(encoded);
  console.log(decoded);
}
*/

function loadIGC(fileContent: string): IGCFile | null {
  let result = IGCParser.parse(fileContent, { lenient: true });
  if (result.errors.length > 0) {
    console.error("Errors while parsing IGC file:", result.errors);
    return null;
  }
  return result;
}

function simplifyIGC(igcfile: IGCFile, dpepsilon: number=0.018): { lat: number; lon: number }[] {
  const s = simplify(igcfile.fixes.map(pt => pt.longitude), igcfile.fixes.map(pt => pt.latitude), dpepsilon);
  return s[0].reduce((acc:{ lat: number; lon: number }[], cur:number, i:number) => {acc.push({ lat: s[1][i], lon: cur }); return acc}, []);
}

function getPolygon(coordinates: { lat: number; lon: number }[], distance: number=1.8, steps: number=1) {
  const line = turf.lineString(
    coordinates.map(p => [p.lon, p.lat])
  );
  const buffered = turf.buffer(line, distance, { units: 'kilometers', steps: steps });
  return buffered;
}

function intersect(poly1: Feature<Polygon | MultiPolygon>, poly2: Feature<Polygon | MultiPolygon>) {
  return turf.intersect(turf.featureCollection([poly1, poly2]));
}

function encodePolygon(polygon: Feature<Polygon | MultiPolygon>) {
  const coordinates = polygon.geometry.type === 'Polygon' ? polygon.geometry.coordinates : polygon.geometry.coordinates[0];
  return coordinates.map(c => {
    return encode(c.map(coord => [coord[1], coord[0] ]), 5); // Inverser les coordonnées pour l'encodage
  }).join('¤'); // Utiliser un séparateur pour différencier les anneaux du polygone
}

function decodePolygon(encoded: string) {
  const coordinates = encoded.split('¤').map(ring => {
    return decode(ring, 5).map(coord => [coord[1], coord[0]]); // Inverser les coordonnées
  });
  return turf.polygon(coordinates);
}

export default { loadIGC, simplifyIGC, getPolygon, intersect, encodePolygon, decodePolygon };
