import * as turf from '@turf/turf';
import { Feature } from '@turf/turf';
import { ItemSeries, RegionData } from '../types/map';

export const findRegionInDataset = (dataset: RegionData, point: turf.helpers.Position | turf.helpers.Point | turf.helpers.Feature<turf.helpers.Point, turf.helpers.Properties>): Feature | undefined => {
  return dataset.features.find((region: any) => {
    const coordinates = region?.geometry?.coordinates;
    const type = region?.geometry?.type;

    if (!Array.isArray(coordinates) || coordinates.length === 0) {
      return false;
    }

    try {
      const polygon: any = type === 'Polygon'
        ? turf.polygon(coordinates)
        : turf.multiPolygon(coordinates);

      return turf.booleanPointInPolygon(point, polygon);
    } catch (error) {
      console.error('Error creating polygon:', error);
      return false;
    }
  });
};

export const calculateMapRegion = (bounds: turf.BBox): any => {
  const padding = 1;
  return {
    latitude: (bounds[1] + bounds[3]) / 2,
    longitude: (bounds[0] + bounds[2]) / 2,
    latitudeDelta: Math.abs(bounds[3] - bounds[1]) + padding,
    longitudeDelta: Math.abs(bounds[2] - bounds[0]) + padding,
  };
};

const isBBoxOverlap = (bbox1: number[], bbox2: number[]) => {
  return bbox1[0] <= bbox2[2] &&
         bbox1[2] >= bbox2[0] &&
         bbox1[1] <= bbox2[3] &&
         bbox1[3] >= bbox2[1];
};

export const filterCandidates = (candidates: { features?: any; }, areaPolygon: turf.BBox) => {
  const visibleAreaPolygon = turf.bboxPolygon(areaPolygon);

  const candidateRegions = candidates.features.filter((feature: any) => {
    const featureBBox = turf.bbox(feature);
    return isBBoxOverlap(featureBBox, areaPolygon);
  });

  return candidateRegions.filter((feature: turf.helpers.Geometry | turf.helpers.Feature<any, turf.helpers.Properties>) => {
    return turf.booleanIntersects(feature, visibleAreaPolygon) || 
    turf.booleanOverlap(feature, visibleAreaPolygon);
  });
};

export const processMarkerData = (marker: ItemSeries) => {
  let coordinates = null;
  if (marker.pointJSON) {
    coordinates = JSON.parse(marker.pointJSON);
  }
  else if (marker.polygonJSON) {
    const polygon = JSON.parse(marker.polygonJSON);
    const polygonFeature = turf.polygon(polygon);
    const center = turf.center(polygonFeature);
    coordinates = center.geometry.coordinates;
  }
  return {
    ...marker,
    pointJSON: coordinates ?? null,
  };
};

export const processIconUrl = (url: string) => {
  let processedUrl = url.startsWith('/static') ? url.substring(7) : url;

  if (processedUrl.endsWith('.png.png')) {
    processedUrl = processedUrl.substring(0, processedUrl.length - 4);
  }

  return `https://nomadmania.eu${processedUrl}`;
};

export const filterCandidatesMarkers = (candidatesMarkers: any[], visibleAreaPolygon: turf.helpers.Geometry | turf.helpers.Feature<any, turf.helpers.Properties>) => (
  candidatesMarkers.filter((marker: { pointJSON: string; polygonJSON: string; }) => {
    if (marker.pointJSON) {
      const coordinates = JSON.parse(marker.pointJSON);
      const point = turf.point([coordinates[1], coordinates[0]]);
      return turf.booleanPointInPolygon(point, visibleAreaPolygon);
    }
    
    else if (marker.polygonJSON) {
      const polygonCoords = JSON.parse(marker.polygonJSON);
      const polygon = turf.polygon(polygonCoords);
      return turf.booleanOverlap(polygon, visibleAreaPolygon) || 
            turf.booleanContains(visibleAreaPolygon, polygon) ||
            turf.booleanWithin(polygon, visibleAreaPolygon);
    }
    
    return false;
  }
));
