/**
 * Nominatim Geocoding API Service
 * Provides address search and autocomplete functionality
 */

import apiClient from '../client';

export interface NominatimResult {
  place_id: number;
  lat: string;
  lon: string;
  display_name: string;
  address: {
    road?: string;
    house_number?: string;
    city?: string;
    town?: string;
    village?: string;
    municipality?: string;
    postcode?: string;
    country?: string;
  };
  boundingbox: [string, string, string, string];
}

export interface NominatimSearchParams {
  q: string;
  format?: 'json';
  addressdetails?: 1 | 0;
  limit?: number;
  countrycodes?: string;
}

class NominatimService {
  private baseUrl = '/api/v1/nominatim';

  /**
   * Search for addresses matching a query
   */
  async searchAddress(query: string, limit: number = 5): Promise<NominatimResult[]> {
    if (!query || query.length < 3) {
      return [];
    }

    try {
      return await apiClient.get<NominatimResult[]>(`${this.baseUrl}/search`, {
        params: {
          q: query,
          format: 'json',
          addressdetails: 1,
          limit,
          countrycodes: 'es', // Spain only
        },
      });
    } catch (error) {
      console.error('Address search failed:', error);
      return [];
    }
  }

  /**
   * Format a Nominatim result for display
   */
  formatAddress(result: NominatimResult): string {
    return result.display_name;
  }

  /**
   * Extract structured address components
   */
  parseAddress(result: NominatimResult) {
    const { address } = result;

    return {
      street: address.road
        ? `${address.road}${address.house_number ? ' ' + address.house_number : ''}`
        : '',
      city: address.city || address.town || address.village || address.municipality || '',
      postalCode: address.postcode || '',
      latitude: parseFloat(result.lat),
      longitude: parseFloat(result.lon),
      displayName: result.display_name,
    };
  }

  /**
   * Geocode a structured address to coordinates
   */
  async geocodeAddress(
    street: string,
    city: string,
    postalCode?: string
  ): Promise<NominatimResult | null> {
    const parts = [street, city];
    if (postalCode) parts.push(postalCode);
    parts.push('Spain');

    const query = parts.join(', ');
    const results = await this.searchAddress(query, 1);

    return results.length > 0 ? results[0] : null;
  }
}

export const nominatimService = new NominatimService();
export default nominatimService;
