// src/services/googleGeocodingService.server.ts
import type { Logger } from 'pino';
import { logger as defaultLogger } from './logger.server';

export class GoogleGeocodingService {
  private readonly baseUrl = 'https://maps.googleapis.com/maps/api/geocode/json';

  /**
   * Geocodes an address using the Google Maps Geocoding API.
   * @param address The address string to geocode.
   * @param logger A logger instance.
   * @returns A promise that resolves to the coordinates or null if not found.
   */
  async geocode(address: string, logger: Logger = defaultLogger): Promise<{ lat: number; lng: number } | null> {
    const apiKey = process.env.GOOGLE_MAPS_API_KEY;
    if (!apiKey) {
      logger.error('[GoogleGeocodingService] API key is missing.');
      throw new Error('GOOGLE_MAPS_API_KEY is not set.');
    }

    const url = `${this.baseUrl}?address=${encodeURIComponent(address)}&key=${apiKey}`;

    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`Google Maps API returned status ${response.status}`);
      }

      const data = await response.json();
      if (data.status === 'OK' && data.results.length > 0) {
        logger.info({ address, result: data.results[0].geometry.location }, `[GoogleGeocodingService] Successfully geocoded address`);
        return data.results[0].geometry.location;
      }

      logger.warn({ address, status: data.status }, '[GoogleGeocodingService] Geocoding failed or returned no results.');
      return null;
    } catch (error) {
      logger.error({ err: error, address }, '[GoogleGeocodingService] An error occurred while calling the Google Maps API.');
      throw error; // Re-throw to allow the calling service to handle the failure (e.g., by falling back).
    }
  }
}

export const googleGeocodingService = new GoogleGeocodingService();