// $(document).ready(function () { const EnderecoModal = { mapa: null, moveMarker: true, marker: null, markerIcon: null, markerEstabelecimento: null, circuloAlcance: null, circuloCliente: null, markerCirculoCliente:null, raioKmEndereco: 0.15, dentroDoEndereco:false, estabelecimento: { lat: null, lng: null, raioKm: null, icon: null, titulo: null, label: null, icon_centro: null, }, enderecoFinal: null, formatoEndereco: { endereco: null, rua: null, numero: null, bairro: null, cidade: null, estado: null, uf: null, pais: null, cep: null, latitude: null, longitude: null, distanciaKm: null, tempoEstimadoMinuto: null }, modalEndereco:null, // Removido stylesMapa do Google Maps init: function (estabelecimento) { this.estabelecimento = estabelecimento; this.bindEvents(); this.mudarEtapa(1); }, openModal: function ({estabelecimento,initConfig=false, initialLat = null, initialLng = null, latAtual = null, lonAtual = null, radiusKm = null, onConfirm, onCancel}) { const modalEndereco = 'modalEndereco'; this.modalEndereco = modalEndereco; this.estabelecimento = estabelecimento; this.estabelecimento.raioKm = this.estabelecimento.raioKm??0; if (initialLat) initialLat = parseFloat(initialLat); if (initialLng) initialLng = parseFloat(initialLng); if (latAtual) latAtual = parseFloat(latAtual); if (lonAtual) lonAtual = parseFloat(lonAtual); if ($('#' + modalEndereco).length > 0) { if (!initConfig){ $('#' + modalEndereco).modal('show'); } this.mudarEtapa(1); return; } const modalEnderecoHtml = ` `; document.body.insertAdjacentHTML('beforeend', modalEnderecoHtml); if (!initConfig){ $('#' + modalEndereco).modal('show'); } this.mudarEtapa(1); // Carregar Leaflet CSS e JS function loadLeaflet(callback) { if (window.L) { callback(); } else { // Adicionar CSS do Leaflet const leafletCSS = document.createElement('link'); leafletCSS.rel = 'stylesheet'; leafletCSS.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'; document.head.appendChild(leafletCSS); // Adicionar JS do Leaflet const leafletJS = document.createElement('script'); leafletJS.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'; leafletJS.onload = callback; document.body.appendChild(leafletJS); } } this.mudarEtapa(1); loadLeaflet(() => { EnderecoModal.bindEvents(); EnderecoModal.setCallback(onConfirm); }); $(document).off('shown.bs.modal','.'+modalEndereco); $(document).on('shown.bs.modal','.'+modalEndereco,function () { if (EnderecoModal.mapa) { setTimeout(() => EnderecoModal.mapa.invalidateSize(), 300); } EnderecoModal.mudarEtapa(1); EnderecoModal.limpaInputBox('#etapa3'); }); $(document).off('hidden.bs.modal','.'+modalEndereco); $(document).on('hidden.bs.modal','.'+modalEndereco,function () { EnderecoModal.mudarEtapa(1); }); // Forçar redraw do mapa setTimeout(() => { if (EnderecoModal.mapa){ EnderecoModal.mapa.invalidateSize(); EnderecoModal.atualizarInformacoes(lat, lng); } }, 300); }, configAutoCompleteOSM: function () { $(document).off("keyup", "#mapa_pesquisa"); // Cria o container para os resultados logo após o input if ($("#osm-autocomplete-results").length === 0) { $("#mapa_pesquisa").parent().css("position", "relative"); $("#mapa_pesquisa").after('
'); } let timeout = null; $(document).on("keyup", "#mapa_pesquisa", function(e) { const query = $(this).val(); // Se pressionar Enter if (e.which === 13) { if (query.length > 0) EnderecoModal.buscarEnderecoNominatim(query); $("#osm-autocomplete-results").hide(); return; } // Esconde se for pequeno if (query.length < 4) { $("#osm-autocomplete-results").empty().hide(); return; } // Feedback visual de carregamento $("#osm-autocomplete-results").html('
Buscando endereços...
').show(); clearTimeout(timeout); timeout = setTimeout(() => { const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&addressdetails=1&limit=5&countrycodes=br`; fetch(url) .then(response => response.json()) .then(data => { const resultsContainer = $("#osm-autocomplete-results"); resultsContainer.empty(); if (data && data.length > 0) { data.forEach(item => { const suggestion = $('
', { class: 'osm-autocomplete-item', text: item.display_name }); suggestion.on("click", function() { $("#mapa_pesquisa").val(item.display_name); resultsContainer.hide(); const componentes = EnderecoModal.extrairComponentesNominatim(item); EnderecoModal.preencherEnderecoTela(componentes); }); resultsContainer.append(suggestion); }); resultsContainer.show(); } else { resultsContainer.html('
Nenhum endereço encontrado.
').show(); } }) .catch(() => { $("#osm-autocomplete-results").html('
Erro na busca. Confirme se há conexão.
').show(); }); }, 800); // 800ms debounce }); // Fechar ao clicar fora $(document).on("click", function(event) { if (!$(event.target).closest("#mapa_pesquisa, #osm-autocomplete-results").length) { $("#osm-autocomplete-results").hide(); } }); } ,bindEvents: function () { $("#wem_btn_mapa")?.click(() => $("#"+EnderecoModal.modalEndereco).modal("show")); // Autocomplete simplificado - usando Nominatim (OSM) // // Adiciona o Autocomplete ao campo de endereço this.configAutoCompleteOSM(); $(document).off("click", ".btnEscolha"); $(document).on("click", ".btnEscolha", (e) => { const escolha = $(e.target).data("escolha"); EnderecoModal.preparaInputCEPeLocal(); if (escolha === "cep") { EnderecoModal.limpaInputBox('#etapa2'); EnderecoModal.limpaInputBox('#etapa3'); EnderecoModal.mudarEtapa(2); $(document).off("afterFadeIn","#etapa3"); $(document).on("afterFadeIn","#etapa3",function() { $(document).off("afterFadeIn","#etapa3"); $("#mapa_numero").val('').focus(); }); } else if (escolha === "nao") { EnderecoModal.preparaInputCEPNao(); EnderecoModal.limpaInputBox('#etapa3'); $(document).off("afterFadeIn","#etapa3"); EnderecoModal.mudarEtapa(3); } else if (escolha === "geo") { $(document).off("afterFadeIn","#etapa3"); $(document).on("afterFadeIn","#etapa3",function() { $("#mapa_numero").focus(); }); EnderecoModal.usarGeolocalizacao(); } }); $(document).off("click", "#btnBuscar"); $(document).on("click", "#btnBuscar", () => { EnderecoModal.mostrarCarregamento(); EnderecoModal.buscarCEP(); }); $(document).off("keypress", "#mapa_inputCep"); $(document).on("keypress", "#mapa_inputCep", function (event) { if (event.which === 13) { $("#btnBuscar").trigger('click'); } }); $(document).off("click", "#btnAvancarMapa"); $(document).on("click", "#btnAvancarMapa", () => { if (EnderecoModal.validaInputBox('#etapa3')) { EnderecoModal.mostrarCarregamento(); EnderecoModal.prepararMapa(); } }); $(document).off("click", "#btnConfirmar"); $(document).on("click", "#btnConfirmar", () => EnderecoModal.confirmarEndereco()); $(document).off("click", ".btnVoltar"); $(document).on("click", ".btnVoltar", (e) => EnderecoModal.mudarEtapa($(e.target).data("etapa"))); $(document).off('keyup','#etapa3 input, #etapa3 textarea'); $(document).on('keyup','#etapa3 input, #etapa3 textarea', function(e) { if (e.key === 'Enter') { e.preventDefault(); let tabindex = $(this).attr('tabindex'); let nextElement = $('[tabindex]').filter(function() { return $(this).attr('tabindex') > tabindex && !$(this).prop('readonly'); }).first(); if (nextElement.length) { nextElement.focus(); } else { $('[tabindex="1"]:not([readonly])').focus(); } } }); $(document).off('keyup','#w_map'); $(document).on('keyup',"#w_map", function (e) { if (e.key === "Enter") { $("#btnConfirmar").focus(); } }); }, verificarAlcance: function (lat, lng) { const distancia = this.calcularDistanciaLinhaReta( lat, lng, this.estabelecimento.lat, this.estabelecimento.lng ); const dentroAlcance = (distancia <= this.estabelecimento.raioKm) || (this.estabelecimento.raioKm==0); const infoDiv = document.getElementById('infoAlcanceModal'); infoDiv.innerHTML = ` Distância do estabelecimento: ${distancia} km em linha reta.
Status: ${dentroAlcance ? 'Dentro da área de entrega 🟢' : 'Fora da área de entrega 🔴'} `; infoDiv.className = `distance-info ${dentroAlcance ? 'within-range' : 'out-of-range'}`; document.getElementById('btnConfirmar').disabled = !dentroAlcance; }, // Buscar endereço usando Nominatim (OSM) buscarEnderecoNominatim: function(query) { if (query.length < 3) return; const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&addressdetails=1&limit=5&countrycodes=br`; fetch(url) .then(response => response.json()) .then(data => { if (data && data.length > 0) { const primeiroResultado = data[0]; const componentes = this.extrairComponentesNominatim(primeiroResultado); this.preencherEnderecoTela(componentes); } }) .catch(error => { console.error('Erro ao buscar endereço:', error); EnderecoModal.mostrarAlerta('Erro ao buscar endereço. Tente novamente.'); }); }, extrairComponentesNominatim: function(resultado) { const address = resultado.address || {}; return { rua: address.road || address.pedestrian || '', numero: address.house_number || '', bairro: address.suburb || address.neighbourhood || address.city_district || '', cidade: address.city || address.town || address.village || address.municipality || '', estado: address.state || '', lat: parseFloat(resultado.lat), lng: parseFloat(resultado.lon) }; }, validaInputBox: function (box) { const currentFields = $(box).find(':input'); let valid = true; currentFields.each(function () { if (!this.checkValidity()) { this.reportValidity(); valid = false; return false; } }); return valid; }, limpaInputBox: function (box) { const currentFields = $(box).find(':input'); currentFields.each(function () { $(this).val(''); }); }, preparaInputCEPeLocal: function () { $('#mapa_estado').prop('readonly', true); $('#mapa_cidade').prop('readonly', true); $('#mapa_bairro').prop('readonly', false); $('#mapa_rua').prop('readonly', false); $('#mapa_numero').prop('readonly', false); }, preparaInputCEPNao: function () { const currentFields = $('#etapa3').find(':input'); currentFields.each(function () { $(this).val('').prop('readonly', false); }); }, calcularRotaOSRM: async function (origemLat, origemLng, destinoLat, destinoLng, perfil = 'driving') { const perfisValidos = ['driving', 'walking', 'cycling']; const perfilUsar = perfisValidos.includes(perfil) ? perfil : 'driving'; try { const url = `https://router.project-osrm.org/route/v1/${perfilUsar}/${origemLng},${origemLat};${destinoLng},${destinoLat}?overview=full&geometries=geojson`; const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); if (data.code !== 'Ok' || !data.routes || data.routes.length === 0) { throw new Error('Nenhuma rota encontrada'); } const rota = data.routes[0]; const leg = rota.legs[0]; return { success: true, distanciaKm: (leg.distance / 1000).toFixed(2), tempoMinutos: Math.ceil(leg.duration / 60), geometria: rota.geometry, instrucoes: leg.steps.map(step => ({ instrucao: step.maneuver.instruction, distancia: (step.distance / 1000).toFixed(1), tempo: Math.ceil(step.duration / 60) })), perfil: perfilUsar }; } catch (error) { console.warn('Erro OSRM, usando fallback:', error); // Fallback para cálculo em linha reta const distancia = calcularDistanciaLinhaReta(origemLat, origemLng, destinoLat, destinoLng); let fatorTempo = 2.5; // minutos por km (carro) if (perfilUsar === 'walking') fatorTempo = 12; if (perfilUsar === 'cycling') fatorTempo = 6; return { success: false, distanciaKm: distancia, tempoMinutos: Math.ceil(distancia * fatorTempo), geometria: null, instrucoes: [], perfil: perfilUsar, fallback: true }; } } , calcularDistanciaLinhaReta: function (lat1, lon1, lat2, lon2) { const R = 6371; const dLat = (lat2 - lat1) * Math.PI / 180; const dLon = (lon2 - lon1) * Math.PI / 180; const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); const resultado = R * c; return resultado.toFixed(2); }, estimarTempoKm: function (distanciaEmKm, tipoEntrega = "moto") { const velocidades = { "moto": 2.2, "carro": 2.8, "bike": 4.5, "a_pe": 15 }; const fatoresExtras = { "moto": 0.30, "carro": 0.40, "bike": 0.25, "a_pe": 0.15 }; let tempoPorKmEmMinutos = velocidades[tipoEntrega] || 2; let fatorExtra = fatoresExtras[tipoEntrega] || 0.30; let tempoEstimado = distanciaEmKm * tempoPorKmEmMinutos; tempoEstimado += tempoEstimado * fatorExtra; return Math.ceil(tempoEstimado); }, mudarEtapa: function (etapa) { const $etapaAtual = $(`#etapa${etapa}`); if (!$etapaAtual.is(":visible")) { $(".etapa").hide(); $etapaAtual.fadeIn(function () { $etapaAtual.find("input:visible:not([readonly])").first().focus(); $etapaAtual.trigger("afterFadeIn"); }); } }, buscarCEP: function () { const cep = $("#mapa_inputCep").val().replace(/\D/g, ''); if (cep.length === 8) { $.getJSON(`https://viacep.com.br/ws/${cep}/json/`, (data) => { this.ocultarCarregamento(); if (!data.erro) { $("#mapa_rua").val(data.logradouro); $("#mapa_bairro").val(data.bairro); $("#mapa_cidade").val(data.localidade); $("#mapa_estado").val(data.uf); this.mudarEtapa(3); $("#mapa_numero").focus(); } else { EnderecoModal.mostrarAlerta("CEP não encontrado."); } }).fail(() => { this.ocultarCarregamento(); EnderecoModal.mostrarAlerta("Erro ao consultar o CEP."); }); } else { this.ocultarCarregamento(); EnderecoModal.mostrarAlerta("Digite um CEP válido."); } }, usarGeolocalizacao: function () { this.mostrarCarregamento(); if (navigator.geolocation) { navigator.geolocation.getCurrentPosition((position) => { const lat = position.coords.latitude; const lng = position.coords.longitude; this.buscarEnderecoPorCoordenadas(lat, lng); }, () => { this.ocultarCarregamento(); $(document).off("afterFadeIn","#etapa3"); EnderecoModal.mostrarAlerta("Verifique se seu GPS esta ligado e de permissão ao site para usar."); }); } else { this.ocultarCarregamento(); $(document).off("afterFadeIn","#etapa3"); EnderecoModal.mostrarAlerta("Geolocalização não suportada."); } }, buscarEnderecoPorCoordenadas: function (lat, lng) { const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&addressdetails=1`; fetch(url) .then(response => response.json()) .then(data => { this.ocultarCarregamento(); if (data) { let componentes = this.extrairComponentesNominatim(data); if (!componentes.rua){ EnderecoModal.mostrarAlerta("Endereço não localizado com precisão. Preencha manualmente."); } this.preencherEnderecoTela(componentes, lat, lng); } else { EnderecoModal.mostrarAlerta("Erro ao buscar endereço."); } }) .catch(error => { this.ocultarCarregamento(); EnderecoModal.mostrarAlerta("Erro ao buscar endereço."); }); }, preencherEnderecoTela: function (componentes, lat=null, lng=null) { this.ocultarCarregamento(); if (componentes) { $("#mapa_rua").val(componentes.rua || ""); $("#mapa_numero").val($("#mapa_numero").val()||componentes.numero || ""); $("#mapa_bairro").val(componentes.bairro || ""); $("#mapa_cidade").val(componentes.cidade || ""); $("#mapa_estado").val(componentes.estado || ""); $("#mapa_lat").val(lat||componentes.lat); $("#mapa_lng").val(lng||componentes.lng); this.mudarEtapa(3); $("#mapa_numero").focus(); } }, prepararComponentesMap: function () { if (this.estabelecimento) { // Círculo de alcance do estabelecimento if (!this.circuloAlcance) { this.circuloAlcance = L.circle( [this.estabelecimento.lat, this.estabelecimento.lng], { radius: this.estabelecimento.raioKm * 1000, color: '#FF0000', fillColor: '#00cccc', fillOpacity: 0.1, weight: 1 } ).addTo(this.mapa); } // Marker do círculo do cliente if (!this.markerCirculoCliente) { const markerPos = this.marker.getLatLng(); this.markerCirculoCliente = L.marker(markerPos, { icon: L.divIcon({ html: '
Ajuste dentro dessa área
', className: 'custom-label', iconSize: [150, 20] }) }).addTo(this.mapa); } // Círculo do cliente if (!this.circuloCliente) { const markerPos = this.marker.getLatLng(); this.circuloCliente = L.circle(markerPos, { radius: this.raioKmEndereco * 1000, color: '#FF0000', fillColor: '#00cccc', fillOpacity: 0.1, weight: 1 }).addTo(this.mapa); } else { const markerPos = this.marker.getLatLng(); this.circuloCliente.setLatLng(markerPos); this.markerCirculoCliente.setLatLng(markerPos); } } }, prepararMapa: function () { const rua = $("#mapa_rua").val(); const numero = $("#mapa_numero").val(); const bairro = $("#mapa_bairro").val(); const cidade = $("#mapa_cidade").val(); const estado = $("#mapa_estado").val(); const endereco = `${rua}, ${numero}, ${bairro}, ${cidade}, ${estado}`; const lat = $("#mapa_lat").val(); const lng = $("#mapa_lng").val(); $("#infoEndereco")?.text(endereco); this.ocultarCarregamento(); if (lat && lng) { const location = { lat: parseFloat(lat), lng: parseFloat(lng) }; setTimeout(() => this.inicializarMapa(location.lat, location.lng), 100); this.mudarEtapa(4); } else { // Função recursiva para tentar localizar o endereço relaxando a precisão se necessário const tentativas = [ `${rua}, ${numero}, ${bairro}, ${cidade}, ${estado}`, `${rua}, ${bairro}, ${cidade}, ${estado}` ]; const tentarGeocodificar = (index) => { if (index >= tentativas.length) { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( (position) => { EnderecoModal.mostrarAlerta("Não conseguimos localizar o endereço com precisão, então o mapa abriu na sua localização do GPS. Por favor, ajuste o pino vermelho!"); setTimeout(() => this.inicializarMapa(position.coords.latitude, position.coords.longitude), 100); this.mudarEtapa(4); }, () => { EnderecoModal.mostrarAlerta("Não achamos a rua e não foi possível localizar seu GPS. O mapa abrirá perto da lanchonete, ajuste o pino até sua casa!"); setTimeout(() => this.inicializarMapa(this.estabelecimento.lat, this.estabelecimento.lng), 100); this.mudarEtapa(4); }, { timeout: 10000 } ); } else { EnderecoModal.mostrarAlerta("Não encontramos sua rua no mapa. O mapa vai abrir no entorno do estabelecimento, por favor, puxe o pino vermelho até sua casa!"); setTimeout(() => this.inicializarMapa(this.estabelecimento.lat, this.estabelecimento.lng), 100); this.mudarEtapa(4); } return; } const query = tentativas[index]; const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=1&countrycodes=br`; fetch(url) .then(response => response.json()) .then(data => { if (data && data.length > 0) { const location = data[0]; setTimeout(() => this.inicializarMapa(parseFloat(location.lat), parseFloat(location.lon)), 100); this.mudarEtapa(4); if(index > 0) { EnderecoModal.mostrarAlerta("Achamos a região, mas não o ponto exato. Por favor, arraste o pino para a posição exata."); } } else { tentarGeocodificar(index + 1); // Tenta o próximo nível de relaxamento } }) .catch(() => { tentarGeocodificar(index + 1); }); }; tentarGeocodificar(0); } $("#w_map")?.focus(); }, inicializarMapa: function (lat, lng) { const mapElement = document.getElementById("w_map"); if (!this.mapa) { this.mapa = L.map(mapElement).setView([lat, lng], 13); // Adicionar tile layer do OpenStreetMap L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19 }).addTo(this.mapa); } else { this.mapa.setView([lat, lng], 13); } // Marker do usuário if (!this.marker) { const icon_centro = L.icon({ iconUrl: this.estabelecimento.icon_centro, iconSize: [60, 60], iconAnchor: [30, 60] }); this.marker = L.marker([lat, lng], { draggable: true, icon: icon_centro, title: "Você está aqui" }).addTo(this.mapa); } else { this.marker.setLatLng([lat, lng]); } // Marker do estabelecimento if (this.estabelecimento) { const iconEstabelecimento = L.icon({ iconUrl: this.estabelecimento.icon, iconSize: [60, 60], iconAnchor: [30, 30] }); if (!this.markerEstabelecimento) { this.markerEstabelecimento = L.marker( [this.estabelecimento.lat, this.estabelecimento.lng], { draggable: false, icon: iconEstabelecimento, title: this.estabelecimento.titulo } ).addTo(this.mapa); // Adicionar popup com label if (this.estabelecimento.label) { this.markerEstabelecimento.bindPopup(this.estabelecimento.label); } } } // Eventos do marker this.marker.on('dragstart', () => { $('#btnConfirmar').prop('disabled', true); }); this.marker.on('dragend', (e) => { const novaPosicao = e.target.getLatLng(); this.mapa.setView(novaPosicao); this.atualizarInformacoes(novaPosicao.lat, novaPosicao.lng); $('#btnConfirmar').prop('disabled', false); }); // ✅ EVENTOS DE ZOM - use conforme sua necessidade: // 1. Quando o zoom COMEÇA this.mapa.on('zoomstart', () => { this.moveMarker = false; }); // 2. Durante o zoom (dispara múltiplas vezes) this.mapa.on('zoom', () => { // CUIDADO: Dispara muitas vezes durante o zoom // console.log('Zoom em andamento:', this.mapa.getZoom()); }); // 3. Quando o zoom TERMINA this.mapa.on('zoomend', () => { this.moveMarker = true; }); // Evento de movimentação do mapa this.mapa.on('move', () => { if (this.moveMarker){ const centro = this.mapa.getCenter(); this.marker.setLatLng(centro); this.atualizarInformacoes(centro.lat, centro.lng); } }); // ✅ ADICIONAR isto (dispara apenas quando termina o movimento): // this.mapa.on('moveend', () => { // const centro = this.mapa.getCenter(); // this.marker.setLatLng(centro); // this.atualizarInformacoes(centro.lat, centro.lng); // }); if (this.mapa) { setTimeout(() =>{ this.mapa.invalidateSize(); this.prepararComponentesMap(); this.atualizarInformacoes(lat, lng); this.animateZoom(18, 1000); }, 300); } //this.prepararComponentesMap(); //this.animateZoom(18, 2000); // this.atualizarInformacoes(lat, lng); }, animateZoom: function (targetZoom, duration) { let currentZoom = this.mapa.getZoom(); const increment = (targetZoom - currentZoom) / (duration / 50); const step = () => { currentZoom += increment; this.mapa.setZoom(Math.round(currentZoom)); if ((increment > 0 && currentZoom < targetZoom) || (increment < 0 && currentZoom > targetZoom)) { setTimeout(step, 50); } }; step(); },getUFFromState: function(stateName) { const stateMap = { // Com acentos corretos 'acre': 'AC', 'ac': 'AC', 'alagoas': 'AL', 'al': 'AL', 'amapá': 'AP', 'amapa': 'AP', 'ap': 'AP', 'amazonas': 'AM', 'am': 'AM', 'bahia': 'BA', 'ba': 'BA', 'ceará': 'CE', 'ceara': 'CE', 'ce': 'CE', 'distrito federal': 'DF', 'df': 'DF', 'espírito santo': 'ES', 'espirito santo': 'ES', 'es': 'ES', 'goiás': 'GO', 'goias': 'GO', 'go': 'GO', 'maranhão': 'MA', 'maranhao': 'MA', 'ma': 'MA', 'mato grosso': 'MT', 'mt': 'MT', 'mato grosso do sul': 'MS', 'ms': 'MS', 'minas gerais': 'MG', 'mg': 'MG', 'pará': 'PA', 'para': 'PA', 'pa': 'PA', 'paraíba': 'PB', 'paraiba': 'PB', 'pb': 'PB', 'paraná': 'PR', 'parana': 'PR', 'pr': 'PR', 'pernambuco': 'PE', 'pe': 'PE', 'piauí': 'PI', 'piaui': 'PI', 'pi': 'PI', 'rio de janeiro': 'RJ', 'rj': 'RJ', 'rio grande do norte': 'RN', 'rn': 'RN', 'rio grande do sul': 'RS', 'rs': 'RS', 'rondônia': 'RO', 'rondonia': 'RO', 'ro': 'RO', 'roraima': 'RR', 'rr': 'RR', 'santa catarina': 'SC', 'sc': 'SC', 'são paulo': 'SP', 'sao paulo': 'SP', 'sp': 'SP', 'sergipe': 'SE', 'se': 'SE', 'tocantins': 'TO', 'to': 'TO' }; if (!stateName) return ''; // Remove acentos e deixa minúsculo const normalized = stateName .toLowerCase() .normalize('NFD') .replace(/[\u0300-\u036f]/g, '') // Remove acentos .trim(); return stateMap[normalized] || stateName; }, geocodeLatLng: async function (lat, lng, callback) { lat = parseFloat(lat); lng = parseFloat(lng); const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&addressdetails=1`; try { const response = await fetch(url); const data = await response.json(); if (!data) { throw new Error('Endereço não encontrado!'); } const address = data.address || {}; let distanciaKm = 0; let tempoEstimadoMinuto = 0; if (this.estabelecimento) { distanciaKm = this.calcularDistanciaLinhaReta( lat, lng, this.estabelecimento.lat, this.estabelecimento.lng ); tempoEstimadoMinuto = this.estimarTempoKm(distanciaKm); } const formattedData = { endereco: data.display_name || '', rua: address.road || address.pedestrian || $('#mapa_rua').val(), numero: $('#mapa_numero').val(), bairro: address.suburb || address.neighbourhood || address.city_district || '', cidade: address.city || address.town || address.village || address.municipality || '', estado: this.getUFFromState(address.state) || address.state || 'Espirito Santo', uf: this.getUFFromState(address.state) || address.state|| 'ES', pais: address.country || '', cep: address.postcode || '', latitude: lat, longitude: lng, distanciaKm: parseFloat(distanciaKm), tempoEstimadoMinuto: tempoEstimadoMinuto }; formattedData.rua = $('#mapa_rua').val(); formattedData.numero = $('#mapa_numero').val(); formattedData.bairro = $('#mapa_bairro').val(); formattedData.endereco = formattedData.rua + ', ' + formattedData.numero + ', ' + formattedData.bairro + ', ' + formattedData.cidade + ' - ' + formattedData.uf; $("#wem_endereco")?.val(formattedData.endereco); callback(formattedData); } catch (error) { console.log(error); } }, atualizarInformacoes: function (lat, lng) { $("#mapa_lat").val(lat); $("#mapa_lng").val(lng); if (this.estabelecimento) { const distanciaKm = this.calcularDistanciaLinhaReta( lat, lng, this.estabelecimento.lat, this.estabelecimento.lng ); const distanciaKmCentro = this.calcularDistanciaLinhaReta( lat, lng, this.circuloCliente.getLatLng().lat, this.circuloCliente.getLatLng().lng ); const tempo = (distanciaKm / 40) * 60; $("#mapa_distancia").val(distanciaKm); $("#mapa_tempo").val(tempo.toFixed(2)); const dentroDoAlcance = (parseFloat(distanciaKm) <= this.estabelecimento.raioKm) || (this.estabelecimento.raioKm==0); const dentroDoEndereco = parseFloat(distanciaKmCentro) <= this.raioKmEndereco; this.dentroDoEndereco = dentroDoEndereco; // USAR ROTA REAL // const rota = await calcularRotaOSRM( // lat, lng, // this.estabelecimento.lat, this.estabelecimento.lng, // 'driving' // ou 'walking', 'cycling' // ); let textoExibir = (dentroDoAlcance ? "Dentro do Alcance (Delivery)" : "Fora do Alcance (Retirar)") + " de " + distanciaKm + " / " + this.estabelecimento.raioKm + " km."; textoExibir += (dentroDoEndereco ? "" : ' (Muito afastado do ponto inicial)'); if (this.estabelecimento.raioKm==0) { $('#infoAlcanceModal').hide(); } else { $('#infoAlcanceModal').show(); } $("#infoAlcance").html(textoExibir); $(".infoAlcance").css("color", dentroDoAlcance ? "green" : "red"); $("#infoAlcanceEndereco").css("color", dentroDoEndereco ? "green" : "red"); $("#btnConfirmar").prop("disabled", !dentroDoAlcance); if (dentroDoAlcance) { $("#btnConfirmar").addClass("btn-success"); } else { $("#btnConfirmar").removeClass("btn-success"); } this.verificarAlcance(lat, lng); } }, confirmarEndereco: function () { if (!this.dentroDoEndereco){ this.buscarEnderecoPorCoordenadas( this.marker.getLatLng().lat, this.marker.getLatLng().lng ); return; } const endereco = `${$("#mapa_rua").val()}, ${$("#mapa_numero").val()}, ${$("#mapa_bairro").val()}, ${$("#mapa_cidade").val()}, ${$("#mapa_estado").val()}`; this.enderecoFinal = endereco; $("#"+EnderecoModal.modalEndereco).modal("hide"); this.mudarEtapa(1); if (typeof this.callback === "function") { this.geocodeLatLng($("#mapa_lat").val(), $("#mapa_lng").val(), this.callback); } }, mostrarCarregamento: function () { $(".modal-body").append('
Carregando...
'); }, ocultarCarregamento: function () { $(".carregamento").remove(); }, setCallback: function (callback) { this.callback = callback; }, mostrarAlerta: function (mensagem, tipo = 'warning') { $('.w-alerta-amigavel').remove(); const alertHtml = ``; $('#' + EnderecoModal.modalEndereco + ' .modal-content').css('position', 'relative').append(alertHtml); $('.w-alerta-amigavel').fadeIn(); setTimeout(() => { $('.w-alerta-amigavel').fadeOut(500, function() { $(this).remove(); }); }, 6000); } };