window.phMap = { _maps: {}, _searchAbortController: null, initMap: function (mapId, lat, lng, zoom) { // Evitar reinicializar si ya existe if (this._maps[mapId]) { console.warn(`Map ${mapId} already initialized`); return; } try { const map = L.map(mapId, { zoomControl: true, attributionControl: true }).setView([lat, lng], zoom); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19, crossOrigin: true }).addTo(map); const marker = L.marker([lat, lng], { draggable: false, keyboard: false }).addTo(map) .bindPopup(`Lat: ${lat.toFixed(5)}
Lng: ${lng.toFixed(5)}`) .openPopup(); this._maps[mapId] = { map, marker, clickHandler: this._createClickHandler.bind(this, mapId) }; // Agregar event listener para clicks en el mapa map.on('click', this._maps[mapId].clickHandler); // Resizable map map.invalidateSize(); } catch (error) { console.error(`Error initializing map ${mapId}:`, error); } }, _createClickHandler: function (mapId, e) { const newLat = e.latlng.lat; const newLng = e.latlng.lng; const mapData = this._maps[mapId]; if (!mapData) return; mapData.marker.setLatLng([newLat, newLng]); mapData.marker.setPopupContent(`Lat: ${newLat.toFixed(5)}
Lng: ${newLng.toFixed(5)}`); mapData.marker.getPopup().setLatLng([newLat, newLng]); if (typeof DotNet !== 'undefined' && DotNet.invokeMethodAsync) { DotNet.invokeMethodAsync('phronCare.UIBlazor', 'NotifyLocationChanged', newLat, newLng) .catch(error => console.error('Error invoking Blazor method NotifyLocationChanged:', error)); } else { console.warn('DotNet interop not available'); } }, updateLocation: function (mapId, lat, lng) { const mapData = this._maps[mapId]; if (!mapData) { console.warn(`Map ${mapId} not found`); return; } mapData.map.setView([lat, lng], mapData.map.getZoom()); mapData.marker.setLatLng([lat, lng]); mapData.marker.setPopupContent(`Lat: ${lat.toFixed(5)}
Lng: ${lng.toFixed(5)}`); }, searchAddress: async function (mapId, address) { const mapData = this._maps[mapId]; if (!mapData) { console.warn(`Map ${mapId} not found`); return; } // Cancelar búsquedas anteriores if (this._searchAbortController) { this._searchAbortController.abort(); } this._searchAbortController = new AbortController(); try { const response = await fetch( `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}`, { signal: this._searchAbortController.signal, headers: { 'Accept': 'application/json' } } ); if (!response.ok) { throw new Error(`API error: ${response.status}`); } const data = await response.json(); if (!data || data.length === 0) { console.warn(`Address not found: ${address}`); return; } const lat = parseFloat(data[0].lat); const lon = parseFloat(data[0].lon); if (isNaN(lat) || isNaN(lon)) { console.error('Invalid coordinates from API'); return; } mapData.map.setView([lat, lon], 15); mapData.marker.setLatLng([lat, lon]); mapData.marker.setPopupContent(`${address}
Lat: ${lat.toFixed(5)}
Lng: ${lon.toFixed(5)}`); if (typeof DotNet !== 'undefined' && DotNet.invokeMethodAsync) { DotNet.invokeMethodAsync('phronCare.UIBlazor', 'NotifyLocationChanged', lat, lon) .catch(error => console.error('Error invoking Blazor method NotifyLocationChanged:', error)); } else { console.warn('DotNet interop not available'); } } catch (error) { if (error.name === 'AbortError') { console.log('Search cancelled'); } else { console.error('Search error:', error); } } }, destroyMap: function (mapId) { const mapData = this._maps[mapId]; if (!mapData) return; try { mapData.map.off('click', mapData.clickHandler); mapData.map.remove(); delete this._maps[mapId]; } catch (error) { console.error(`Error destroying map ${mapId}:`, error); } } };