<!-- Reusable project-location map.

  Renders a Leaflet map with one pin per active monitoring location for
  the given project.  Fetches data from /api/projects/{p}/locations-json
  on load.

  Required context variable:
    project_id   — UUID string

  Optional context variable:
    map_height   — CSS height (default "320px")
    location_type — filter the fetched list (default: all types)

  Hover any .location-card on the page with a matching
  data-location-id → highlights the pin.  Click a pin → scrolls
  the matching card into view + flashes an orange ring.

  isolation:isolate on the container forces a new stacking context so
  Leaflet's internal z-indexes (200-800) stay contained inside the
  card instead of leaking out and rendering over modals (z-50).
-->
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-lg p-4">
    <div class="flex items-center justify-between mb-3">
        <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Location Map</h3>
        <span class="text-xs text-gray-400 dark:text-gray-500" id="loc-map-status-{{ project_id }}"></span>
    </div>
    <div id="loc-map-{{ project_id }}"
         class="w-full rounded-lg border border-gray-200 dark:border-gray-700"
         style="height: {{ map_height | default('320px') }}; background: rgba(0,0,0,0.05); isolation: isolate;">
    </div>
    <div id="loc-map-empty-{{ project_id }}" class="hidden text-xs text-gray-500 dark:text-gray-400 mt-2 italic text-center">
        No location coordinates set.  Edit a location and add a <code class="font-mono">lat,lon</code> pair to see it here.
    </div>
    <div id="loc-map-missing-{{ project_id }}" class="hidden text-xs text-gray-500 dark:text-gray-400 mt-2"></div>
</div>

<script>
(function () {
    const projectId    = {{ project_id | tojson }};
    const locationType = {{ (location_type | default(none)) | tojson }};
    const mapEl        = document.getElementById('loc-map-' + projectId);
    const emptyMsg     = document.getElementById('loc-map-empty-' + projectId);
    const missingMsg   = document.getElementById('loc-map-missing-' + projectId);
    const statusEl     = document.getElementById('loc-map-status-' + projectId);
    if (!mapEl) return;

    function parseCoords(s) {
        if (!s) return null;
        const parts = String(s).split(',').map(x => parseFloat(x.trim()));
        if (parts.length !== 2 || parts.some(isNaN)) return null;
        const [lat, lon] = parts;
        if (lat < -90 || lat > 90 || lon < -180 || lon > 180) return null;
        return [lat, lon];
    }

    async function init() {
        statusEl.textContent = 'loading…';
        let locs;
        try {
            const qs = locationType ? `?location_type=${encodeURIComponent(locationType)}` : '';
            const r = await fetch(`/api/projects/${projectId}/locations-json${qs}`);
            if (!r.ok) throw new Error('HTTP ' + r.status);
            locs = await r.json();
        } catch (e) {
            statusEl.textContent = 'failed';
            mapEl.innerHTML = `<div class="flex items-center justify-center h-full text-sm text-red-500">Map load failed: ${e.message}</div>`;
            return;
        }
        statusEl.textContent = '';

        const withCoords    = [];
        const withoutCoords = [];
        for (const loc of locs) {
            const xy = parseCoords(loc.coordinates);
            if (xy) withCoords.push({ ...loc, latlon: xy });
            else    withoutCoords.push(loc);
        }

        if (withCoords.length === 0) {
            mapEl.classList.add('hidden');
            emptyMsg.classList.remove('hidden');
            return;
        }

        const map = L.map(mapEl, { scrollWheelZoom: false });
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap',
            maxZoom: 18,
        }).addTo(map);

        const markersById = {};
        const bounds = [];
        withCoords.forEach(loc => {
            const marker = L.circleMarker(loc.latlon, {
                radius: 8, fillColor: '#f48b1c', color: '#fff',
                weight: 2, opacity: 1, fillOpacity: 0.9,
            }).addTo(map);
            marker.bindTooltip(loc.name, { direction: 'top', offset: [0, -6] });
            marker.on('click', () => _lmFlashCard(loc.id));
            markersById[loc.id] = marker;
            bounds.push(loc.latlon);
        });

        if (bounds.length === 1) map.setView(bounds[0], 14);
        else                     map.fitBounds(bounds, { padding: [20, 20] });
        setTimeout(() => map.invalidateSize(), 100);

        if (withoutCoords.length > 0) {
            const names = withoutCoords.map(l => l.name).join(', ');
            missingMsg.textContent = `${withoutCoords.length} location${withoutCoords.length === 1 ? '' : 's'} not shown (no coordinates): ${names}`;
            missingMsg.classList.remove('hidden');
        }

        // Hover any .location-card on the page → highlight matching pin.
        let hoverPinId = null;
        document.addEventListener('mouseover', (e) => {
            const card = e.target.closest('.location-card');
            if (!card) return;
            const locId = card.dataset.locationId;
            if (!markersById[locId] || locId === hoverPinId) return;
            if (hoverPinId) _unhighlight(hoverPinId);
            _highlight(locId);
            hoverPinId = locId;
        });
        document.addEventListener('mouseout', (e) => {
            const card = e.target.closest('.location-card');
            if (!card) return;
            const related = e.relatedTarget && e.relatedTarget.closest('.location-card');
            if (related === card) return;
            if (hoverPinId) {
                _unhighlight(hoverPinId);
                hoverPinId = null;
            }
        });

        function _highlight(locId) {
            const m = markersById[locId]; if (!m) return;
            m.setStyle({ radius: 12, fillColor: '#dc2626', weight: 3 });
            m.openTooltip();
            m.bringToFront();
        }
        function _unhighlight(locId) {
            const m = markersById[locId]; if (!m) return;
            m.setStyle({ radius: 8, fillColor: '#f48b1c', weight: 2 });
            m.closeTooltip();
        }
    }

    function _lmFlashCard(locId) {
        const card = document.querySelector(`.location-card[data-location-id="${locId}"]`);
        if (!card) return;
        card.scrollIntoView({ behavior: 'smooth', block: 'center' });
        card.classList.add('ring-2', 'ring-seismo-orange');
        setTimeout(() => card.classList.remove('ring-2', 'ring-seismo-orange'), 1500);
    }

    init();
})();
</script>
