/* Torre Auro — Mapa de competencia por nicho (decisión por nivel) */

const _nicheCache = {}; // eco → places[]

function _hav(aLat, aLng, bLat, bLng) {
  const R = 6371000, toR = Math.PI / 180;
  const dLat = (bLat - aLat) * toR, dLng = (bLng - aLng) * toR;
  const s = Math.sin(dLat/2)**2 + Math.cos(aLat*toR)*Math.cos(bLat*toR)*Math.sin(dLng/2)**2;
  return 2 * R * Math.asin(Math.sqrt(s));
}

function NicheMap({ floor }) {
  const z = ZONES[floor.zone];
  const eco = z.eco;
  const comp = NICHE_COMPETITION[eco] || NICHE_COMPETITION.corporativo;
  const acc = z.accHex;

  const mapRef = useRef(null);
  const clusterRef = useRef(null);
  const placesRef = useRef([]);
  const [ring, setRing] = useState(3000);
  const [status, setStatus] = useState('cargando');
  const [counts, setCounts] = useState({ 1000:0, 3000:0, 5000:0 });
  const ringRef = useRef(3000);

  function applyFilter() {
    const cl = clusterRef.current; if (!cl) return;
    cl.clearLayers();
    const r = ringRef.current;
    cl.addLayers(placesRef.current.filter(p => p.dist <= r).map(p => p.marker));
  }

  async function fetchNiche(signal) {
    if (_nicheCache[eco]) return _nicheCache[eco];
    const { lat, lng } = TORRE_COORD;
    const out = []; const seen = new Set();
    try {
      const url = `https://www.inegi.org.mx/app/api/denue/v1/consulta/Buscar/${encodeURIComponent(comp.term)}/${lat},${lng}/5000/${DENUE_TOKEN}`;
      const res = await fetch(url, { signal });
      if (res.ok) {
        const data = await res.json();
        (data || []).forEach(row => {
          const la = parseFloat(row.Latitud), ln = parseFloat(row.Longitud);
          if (!la || !ln) return;
          const id = row.Id || (row.Nombre + la + ln);
          if (seen.has(id)) return; seen.add(id);
          out.push({ lat:la, lng:ln, name: row.Nombre || row.Razon_social || 'Establecimiento', clase: row.Clase_actividad || '', dist: _hav(lat, lng, la, ln) });
        });
      }
    } catch (e) { /* ignore */ }
    _nicheCache[eco] = out;
    return out;
  }

  useEffect(() => {
    if (!window.L || mapRef.current) return;
    const el = document.getElementById('nichemap-' + floor.id);
    if (!el) return;
    let cancelled = false;
    const ac = new AbortController();
    const { lat, lng } = TORRE_COORD;

    const map = window.L.map(el, { center:[lat,lng], zoom:14, scrollWheelZoom:false, zoomControl:true, attributionControl:false });
    mapRef.current = map;
    window.L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', { maxZoom:19 }).addTo(map);

    [5000,3000,1000].forEach(r => window.L.circle([lat,lng], { radius:r, color:acc, weight:1, opacity:.4, fill:false, dashArray:'4 6' }).addTo(map));

    const torreIcon = window.L.divIcon({ className:'lmk-torre-wrap', html:'<div class="lmk-torre nichetorre"><span class="lmk-torre-dot"></span><span class="lmk-torre-flag">Torre Auro · exclusividad</span></div>', iconSize:[0,0] });
    window.L.marker([lat,lng], { icon:torreIcon, zIndexOffset:1000 }).addTo(map);

    const cluster = window.L.markerClusterGroup({
      maxClusterRadius:90, showCoverageOnHover:false, spiderfyOnMaxZoom:false, disableClusteringAtZoom:17, chunkedLoading:true,
      iconCreateFunction: (c) => {
        const n = c.getChildCount();
        const size = n < 8 ? 40 : n < 20 ? 56 : n < 45 ? 74 : 92;
        return window.L.divIcon({ className:'lmk-blob-wrap', html:`<span class="lmk-blob" style="--c:${acc};width:${size}px;height:${size}px"></span>`, iconSize:[size,size] });
      },
    });
    clusterRef.current = cluster;
    map.addLayer(cluster);
    map.setView([lat,lng], 13);

    (async () => {
      const places = await fetchNiche(ac.signal);
      if (cancelled || mapRef.current !== map) return;
      places.forEach(p => {
        const icon = window.L.divIcon({ className:'lmk-pin-wrap', html:`<span class="lmk-pin" style="--c:${acc}"><span class="lmk-pin-ring"></span></span>`, iconSize:[16,16], iconAnchor:[8,8] });
        p.marker = window.L.marker([p.lat,p.lng], { icon });
        p.marker.bindTooltip(`<b>${p.name}</b><br>${p.clase || ''}`, { direction:'top', offset:[0,-8], className:'lmk-tip' });
      });
      placesRef.current = places;
      const c = { 1000:0, 3000:0, 5000:0 };
      places.forEach(p => { if (p.dist<=1000) c[1000]++; if (p.dist<=3000) c[3000]++; if (p.dist<=5000) c[5000]++; });
      setCounts(c);
      applyFilter();
      setStatus(places.length ? 'ok' : 'empty');
    })();

    return () => { cancelled = true; ac.abort(); map.remove(); mapRef.current = null; clusterRef.current = null; placesRef.current = []; };
  }, [floor.id]);

  function pickRing(r) { setRing(r); ringRef.current = r; applyFilter(); }
  const RINGS = [{ v:1000, l:'1 km' }, { v:3000, l:'3 km' }, { v:5000, l:'5 km' }];
  const nearby = counts[ring] || 0;

  return (
    <section className="section tight" style={{ background:'var(--navy)' }}>
      <div className="container">
        <div className="section-head" style={{ marginBottom:40 }}>
          <div className="kicker light">04 / Tu competencia</div>
          <h2 style={{ color:'#fff', fontSize:'clamp(32px,4vw,48px)' }}>El mercado está <em style={{ color: acc, fontFamily:'var(--serif)', fontStyle:'italic' }}>afuera.</em><br/>La exclusividad, <em style={{ color: acc, fontFamily:'var(--serif)', fontStyle:'italic' }}>adentro.</em></h2>
          <p style={{ color:'rgba(255,255,255,.72)' }}>Torre Auro garantiza exclusividad de giro por categoría. Esto significa cero competencia directa de tu nicho dentro del edificio — mientras el mercado de {comp.label} ya está activo en el entorno inmediato.</p>
        </div>

        <div className="nm-grid">
          <div className="nm-mapwrap">
            <div id={'nichemap-' + floor.id} className="nm-map" aria-label={`Competencia de ${comp.label} cerca de Torre Auro`}></div>
            <div className="nm-rings">
              <span className="nm-rings-lbl">Radio</span>
              {RINGS.map(r => (
                <button key={r.v} className={`locmap-ring ${ring === r.v ? 'on' : ''}`} onClick={() => pickRing(r.v)}>{r.l}</button>
              ))}
            </div>
          </div>

          <aside className="nm-panel">
            <div className="nm-stat nm-stat-hero" style={{ '--acc': acc }}>
              <span className="nm-stat-n">0</span>
              <span className="nm-stat-lbl">competidores de tu giro <b>dentro de Torre Auro</b></span>
              <span className="nm-stat-tag" style={{ color: acc, borderColor: acc }}>Exclusividad de giro garantizada</span>
            </div>

            <div className="nm-stat">
              <span className="nm-stat-n2">{status === 'cargando' ? '···' : nearby}</span>
              <span className="nm-stat-lbl2">{comp.label} a {ring/1000} km — <b>demanda activa del mercado</b></span>
              <span className="nm-stat-src">{status === 'cargando' ? 'Consultando DENUE · INEGI…' : status === 'empty' ? 'Sin registros DENUE en el radio' : 'Fuente: DENUE · INEGI'}</span>
            </div>

            <p className="nm-read">
              {nearby > 0
                ? <>Hay <b>{nearby} {comp.label}</b> operando en {ring/1000} km: el mercado de tu giro ya existe y tiene flujo. Al instalarte en {floor.sh}, capturas esa demanda <b>sin competir contra nadie dentro del edificio</b>.</>
                : <>Al instalarte en {floor.sh} aseguras tu giro en el edificio con exclusividad de categoría.</>}
            </p>

            <div className="nm-cta">
              <button className="btn btn-gold btn-sm" onClick={() => openChat(floor.id)}>Asegurar mi giro <Icon n="ti-arrow-right" /></button>
            </div>
          </aside>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { NicheMap });
