// ─────────────────────────────────────────────────────────────────────
// DyraListingsMap — Leaflet/OSM map with Airbnb/Vrbo-style approximate
// area circles per listing. Privacy-safe: the lat/lng we draw is the
// per-listing fuzzed coordinate the customer API returns, not the real
// address. Each circle is 300m, so the actual building sits *somewhere*
// inside the circle — never identified.
//
// Props:
//   listings  — array of properties; each must have lat/lng (or lat/lon).
//   onSelect  — (listing) => void; fires when a circle/popup is clicked.
//   palette   — { ink, accent, surface, muted, line } for theming.
//   height    — pixel height of the map container.
// ─────────────────────────────────────────────────────────────────────
// 770 Eastern Parkway — every Dyra map shows this as a fixed reference pin
// so guests can see where each home sits in relation to the Rebbe's shul.
// Coordinates verified via Nominatim's geocode of "770 Eastern Parkway,
// Brooklyn, NY 11213". Don't tweak by hand — re-geocode if you ever move.
const DYRA_REF_770 = { lat: 40.6689619, lng: -73.9427981, label: '770 Eastern Pkwy' };

function DyraListingsMap({ listings, onSelect, palette, height }) {
  const containerRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const layerRef = React.useRef(null);

  const items = (listings || [])
    .map(p => ({
      ...p,
      _lat: typeof p.lat === 'number' ? p.lat : (typeof p.lat === 'string' ? Number(p.lat) : null),
      _lng: typeof p.lng === 'number' ? p.lng
          : typeof p.lon === 'number' ? p.lon
          : null,
    }))
    .filter(p => Number.isFinite(p._lat) && Number.isFinite(p._lng));

  React.useEffect(() => {
    if (!containerRef.current) return;
    if (typeof window === 'undefined' || !window.L) return;
    const L = window.L;

    // Initialize map once.
    if (!mapRef.current) {
      mapRef.current = L.map(containerRef.current, {
        zoomControl: true,
        scrollWheelZoom: false,
        attributionControl: true,
      }).setView([DYRA_REF_770.lat, DYRA_REF_770.lng], 14);
      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
      }).addTo(mapRef.current);
    }

    // Re-render the listing layer.
    if (layerRef.current) {
      layerRef.current.clearLayers();
    } else {
      layerRef.current = L.layerGroup().addTo(mapRef.current);
    }

    const accent = (palette && palette.accent) || '#1a1a1a';

    // Always-on reference pin for 770 Eastern Parkway. Custom divIcon so it
    // reads as a labeled landmark, not a generic Leaflet pin (which would
    // visually compete with the listing circles).
    // The icon is laid out as a pill above an arrow whose tip points at the
    // landmark. Leaflet places `iconAnchor` AT the lat/lng — set it to the
    // bottom-center of the bounding box so the arrow tip lands on 770 itself.
    const ref770Icon = L.divIcon({
      className: 'dyra-770-pin',
      html: `<div style="display:flex;flex-direction:column;align-items:center;line-height:1;">
        <div style="background:#b8532a;color:#fff;font-family:Inter,system-ui,sans-serif;font-size:11px;font-weight:600;letter-spacing:0.04em;padding:4px 8px;border-radius:100px;white-space:nowrap;box-shadow:0 2px 6px rgba(0,0,0,0.18);">770</div>
        <div style="width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:8px solid #b8532a;margin-top:-1px;"></div>
      </div>`,
      iconSize: [50, 32],
      iconAnchor: [25, 32],
    });
    const ref770Marker = L.marker([DYRA_REF_770.lat, DYRA_REF_770.lng], {
      icon: ref770Icon,
      keyboard: false,
      title: DYRA_REF_770.label,
    }).addTo(layerRef.current);
    ref770Marker.bindPopup(
      `<div style="font-family:Inter,system-ui,sans-serif;font-size:12px;color:#2a241c;padding:2px 4px;">
        <div style="font-weight:600;">${DYRA_REF_770.label}</div>
        <div style="color:#6b5e47;margin-top:2px;">Reference landmark</div>
      </div>`,
      { closeButton: true }
    );

    if (!items.length) {
      // No listings have coords yet — center on 770 so users still see the
      // landmark and the "where Crown Heights starts" context.
      mapRef.current.setView([DYRA_REF_770.lat, DYRA_REF_770.lng], 15);
      return;
    }
    // Per-listing pin marker. Backend fuzzes the public lat/lng by ≤25m so
    // the pin sits within a 25m radius of the actual building — close enough
    // to read as a precise location, with the exact address still revealed
    // only after booking. Pins use the palette accent so they distinguish
    // visually from the orange 770 reference pin.
    items.forEach(p => {
      // Logo-stamped marker. Uses the actual brand logo from `window.DYRA_LOGO`
      // (base64 JPEG, same source the homepage header pulls from) on a white
      // chip with the brand accent color as the border and the arrow tip.
      const logoSrc = (typeof window !== 'undefined' && window.DYRA_LOGO) || '/logo/dyra-logo.png';
      const pinIcon = L.divIcon({
        className: 'dyra-listing-pin',
        html: `<div style="display:flex;flex-direction:column;align-items:center;line-height:1;">
          <div style="width:38px;height:38px;border-radius:50%;background:#fff;border:2px solid ${accent};box-shadow:0 2px 8px rgba(0,0,0,0.3);overflow:hidden;display:flex;align-items:center;justify-content:center;">
            <img src="${logoSrc}" alt="" style="width:34px;height:34px;object-fit:cover;display:block;"/>
          </div>
          <div style="width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:9px solid ${accent};margin-top:-2px;filter:drop-shadow(0 2px 2px rgba(0,0,0,0.25));"></div>
        </div>`,
        iconSize: [44, 49],
        iconAnchor: [22, 49],
      });
      const marker = L.marker([p._lat, p._lng], { icon: pinIcon, title: p.name || '' }).addTo(layerRef.current);

      const photoSrc = (p.photos && p.photos[0] && p.photos[0].src) || null;
      const photoHtml = photoSrc
        ? `<div style="width:100%;height:120px;background:#eee url('${photoSrc.replace(/'/g, "\\'")}') center/cover no-repeat;border-radius:8px;margin-bottom:8px;"></div>`
        : '';
      const priceLabel = p.priceFrom ? `From $${p.priceFrom} / night` : '';
      const popupHtml = `
        <div style="font-family:Inter,system-ui,sans-serif;min-width:200px;">
          ${photoHtml}
          <div style="font-family:'Cormorant Garamond',Georgia,serif;font-size:18px;font-weight:500;color:#2a241c;line-height:1.2;">${escapeHtml(p.name || '')}</div>
          <div style="font-size:12px;color:#6b5e47;margin-top:4px;">${escapeHtml(p.tagline || '')}</div>
          <div style="font-size:13px;color:#2a241c;margin-top:8px;font-weight:500;">${priceLabel}</div>
          <button data-dyra-select="${escapeHtml(p.id || '')}" style="margin-top:10px;width:100%;padding:8px 12px;background:${accent};color:#fff;border:none;border-radius:8px;font-size:12px;font-weight:600;cursor:pointer;letter-spacing:0.04em;text-transform:uppercase;">View listing</button>
        </div>`;
      marker.bindPopup(popupHtml, { closeButton: true, autoPan: true });
      marker.on('popupopen', () => {
        const btn = document.querySelector(`[data-dyra-select="${cssEscape(p.id || '')}"]`);
        if (btn) {
          btn.addEventListener('click', (e) => {
            e.preventDefault();
            if (onSelect) onSelect(p);
          }, { once: true });
        }
      });
    });

    // Fit bounds to show all listing pins AND the 770 reference pin so guests
    // can always see where each listing sits relative to the landmark.
    const boundsPoints = items.map(p => [p._lat, p._lng]);
    boundsPoints.push([DYRA_REF_770.lat, DYRA_REF_770.lng]);
    const bounds = L.latLngBounds(boundsPoints);
    if (bounds.isValid()) {
      mapRef.current.fitBounds(bounds.pad(0.4), { maxZoom: 16, animate: false });
    }
  }, [items.length, JSON.stringify(items.map(i => [i._lat, i._lng, i.id]))]);

  // Tear down on unmount.
  React.useEffect(() => {
    return () => {
      if (mapRef.current) {
        mapRef.current.remove();
        mapRef.current = null;
        layerRef.current = null;
      }
    };
  }, []);

  return (
    <div style={{ position: 'relative', height: height || 480, borderRadius: 16, overflow: 'hidden', border: `0.5px solid ${(palette && palette.line) || '#d9cfba'}`, background: (palette && palette.surface) || '#f5efe3' }}>
      <div ref={containerRef} style={{ position: 'absolute', inset: 0 }}/>
    </div>
  );
}

function escapeHtml(s) {
  return String(s).replace(/[&<>"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
}
function cssEscape(s) {
  // Best-effort selector escape. Listing ids are slug-shaped so this is plenty.
  return String(s).replace(/[^a-zA-Z0-9_-]/g, '\\$&');
}

if (typeof window !== 'undefined') {
  window.DyraListingsMap = DyraListingsMap;
}
