// Daoob Real Estate — Suhail-style interactive map
// Real OSM tiles + parcel polygons + district price-per-sqm heatmap + click loads rich data

const LeafletMap = ({
  parcels,
  zoning,
  districts,
  selectedId,
  onSelect,
  basemap = "street",
  filterZones = null,
  lang = "en",
  heatmap = true,
  onMapClick,                // (latlng, nearestParcelId) => void  — for "drop pin anywhere"
}) => {
  const containerRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const layerRef = React.useRef({ base: null, heat: null, parcels: null });
  const selectedRef = React.useRef(selectedId);

  // ===== Geometry helpers =====
  const centerFor = (p) => {
    const d = districts[p.district];
    const seed = p.id.split("").reduce((a, c) => a + c.charCodeAt(0), 0);
    const sign1 = (seed % 2 ? 1 : -1);
    const sign2 = ((seed >> 2) % 2 ? 1 : -1);
    const ox = ((seed * 7) % 100) / 14000 * sign1;
    const oy = ((seed * 11) % 100) / 14000 * sign2;
    return [d.lat + oy, d.lng + ox];
  };

  const polygonFor = (p) => {
    const [cy, cx] = centerFor(p);
    const seed = p.id.split("").reduce((a, c) => a + c.charCodeAt(0), 0);
    const ext = Math.max(Math.sqrt(p.area) / 110000 * 8, 0.0024);
    const j = (n) => ((seed * n) % 5 - 2) * 0.00018;
    return [
      [cy - ext + j(1), cx - ext + j(2)],
      [cy - ext + j(3), cx + ext + j(4)],
      [cy + ext + j(5), cx + ext + j(6)],
      [cy + ext + j(7), cx - ext + j(8)],
    ];
  };

  // ===== Init map =====
  React.useEffect(() => {
    if (!containerRef.current || mapRef.current) return;
    const map = L.map(containerRef.current, {
      center: [24.7136, 46.6753],
      zoom: 12,
      zoomControl: false,
      attributionControl: true,
      minZoom: 10,
      maxZoom: 18,
    });
    mapRef.current = map;
    L.control.zoom({ position: "topright" }).addTo(map);

    // Re-sync size after layout settles
    const ro = new ResizeObserver(() => {
      if (mapRef.current) mapRef.current.invalidateSize({ animate: false });
    });
    ro.observe(containerRef.current);
    requestAnimationFrame(() => map.invalidateSize({ animate: false }));
    const t = setTimeout(() => map.invalidateSize({ animate: false }), 250);

    // Click ANYWHERE on the map → drop a visible pin → snap to nearest parcel
    let dropPin = null;
    const onClick = (e) => {
      const { lat, lng } = e.latlng;

      // Drop a visible gold pin where user clicked
      if (dropPin) map.removeLayer(dropPin);
      dropPin = L.marker([lat, lng], {
        icon: L.divIcon({
          className: "daoob-droppin",
          html: `<div class="dp-wrap">
                   <div class="dp-pulse"></div>
                   <div class="dp-pin"></div>
                 </div>`,
          iconSize: [36, 48],
          iconAnchor: [18, 44],
        }),
      });
      dropPin.addTo(map);

      // Find nearest parcel within ~1.5km
      let best = null;
      let bestDist = Infinity;
      parcels.forEach(p => {
        const seed = p.id.split("").reduce((a, c) => a + c.charCodeAt(0), 0);
        const sign1 = (seed % 2 ? 1 : -1);
        const sign2 = ((seed >> 2) % 2 ? 1 : -1);
        const ox = ((seed * 7) % 100) / 14000 * sign1;
        const oy = ((seed * 11) % 100) / 14000 * sign2;
        const d = districts[p.district];
        const py = d.lat + oy;
        const px = d.lng + ox;
        const dist = Math.hypot(py - lat, px - lng);
        if (dist < bestDist) { bestDist = dist; best = p; }
      });
      if (best) onSelect(best.id);
      if (onMapClick) onMapClick({ lat, lng }, best ? best.id : null);
    };
    map.on("click", onClick);

    return () => {
      map.off("click", onClick);
      if (dropPin) map.removeLayer(dropPin);
      ro.disconnect();
      clearTimeout(t);
      map.remove();
      mapRef.current = null;
    };
  }, [parcels, districts, onMapClick, onSelect]);

  // ===== Basemap =====
  React.useEffect(() => {
    if (!mapRef.current) return;
    const map = mapRef.current;
    if (layerRef.current.base) map.removeLayer(layerRef.current.base);
    let tile;
    if (basemap === "satellite") {
      tile = L.tileLayer(
        "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
        { maxZoom: 19, attribution: "Tiles &copy; Esri" }
      );
    } else if (basemap === "dark") {
      tile = L.tileLayer(
        "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
        { maxZoom: 19, attribution: "&copy; OpenStreetMap &copy; CARTO" }
      );
    } else {
      // street (default) — light Voyager
      tile = L.tileLayer(
        "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
        { maxZoom: 19, attribution: "&copy; OpenStreetMap &copy; CARTO" }
      );
    }
    tile.addTo(map);
    layerRef.current.base = tile;
  }, [basemap]);

  // ===== District price-per-sqm heatmap =====
  // Compute avg price per district; render colored circle per district
  const districtStats = React.useMemo(() => {
    const stats = {};
    Object.keys(districts).forEach(k => stats[k] = { count: 0, totalPrice: 0, totalArea: 0 });
    parcels.forEach(p => {
      if (!p.price) return;
      const s = stats[p.district];
      s.count++;
      s.totalPrice += p.price;
      s.totalArea += p.area;
    });
    Object.keys(stats).forEach(k => {
      const s = stats[k];
      s.avgPrice = s.count > 0 ? Math.round(s.totalPrice / s.count) : 0;
      s.totalValue = s.totalPrice * 0; // unused
    });
    return stats;
  }, [parcels, districts]);

  // Color scale by price/sqm
  const priceColor = (price) => {
    if (!price) return "#5a5247";
    if (price >= 140) return "#7C2D12"; // dark red
    if (price >= 100) return "#C2410C"; // red
    if (price >= 80)  return "#D97757"; // orange
    if (price >= 60)  return "#C8A35A"; // gold
    if (price >= 50)  return "#5BA77A"; // green
    return "#4A8A6B"; // dark green
  };

  React.useEffect(() => {
    if (!mapRef.current) return;
    const map = mapRef.current;
    if (layerRef.current.heat) map.removeLayer(layerRef.current.heat);
    if (!heatmap) return;

    // Only render district labels (no overlapping translucent circles — they block clicks visually)
    const group = L.featureGroup();
    Object.entries(districts).forEach(([key, d]) => {
      const s = districtStats[key];
      if (!s || s.count === 0) return;
      const color = priceColor(s.avgPrice);
      const label = L.marker([d.lat, d.lng], {
        icon: L.divIcon({
          className: "daoob-district-label",
          html: `<div class="ddl" style="border-color:${color}66;"><div class="ddl-n">${d[lang]}</div><div class="ddl-p" style="color:${color};">${s.avgPrice.toLocaleString()} <span>${lang === "ar" ? "ر.س/م²" : "SAR/m²"}</span></div></div>`,
          iconSize: [130, 38],
          iconAnchor: [65, 60],   // offset DOWN so labels don't cover parcel dots
        }),
        interactive: false,
        keyboard: false,
      });
      label.addTo(group);
    });
    group.addTo(map);
    layerRef.current.heat = group;
  }, [districts, districtStats, heatmap, lang]);

  // ===== Parcel polygons + markers =====
  React.useEffect(() => {
    const map = mapRef.current;
    if (!map) return;
    if (layerRef.current.parcels) map.removeLayer(layerRef.current.parcels);

    const visible = filterZones && filterZones.length
      ? parcels.filter(p => filterZones.includes(p.zone))
      : parcels;

    const group = L.featureGroup();
    visible.forEach(p => {
      const isSelected = p.id === selectedId;
      const z = zoning[p.zone];
      const district = districts[p.district][lang];
      const pColor = priceColor(p.price);

      const tip = `<div class="daoob-tip-inner">
        <div class="dtt-ref">${p.id}</div>
        <div class="dtt-dist">${district}</div>
        <div class="dtt-meta">${z[lang]} · ${p.area.toLocaleString()} m²</div>
        ${p.price ? `<div class="dtt-price">${p.price} <span>${lang === "ar" ? "ر.س/م²" : "SAR/m²"}</span></div>` : ""}
        <div class="dtt-cta">${lang === "ar" ? "↳ انقر لعرض كل البيانات" : "↳ Click for full data"}</div>
      </div>`;

      // Parcel polygon
      const poly = L.polygon(polygonFor(p), {
        color: isSelected ? "#C8A35A" : pColor,
        weight: isSelected ? 3 : 1.5,
        fillColor: pColor,
        fillOpacity: isSelected ? 0.6 : 0.35,
      });
      poly.bindTooltip(tip, { className: "daoob-tip", sticky: true, direction: "top", offset: [0, -8] });
      poly.on("click", (e) => {
        L.DomEvent.stopPropagation(e);
        onSelect(p.id);
      });
      poly.addTo(group);

      // Always-clickable circle marker on top — BIG, glowing, hard to miss
      const ctr = centerFor(p);
      const dot = L.circleMarker(ctr, {
        radius: isSelected ? 16 : 13,
        color: "#FFFFFF",
        weight: 3,
        fillColor: isSelected ? "#C8A35A" : pColor,
        fillOpacity: 1,
        pane: "markerPane",
        className: "daoob-parcel-dot",
      });
      dot.bindTooltip(tip, { className: "daoob-tip", sticky: true, direction: "top", offset: [0, -14] });
      dot.on("click", (e) => {
        L.DomEvent.stopPropagation(e);
        onSelect(p.id);
      });
      dot.addTo(group);

      // Pulse ring on selected
      if (isSelected) {
        L.circleMarker(ctr, {
          radius: 30, color: "#C8A35A", weight: 3, opacity: 0.85, fillOpacity: 0,
          interactive: false, className: "daoob-pulse-ring",
        }).addTo(group);
      }
    });
    group.addTo(map);
    layerRef.current.parcels = group;

    // Pan to selected
    if (selectedId && selectedId !== selectedRef.current) {
      const sel = visible.find(p => p.id === selectedId);
      if (sel) {
        const ctr = centerFor(sel);
        map.flyTo(ctr, Math.max(map.getZoom(), 14), { duration: 0.7 });
      }
    }
    selectedRef.current = selectedId;
  }, [parcels, zoning, districts, selectedId, filterZones, lang]);

  return (
    <div className="map-canvas" style={{ background: "#e8e4d4" }}>
      <div ref={containerRef} style={{ position: "absolute", inset: 0 }}/>

      {/* Click-hint banner top-center */}
      <div className="map-clickhint">
        <span className="ch-dot"/>
        {lang === "ar" ? "انقر أي مكان على الخريطة لإسقاط دبوس وعرض البيانات" : "Click anywhere on the map to drop a pin and view data"}
      </div>

      {/* Heatmap legend bottom-left */}
      <div className="map-heatlegend">
        <div className="mhl-h">{lang === "ar" ? "السعر ر.س/م²" : "Price SAR/m²"}</div>
        <div className="mhl-bar">
          <span style={{ background: "#4A8A6B" }}/>
          <span style={{ background: "#5BA77A" }}/>
          <span style={{ background: "#C8A35A" }}/>
          <span style={{ background: "#D97757" }}/>
          <span style={{ background: "#C2410C" }}/>
          <span style={{ background: "#7C2D12" }}/>
        </div>
        <div className="mhl-ticks">
          <span>&lt;50</span>
          <span>80</span>
          <span>120</span>
          <span>150+</span>
        </div>
      </div>

      {/* Amanat link */}
      <a
        href="https://maps.alriyadh.gov.sa/geoportal/geomap"
        target="_blank"
        rel="noopener noreferrer"
        className="geoportal-link"
        title={lang === "ar" ? "افتح بوابة أمانة الرياض" : "Open Amanat Riyadh Geoportal"}
      >
        <span style={{ width: 18, height: 18, borderRadius: 3, background: "var(--green-700)", color: "var(--gold-400)", display: "grid", placeItems: "center", fontSize: 10, fontWeight: 700 }}>أ</span>
        <span>{lang === "ar" ? "بيانات أمانة الرياض" : "Amanat Riyadh data"}</span>
        <Icon name="external" size={12}/>
      </a>
    </div>
  );
};

Object.assign(window, { LeafletMap });
