export interface MapOptions {
  center: LatLng;
  zoom: number;
  styleUrl: string;
  tileUrl: string;
}
export interface GeoPoint {
  x: number;
  y: number;
}
export interface Zone {
  id: number;
  name?: string;
  color?: string;
  opacity?: number;
  polygon: GeoPoint[];
  shippingFee?: number;
  shippingScheduleStart?: string;
  shippingScheduleEnd?: string;
}
export type LatLng = [number, number];

export function getLngLat(latLng: LatLng): [number, number] {
  return [latLng[1], latLng[0]];
}

export function isPointInPolygon(polygon: LatLng[], point: LatLng): boolean {
  let intersections = 0;
  const x = point[0]; // lat
  const y = point[1]; // lng

  for (let i = 0; i < polygon.length; i++) {
    const nextIndex = (i + 1) % polygon.length;
    const x1 = polygon[i][0]; // lat
    const y1 = polygon[i][1]; // lng
    const x2 = polygon[nextIndex][0]; // lat
    const y2 = polygon[nextIndex][1]; // lng

    if ((y1 > y) !== (y2 > y)) {
      const intersectionX = ((x2 - x1) * (y - y1)) / (y2 - y1) + x1;
      if (x < intersectionX) {
        intersections++;
      }
    }
  }

  return intersections % 2 === 1;
}

export interface RouteLineStyle {
  color?: string;
  opacity?: number;
  weight?: number;
}

export interface RouteOptions {
  serviceUrl?: string;
  profile?: 'driving' | 'walking' | 'cycling';
  lineStyle?: RouteLineStyle;
  showMarkers?: boolean;
  draggableWaypoints?: boolean;
}

export interface IMapAdapter<TMarker = any> {
  init(container: HTMLElement, options: MapOptions): void;
  setCenter(latLng: LatLng): void;
  setZoom(zoom: number): void;

  // Marker management
  addMarker(latLng: LatLng, options?: {id?: string; color?: string; icon?: any}): void;
  getMarker(id: string): TMarker | undefined;
  getAllMarkers(): Record<string, TMarker>;
  removeMarker(id?: string): void;
  hasMarker(id: string): boolean;
  updateMarkerIcon(id: string, icon: any): void;
  updateMarkerPopup(id: string, content: HTMLElement): void;
  addMarkerClickHandler(id: string, handler: (e: any) => void): void;

  // Zone management
  addZone(zone: Zone[]): void;
  updateZone(zone: Zone[]): void;
  openZonePopup(zone: Zone) : void
  closePopup(): void;

  // Route management
  addRoute(id: string, waypoints: LatLng[], options?: RouteOptions): void;
  updateRoute(id: string, waypoints: LatLng[], options?: RouteOptions): void;
  removeRoute(id: string): void;
  removeAllRoutes(): void;

  // Utilities
  destroy(): void;
  on(
    type: string,
    event: (e: any) => void,
  ): void;
}
