export interface Location {
  lat: number;
  lng: number;
  address?: string;
}

export interface DistanceResult {
  distance: number; // in kilometers
  duration: number; // in minutes (estimated)
}

export class GeolocationService {
  /**
   * Calculate distance between two points using Haversine formula
   */
  calculateDistance(point1: Location, point2: Location): DistanceResult {
    const R = 6371; // Earth's radius in kilometers
    const dLat = this.toRad(point2.lat - point1.lat);
    const dLng = this.toRad(point2.lng - point1.lng);
    const a = 
      Math.sin(dLat/2) * Math.sin(dLat/2) +
      Math.cos(this.toRad(point1.lat)) * Math.cos(this.toRad(point2.lat)) * 
      Math.sin(dLng/2) * Math.sin(dLng/2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    const distance = R * c;

    // Estimate duration (assuming average speed in urban area)
    // Speed estimates: walking 5km/h, bike 15km/h, car 30km/h in city
    const estimatedSpeed = 20; // km/h average for delivery
    const duration = (distance / estimatedSpeed) * 60; // in minutes

    return {
      distance: Math.round(distance * 100) / 100, // Round to 2 decimal places
      duration: Math.ceil(duration)
    };
  }

  /**
   * Find nearby points within a given radius
   */
  findNearbyPoints(
    center: Location, 
    points: (Location & { id: string; name?: string })[], 
    radiusKm: number = 10
  ): Array<Location & { id: string; name?: string; distance: number; duration: number }> {
    return points
      .map(point => {
        const result = this.calculateDistance(center, point);
        return {
          ...point,
          distance: result.distance,
          duration: result.duration
        };
      })
      .filter(point => point.distance <= radiusKm)
      .sort((a, b) => a.distance - b.distance);
  }

  /**
   * Check if location is within Abidjan area
   */
  isWithinServiceArea(location: Location): boolean {
    const abidjanBounds = {
      south: 5.2,
      north: 5.5,
      west: -4.2,
      east: -3.8
    };

    return (
      location.lat >= abidjanBounds.south &&
      location.lat <= abidjanBounds.north &&
      location.lng >= abidjanBounds.west &&
      location.lng <= abidjanBounds.east
    );
  }

  /**
   * Get Abidjan center point
   */
  getAbidjanCenter(): Location {
    return {
      lat: 5.3364, // Plateau, Abidjan
      lng: -4.0267
    };
  }

  /**
   * Format distance for display
   */
  formatDistance(distanceKm: number): string {
    if (distanceKm < 1) {
      return `${Math.round(distanceKm * 1000)}m`;
    }
    return `${distanceKm.toFixed(1)}km`;
  }

  /**
   * Format duration for display
   */
  formatDuration(minutes: number): string {
    if (minutes < 60) {
      return `${minutes}min`;
    }
    const hours = Math.floor(minutes / 60);
    const remainingMinutes = minutes % 60;
    return `${hours}h${remainingMinutes > 0 ? remainingMinutes + 'min' : ''}`;
  }

  private toRad(value: number): number {
    return value * Math.PI / 180;
  }
}