/**
 * Geocoding API Client
 *
 * Provides address search, autocomplete, and geocoding functionality
 * using the backend Nominatim service.
 */

import { apiClient } from '../../api/client/apiClient';

const GEOCODING_BASE_URL = '/geocoding';

export interface AddressResult {
  display_name: string;
  lat: number;
  lon: number;
  osm_type: string;
  osm_id: number;
  place_id: number;
  type: string;
  class: string;
  address: {
    road?: string;
    house_number?: string;
    suburb?: string;
    city?: string;
    municipality?: string;
    state?: string;
    postcode?: string;
    country?: string;
    country_code?: string;
  };
  boundingbox: string[];
}

export interface GeocodeResult {
  display_name: string;
  lat: number;
  lon: number;
  address: {
    road?: string;
    house_number?: string;
    suburb?: string;
    city?: string;
    municipality?: string;
    state?: string;
    postcode?: string;
    country?: string;
    country_code?: string;
  };
}

export interface CoordinateValidation {
  valid: boolean;
  address?: string;
}

export const geocodingApi = {
  /**
   * Search for addresses matching query (autocomplete)
   *
   * @param query - Search query (minimum 3 characters)
   * @param countryCode - ISO country code (default: 'es')
   * @param limit - Maximum number of results (default: 10)
   */
  async searchAddresses(
    query: string,
    countryCode: string = 'es',
    limit: number = 10
  ): Promise<AddressResult[]> {
    if (!query || query.trim().length < 3) {
      return [];
    }

    const response = await apiClient.get<AddressResult[]>(
      `${GEOCODING_BASE_URL}/search`,
      {
        params: {
          q: query,
          country_code: countryCode,
          limit
        }
      }
    );

    return response;
  },

  /**
   * Geocode an address to get coordinates
   *
   * @param address - Full address string
   * @param countryCode - ISO country code (default: 'es')
   */
  async geocodeAddress(
    address: string,
    countryCode: string = 'es'
  ): Promise<GeocodeResult> {
    const response = await apiClient.get<GeocodeResult>(
      `${GEOCODING_BASE_URL}/geocode`,
      {
        params: {
          address,
          country_code: countryCode
        }
      }
    );

    return response;
  },

  /**
   * Reverse geocode coordinates to get address
   *
   * @param lat - Latitude
   * @param lon - Longitude
   */
  async reverseGeocode(
    lat: number,
    lon: number
  ): Promise<GeocodeResult> {
    const response = await apiClient.get<GeocodeResult>(
      `${GEOCODING_BASE_URL}/reverse`,
      {
        params: { lat, lon }
      }
    );

    return response;
  },

  /**
   * Validate coordinates
   *
   * @param lat - Latitude
   * @param lon - Longitude
   */
  async validateCoordinates(
    lat: number,
    lon: number
  ): Promise<CoordinateValidation> {
    const response = await apiClient.get<CoordinateValidation>(
      `${GEOCODING_BASE_URL}/validate`,
      {
        params: { lat, lon }
      }
    );

    return response;
  },

  /**
   * Check geocoding service health
   */
  async checkHealth(): Promise<{
    status: string;
    service: string;
    base_url: string;
    is_public_api: boolean;
  }> {
    const response = await apiClient.get(`${GEOCODING_BASE_URL}/health`);
    return response;
  }
};
