"use client"

import { useEffect, useRef } from "react"
import type * as Leaflet from "leaflet"
import "leaflet/dist/leaflet.css"
import "./property-map.css"

export type MapMarker = {
  id: string
  name: string
  lat: number
  lng: number
  subtitle?: string
  href?: string
}

// Indigo pin as an inline SVG divIcon — avoids Leaflet's default marker image
// assets (which break under bundlers) and matches the app accent.
const PIN_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="28" height="28" fill="#6366f1" stroke="#0b0b12" stroke-width="1.2"><path d="M12 0.5C6.9 0.5 2.8 4.6 2.8 9.7c0 6.6 8.2 13.9 8.6 14.2a0.9 0.9 0 0 0 1.2 0c0.4-0.3 8.6-7.6 8.6-14.2C21.2 4.6 17.1 0.5 12 0.5z"/><circle cx="12" cy="9.7" r="3.3" fill="#0b0b12"/></svg>`

function escapeHtml(s: string): string {
  return s.replace(/[&<>"']/g, (c) =>
    ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c] as string
  )
}

/**
 * Leaflet map (OpenStreetMap tiles) rendering property markers. Client-only:
 * Leaflet touches `window`, so it's dynamically imported inside an effect.
 */
export function PropertyMap({
  markers,
  className = "h-72 w-full",
  zoom = 15,
}: {
  markers: MapMarker[]
  className?: string
  zoom?: number
}) {
  const containerRef = useRef<HTMLDivElement>(null)
  const mapRef = useRef<Leaflet.Map | null>(null)

  useEffect(() => {
    let cancelled = false

    void (async () => {
      const mod = await import("leaflet")
      const L = ((mod as unknown as { default?: typeof Leaflet }).default ?? mod) as typeof Leaflet
      if (cancelled || !containerRef.current || mapRef.current) return

      const map = L.map(containerRef.current, {
        scrollWheelZoom: false,
        zoomControl: true,
      })
      mapRef.current = map

      L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
        attribution:
          '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        maxZoom: 19,
      }).addTo(map)

      const icon = L.divIcon({
        html: PIN_SVG,
        className: "pmn-map-pin",
        iconSize: [28, 28],
        iconAnchor: [14, 28],
        popupAnchor: [0, -26],
      })

      const latlngs: [number, number][] = []
      for (const m of markers) {
        if (!Number.isFinite(m.lat) || !Number.isFinite(m.lng)) continue
        const marker = L.marker([m.lat, m.lng], { icon }).addTo(map)
        const link = m.href
          ? `<div style="margin-top:4px"><a href="${escapeHtml(m.href)}">View details →</a></div>`
          : ""
        const sub = m.subtitle ? `<div style="color:#9ca3af">${escapeHtml(m.subtitle)}</div>` : ""
        marker.bindPopup(`<div style="font-weight:600">${escapeHtml(m.name)}</div>${sub}${link}`)
        latlngs.push([m.lat, m.lng])
      }

      if (latlngs.length === 1) {
        map.setView(latlngs[0], zoom)
      } else if (latlngs.length > 1) {
        map.fitBounds(latlngs, { padding: [40, 40] })
      } else {
        map.setView([39.8283, -98.5795], 4) // continental US fallback
      }

      // Tiles can render blank if the container sized after init.
      setTimeout(() => map.invalidateSize(), 0)
    })()

    return () => {
      cancelled = true
      mapRef.current?.remove()
      mapRef.current = null
    }
  }, [markers, zoom])

  return <div ref={containerRef} className={`pmn-map-dark ${className}`} />
}
