import axios from 'axios'; const GEOCODING_URL = 'https://maps.googleapis.com/maps/api/geocode/json'; const parseAddressComponents = (components) => { const get = (type, nameType = 'long_name') => components.find((c) => c.types.includes(type))?.[nameType] ?? ''; return { address: `${get('route')}`.trim(), number: get('street_number'), district: get('sublocality_level_1') || get('sublocality') || get('neighborhood'), city: get('administrative_area_level_2'), state: get('administrative_area_level_1', 'short_name'), zip_code: get('postal_code').replace(/\D/g, ''), }; }; const geocodeViaGoogleMaps = async (request) => { const geocoder = new window.google.maps.Geocoder(); const { results } = await geocoder.geocode(request); return results ?? []; }; export const useGeocodingApi = () => { const geocodeCep = async (cep) => { const cleaned = cep.replace(/\D/g, ''); const apiKey = process.env.GOOGLE_MAPS_API_KEY; const usandoGeocoderNativo = !!window.google?.maps?.Geocoder; if (usandoGeocoderNativo) { const results = await geocodeViaGoogleMaps({ address: `${cleaned}, Brazil` }); if (!results.length) return null; const result = results[0]; const parsed = parseAddressComponents(result.address_components); return { lat: result.geometry.location.lat(), lng: result.geometry.location.lng(), ...parsed, }; } const { data } = await axios.get(GEOCODING_URL, { params: { address: `${cleaned}, Brazil`, key: apiKey }, }); if (data.status !== 'OK' || !data.results.length) return null; const result = data.results[0]; const { lat, lng } = result.geometry.location; return { lat, lng, ...parseAddressComponents(result.address_components) }; }; const reverseGeocode = async (lat, lng) => { const apiKey = process.env.GOOGLE_MAPS_API_KEY; const usandoGeocoderNativo = !!window.google?.maps?.Geocoder; if (usandoGeocoderNativo) { const results = await geocodeViaGoogleMaps({ location: { lat, lng } }); if (!results.length) return null; return { lat, lng, ...parseAddressComponents(results[0].address_components) }; } const { data } = await axios.get(GEOCODING_URL, { params: { latlng: `${lat},${lng}`, key: apiKey }, }); if (data.status !== 'OK' || !data.results.length) return null; const result = data.results[0]; return { lat, lng, ...parseAddressComponents(result.address_components) }; }; const geocodeFullAddress = async ({ address, number, district, zip_code, city, state }) => { const parts = [address, number, district, zip_code, city, state, 'Brazil'].filter(Boolean); const query = parts.join(', '); const apiKey = process.env.GOOGLE_MAPS_API_KEY; const usandoGeocoderNativo = !!window.google?.maps?.Geocoder; if (usandoGeocoderNativo) { const results = await geocodeViaGoogleMaps({ address: query }); if (!results.length) return null; const result = results[0]; return { lat: result.geometry.location.lat(), lng: result.geometry.location.lng(), ...parseAddressComponents(result.address_components), }; } const { data } = await axios.get(GEOCODING_URL, { params: { address: query, key: apiKey }, }); if (data.status !== 'OK' || !data.results.length) return null; const result = data.results[0]; const { lat, lng } = result.geometry.location; return { lat, lng, ...parseAddressComponents(result.address_components) }; }; return { geocodeCep, reverseGeocode, geocodeFullAddress }; };