/* ============================================================
   SILVERLINES — reusable location UI (INTERIM, keyless)
   MiniMap (Leaflet) + LocationPicker (search → pick → pin).
   Exposed on window so any module can drop in a real, findable,
   pin-able address. Swaps to Google later with no UI change.
   ============================================================ */
(function () {
  'use strict';
  var TILE = 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png';
  var TILE_LIGHT = 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png';

  /* --- Leaflet mini-map with a single marker --- */
  function MiniMap(props) {
    var host = useRef(null);
    var map = useRef(null);
    var lat = props.lat, lng = props.lng, height = props.height || 150;
    useEffect(function () {
      if (!window.L || !host.current || lat == null || lng == null) return;
      var day = (document.documentElement.dataset.theme === 'day');
      if (!map.current) {
        map.current = window.L.map(host.current, { zoomControl: false, attributionControl: true, scrollWheelZoom: false });
        window.L.tileLayer(day ? TILE_LIGHT : TILE, { maxZoom: 19, attribution: '© OpenStreetMap · © CARTO' }).addTo(map.current);
        map.current.__m = window.L.marker([lat, lng]).addTo(map.current);
      } else {
        map.current.__m.setLatLng([lat, lng]);
      }
      map.current.setView([lat, lng], 15);
      var t = setTimeout(function () { try { map.current && map.current.invalidateSize(); } catch (e) {} }, 60);
      return function () { clearTimeout(t); };
    }, [lat, lng]);
    useEffect(function () { return function () { if (map.current) { try { map.current.remove(); } catch (e) {} map.current = null; } }; }, []);
    if (lat == null || lng == null) return null;
    return <div ref={host} style={{ height: height, width: '100%' }} className="overflow-hidden rounded-lg border border-line" />;
  }
  window.MiniMap = MiniMap;

  /* --- address search → candidate list → pick → coords + pin --- */
  function LocationPicker(props) {
    var address = props.address || '', lat = props.lat, lng = props.lng;
    var onSet = props.onSet, showMap = props.showMap !== false, compact = props.compact;
    var s0 = useState(address); var q = s0[0], setQ = s0[1];
    var s1 = useState(null); var res = s1[0], setRes = s1[1];   // null=idle, []=none, [..]=hits
    var s2 = useState(false); var busy = s2[0], setBusy = s2[1];
    var s3 = useState(false); var open = s3[0], setOpen = s3[1];
    var timer = useRef(0), box = useRef(null);
    useEffect(function () { setQ(props.address || ''); }, [props.address]);
    useEffect(function () {
      var h = function (e) { if (box.current && !box.current.contains(e.target)) setOpen(false); };
      window.addEventListener('mousedown', h); return function () { window.removeEventListener('mousedown', h); };
    }, []);
    var run = async function (term) {
      setBusy(true); setOpen(true);
      try { setRes(await window.slGeoSearch(term)); } catch (e) { setRes([]); }
      setBusy(false);
    };
    var onType = function (v) {
      setQ(v);
      clearTimeout(timer.current);
      if (v.trim().length >= 4) timer.current = setTimeout(function () { run(v.trim()); }, 500);
      else { setRes(null); setOpen(false); }
    };
    var pick = function (r) {
      clearTimeout(timer.current);
      setQ(r.label); setOpen(false); setRes(null);
      onSet && onSet({ address: r.label, lat: r.lat, lng: r.lng });
    };
    var commitFree = function () { if (q !== address) onSet && onSet({ address: q, lat: null, lng: null }); }; // freeform edit clears the old pin so View/Directions can't route to a stale place
    var has = (lat != null && lng != null);
    return (
      <div className="relative" ref={box}>
        <div className="flex items-center gap-1.5 rounded-lg border border-line bg-ink-900 px-2.5 py-1.5 focus-within:border-electric/60">
          <Icon name="MapPin" size={12} className={cx('shrink-0', has ? 'text-electric-soft' : 'text-zinc-600')} />
          <input value={q} onChange={function (e) { onType(e.target.value); }}
            onKeyDown={function (e) { if (e.key === 'Enter') { e.preventDefault(); if (q.trim().length >= 3) run(q.trim()); } if (e.key === 'Escape') setOpen(false); }}
            onBlur={commitFree} placeholder="Search an address or place…"
            className="min-w-0 flex-1 bg-transparent text-[11.5px] text-zinc-200 outline-none placeholder:text-zinc-600" />
          {busy ? <Icon name="LoaderCircle" size={12} className="shrink-0 animate-spin text-zinc-500" />
                : <button onMouseDown={function (e) { e.preventDefault(); if (q.trim().length >= 3) run(q.trim()); }} title="Find on map" className="shrink-0 text-zinc-500 hover:text-electric-soft"><Icon name="Search" size={12} /></button>}
        </div>
        {open && res != null && (
          <div className="absolute left-0 right-0 z-40 mt-1 max-h-[220px] overflow-y-auto rounded-lg border border-line bg-ink-850 shadow-2xl">
            {res.length === 0 && !busy && <div className="px-3 py-2.5 text-[11px] text-zinc-500">No match — refine the address, or keep the text as-is.</div>}
            {res.map(function (r, i) {
              return (
                <button key={i} onMouseDown={function (e) { e.preventDefault(); pick(r); }}
                  className="flex w-full items-start gap-2 px-3 py-2 text-left transition-colors hover:bg-ink-800">
                  <Icon name="MapPin" size={12} className="mt-0.5 shrink-0 text-zinc-500" />
                  <span className="min-w-0"><span className="block truncate text-[12px] font-600 text-zinc-200">{r.short}</span>
                    <span className="block truncate text-[10.5px] text-zinc-500">{r.label}</span></span>
                </button>
              );
            })}
            <div className="border-t border-line px-3 py-1 text-[9px] uppercase tracking-wide text-zinc-600">Search · OpenStreetMap</div>
          </div>
        )}
        {showMap && has && (
          <div className="mt-2">
            <MiniMap lat={lat} lng={lng} height={compact ? 120 : 150} />
            <div className="mt-1.5 flex items-center gap-2">
              <a href={window.slMapsUrl(lat, lng)} target="_blank" rel="noreferrer"
                className="inline-flex items-center gap-1 rounded-md border border-line bg-ink-900 px-2 py-1 text-[10.5px] font-600 text-zinc-300 transition-colors hover:border-ink-600 hover:text-electric-soft"><Icon name="MapPinned" size={11} /> View</a>
              <a href={window.slDirUrl(lat, lng)} target="_blank" rel="noreferrer"
                className="inline-flex items-center gap-1 rounded-md border border-line bg-ink-900 px-2 py-1 text-[10.5px] font-600 text-zinc-300 transition-colors hover:border-ink-600 hover:text-electric-soft"><Icon name="Navigation" size={11} /> Directions</a>
              <span className="font-mono text-[9.5px] text-zinc-600">{(+lat).toFixed(4)}, {(+lng).toFixed(4)}</span>
            </div>
          </div>
        )}
      </div>
    );
  }
  window.LocationPicker = LocationPicker;
})();
