// Mapbox Geocoding Service
// Docs: https://docs.mapbox.com/api/search/geocoding/

export interface MapboxFeature {
  id: string;
  place_name: string;
  center: [number, number]; // [longitude, latitude]
  geometry: {
    coordinates: [number, number];
  };
  context?: Array<{
    id: string;
    text: string;
    short_code?: string;
  }>;
  place_type: string[];
  text: string;
  address?: string;
}

export interface MapboxResult {
  description: string;
  street: string;
  number: string;
  city: string;
  state: string;
  zip: string;
  lat: number;
  lng: number;
  mapLink: string;
}

// Token do Mapbox configurado no arquivo .env.local
const MAPBOX_TOKEN = import.meta.env.VITE_MAPBOX_TOKEN || "";

/**
 * Busca endereços usando a API de Geocoding do Mapbox
 * @param query - Texto de busca (endereço, local, etc)
 * @param country - Código do país (ex: 'br' para Brasil)
 */
export async function searchMapboxLocation(
  query: string,
  country: string = "br"
): Promise<MapboxResult[]> {
  if (!MAPBOX_TOKEN || MAPBOX_TOKEN.startsWith("YOUR_")) {
    console.warn(
      "⚠️ Mapbox Token não configurado. Configure em services/mapboxService.ts"
    );
    return [];
  }

  try {
    const encodedQuery = encodeURIComponent(query);
    let url =
      `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodedQuery}.json?` +
      `access_token=${MAPBOX_TOKEN}&` +
      `country=${country}&` +
      `language=pt&` +
      `limit=10`;

    // Add proximity bias based on region
    const region = localStorage.getItem("photum_selected_region");
    if (region === "MG") {
      // Belo Horizonteish center
      url += `&proximity=-43.9378,-19.9208`; 
    } else {
      // São Pauloish center (Default)
      url += `&proximity=-46.6333,-23.5505`;
    }

    console.log("🔍 Buscando endereço:", query);
    const response = await fetch(url);

    if (!response.ok) {
      console.error("❌ Erro na API Mapbox:", response.statusText);
      throw new Error(`Mapbox API error: ${response.statusText}`);
    }

    const data = await response.json();
    console.log("✅ Resultados encontrados:", data.features?.length || 0);

    if (!data.features || data.features.length === 0) {
      return [];
    }

    return data.features.map((feature: MapboxFeature) => {
      // Extrair informações do contexto
      const context = feature.context || [];
      const place = context.find((c) => c.id.startsWith("place"));
      const region = context.find((c) => c.id.startsWith("region"));
      const postcode = context.find((c) => c.id.startsWith("postcode"));

      // Extrair número do endereço
      const addressMatch =
        feature.address || feature.text.match(/\d+/)?.[0] || "";

      return {
        description: feature.place_name,
        street: feature.text,
        number: addressMatch,
        city: place?.text || "",
        state: region?.short_code?.replace("BR-", "") || region?.text || "",
        zip: postcode?.text || "",
        lat: feature.center[1],
        lng: feature.center[0],
        mapLink: `https://www.google.com/maps/search/?api=1&query=${feature.center[1]},${feature.center[0]}`,
      };
    });
  } catch (error) {
    console.error("Erro ao buscar localização no Mapbox:", error);
    return [];
  }
}

/**
 * Busca reversa: converte coordenadas em endereço
 * Retorna o endereço completo baseado nas coordenadas do pin
 */
export async function reverseGeocode(
  lat: number,
  lng: number
): Promise<MapboxResult | null> {
  if (!MAPBOX_TOKEN || MAPBOX_TOKEN.startsWith("YOUR_")) {
    console.warn("⚠️ Mapbox Token não configurado");
    return null;
  }

  try {
    const url =
      `https://api.mapbox.com/geocoding/v5/mapbox.places/${lng},${lat}.json?` +
      `access_token=${MAPBOX_TOKEN}&` +
      `language=pt&` +
      `types=address,place`;

    const response = await fetch(url);
    const data = await response.json();

    if (data.features && data.features.length > 0) {
      const feature = data.features[0];
      const context = feature.context || [];
      const place = context.find((c: any) => c.id.startsWith("place"));
      const region = context.find((c: any) => c.id.startsWith("region"));
      const postcode = context.find((c: any) => c.id.startsWith("postcode"));

      // Extrair número se houver
      const addressMatch = feature.address || "";

      return {
        description: feature.place_name,
        street: feature.text,
        number: addressMatch.toString(),
        city: place?.text || "",
        state: region?.short_code?.replace("BR-", "") || region?.text || "",
        zip: postcode?.text || "",
        lat,
        lng,
        mapLink: `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`,
      };
    }

    return null;
  } catch (error) {
    console.error("Erro no reverse geocode:", error);
    return null;
  }
}
