// 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 { 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 { 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; } }