/* global React */
const { useState: useStateMap, useMemo: useMemoMap, useEffect: useEffectMap, useRef: useRefMap } = React;

// Real GeoJSON-based map of Centro-Sul cearense — adapted for MRTI
function MapCS({ heatmap='talentos', onSelect, focused, onPersonaSelect }) {
  const [geo, setGeo] = useStateMap(null);
  const [hovered, setHovered] = useStateMap(null);
  const [tip, setTip] = useStateMap(null);

  useEffectMap(() => {
    fetch('mapdata.json').then(r => r.json()).then(setGeo);
  }, []);

  const W = 800, H = 600, PAD = 30;

  const project = useMemoMap(() => {
    if (!geo) return null;
    let minX=Infinity, minY=Infinity, maxX=-Infinity, maxY=-Infinity;
    for (const f of geo.centroSul.features) {
      walkCoordsMap(f.geometry, (lon, lat) => {
        if (lon<minX) minX=lon; if (lat<minY) minY=lat;
        if (lon>maxX) maxX=lon; if (lat>maxY) maxY=lat;
      });
    }
    const dx = maxX - minX, dy = maxY - minY;
    const midLat = (minY + maxY) / 2;
    const aspectFix = Math.cos(midLat * Math.PI / 180);
    const scaleX = (W - PAD*2) / dx;
    const scaleY = (H - PAD*2) / (dy / aspectFix);
    const scale = Math.min(scaleX, scaleY);
    const offX = PAD + ((W - PAD*2) - dx * scale) / 2;
    const offY = PAD + ((H - PAD*2) - (dy / aspectFix) * scale) / 2;
    return (lon, lat) => [
      offX + (lon - minX) * scale,
      offY + (maxY - lat) / aspectFix * scale,
    ];
  }, [geo]);

  const polyToPath = (geometry) => {
    if (!project) return '';
    const rings = geometry.type === 'Polygon' ? [geometry.coordinates] : geometry.coordinates;
    let d = '';
    for (const poly of rings) {
      for (const ring of poly) {
        ring.forEach(([lon, lat], i) => {
          const [x, y] = project(lon, lat);
          d += (i === 0 ? 'M' : 'L') + x.toFixed(1) + ' ' + y.toFixed(1) + ' ';
        });
        d += 'Z ';
      }
    }
    return d;
  };

  const centroid = useMemoMap(() => {
    if (!geo || !project) return {};
    const out = {};
    for (const f of geo.centroSul.features) {
      const rings = f.geometry.type === 'Polygon' ? f.geometry.coordinates : f.geometry.coordinates[0];
      let largest = rings[0], maxLen = rings[0].length;
      if (f.geometry.type === 'MultiPolygon') {
        for (const poly of f.geometry.coordinates) {
          if (poly[0].length > maxLen) { largest = poly[0]; maxLen = poly[0].length; }
        }
      }
      let sx = 0, sy = 0;
      for (const [lon, lat] of largest) { const [x, y] = project(lon, lat); sx += x; sy += y; }
      out[f.properties.name] = [sx / largest.length, sy / largest.length];
    }
    return out;
  }, [geo, project]);

  const munByName = useMemoMap(() => {
    const map = {};
    window.MUNICIPALITIES.forEach(m => { map[NAME_MAP_M[m.id] || m.nome] = m; });
    return map;
  }, []);

  const heat = useMemoMap(() => window.densidadePorMunicipio(heatmap), [heatmap]);
  const maxHeat = Math.max(...Object.values(heat), 1);

  if (!geo) return <div style={{padding:60, textAlign:'center', color:'#94A3B8'}}>Carregando mapa…</div>;

  const mrColors = window.MR_COLORS;
  const total = window.MUNICIPALITIES;

  // Color scale based on heatmap
  const heatColor = (v) => {
    if (v === 0) return '#E5F0FC';
    const t = v / maxHeat;
    // Light blue → deep blue
    const r = Math.round(229 + (11-229)*t);
    const g = Math.round(240 + (95-240)*t);
    const b = Math.round(252 + (190-252)*t);
    return `rgb(${r},${g},${b})`;
  };

  return (
    <div style={{position:'relative', width:'100%', height:'100%'}}>
      <svg viewBox={`0 0 ${W} ${H}`} className="map-svg" preserveAspectRatio="xMidYMid meet"
        onMouseMove={(e) => {
          if (hovered) {
            const r = e.currentTarget.getBoundingClientRect();
            setTip({x: e.clientX - r.left, y: e.clientY - r.top});
          }
        }}
        onMouseLeave={() => { setHovered(null); setTip(null); }}>
        <defs>
          <filter id="munShadow" x="-10%" y="-10%" width="120%" height="120%">
            <feGaussianBlur in="SourceAlpha" stdDeviation="1.2"/>
            <feOffset dx="0" dy="2" result="b"/>
            <feComponentTransfer><feFuncA type="linear" slope="0.18"/></feComponentTransfer>
            <feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>
          </filter>
        </defs>

        {/* surrounding ceará */}
        <g opacity=".55">
          {geo.surrounding.features.map((f, i) => (
            <path key={i} d={polyToPath(f.geometry)}
              fill="#EFF2F7" stroke="#D8DEE8" strokeWidth="0.6"/>
          ))}
        </g>
        {geo.excluded && (
          <g>{geo.excluded.features.map((f, i) => (
            <path key={i} d={polyToPath(f.geometry)} fill="#D8DEE8" stroke="#B5BCCB" strokeWidth="0.6"
                  style={{opacity:.6}}/>
          ))}</g>
        )}

        {/* Centro-Sul municipalities */}
        <g filter="url(#munShadow)">
          {geo.centroSul.features.map(f => {
            const mun = munByName[f.properties.name];
            if (!mun) return null;
            const isHover = hovered === mun.id;
            const isFocus = focused === mun.id;
            const v = heat[mun.id] || 0;
            const fill = heatmap === 'mr' ? mrColors[mun.mr] : heatColor(v);
            return (
              <path
                key={mun.id} d={polyToPath(f.geometry)} fill={fill}
                data-mun={mun.id}
                stroke={isHover || isFocus ? '#0E3F84' : '#fff'}
                strokeWidth={isHover || isFocus ? 2.2 : 1}
                style={{cursor:'pointer', transition:'stroke-width .12s'}}
                onMouseEnter={() => setHovered(mun.id)}
                onMouseLeave={() => setHovered(null)}
                onClick={() => onSelect && onSelect(mun.id)}
              />
            );
          })}
        </g>

        {/* labels */}
        <g style={{pointerEvents:'none'}}>
          {geo.centroSul.features.map(f => {
            const mun = munByName[f.properties.name];
            if (!mun) return null;
            const c = centroid[f.properties.name]; if (!c) return null;
            const isPolo = mun.isPolo;
            const v = heat[mun.id] || 0;
            const fillT = heatmap !== 'mr' && (v > maxHeat*0.5) ? '#fff' : (heatmap==='mr' ? '#fff' : '#1E293B');
            return (
              <g key={mun.id} transform={`translate(${c[0]}, ${c[1]})`}>
                <text textAnchor="middle" dominantBaseline="middle"
                  fontFamily="Outfit" fontWeight={isPolo?700:600}
                  fontSize={isPolo ? 11.5 : 8.5}
                  fill={fillT}
                  style={{textShadow:'0 1px 1px rgba(255,255,255,.4)', letterSpacing:.2}}>
                  {mun.nome.length > 16 ? mun.nome.split(' ')[0] : mun.nome}
                </text>
                {v > 0 && (
                  <g transform="translate(0, 11)">
                    <rect x="-14" y="-7" width="28" height="14" rx="7" fill="#0B1220" opacity=".82"/>
                    <text textAnchor="middle" dominantBaseline="middle" fontSize="9" fontWeight="700"
                      fontFamily="JetBrains Mono" fill="#fff">{v}</text>
                  </g>
                )}
              </g>
            );
          })}
        </g>
      </svg>

      {tip && hovered && (() => {
        const mun = window.MUNICIPALITIES.find(m => m.id === hovered);
        if (!mun) return null;
        const v = heat[mun.id] || 0;
        const labels = {talentos:'Talentos', projetos:'Projetos', eventos:'Eventos', mr:'Microrregião'};
        return (
          <div className="map-tooltip" style={{left: tip.x + 12, top: tip.y + 12}}>
            <div className="name">{mun.nome}</div>
            <div style={{fontSize:11, color:'rgba(255,255,255,.65)'}}>{window.MR_NAMES[mun.mr]}</div>
            <div className="stats">
              <div><span>{labels[heatmap]||'Valor'}</span> <strong>{v}</strong></div>
              <div><span>População</span> <strong>{(mun.pop/1000).toFixed(1)}k</strong></div>
            </div>
            <div style={{fontSize:10.5, marginTop:6, color:'rgba(255,255,255,.55)'}}>Clique para abrir o painel</div>
          </div>
        );
      })()}
    </div>
  );
}

const NAME_MAP_M = {
  'iguatu': 'Iguatu', 'piquet': 'Piquet Carneiro', 'irapuan': 'Deputado Irapuan Pinheiro',
  'acopiara': 'Acopiara', 'quixelo': 'Quixelô', 'oros': 'Orós', 'ico': 'Icó',
  'saboeiro': 'Saboeiro', 'jucas': 'Jucás', 'carius': 'Cariús', 'tarrafas': 'Tarrafas',
  'cedro': 'Cedro', 'lavras': 'Lavras da Mangabeira', 'umari': 'Umari',
  'baixio': 'Baixio', 'ipaumirim': 'Ipaumirim',
};

function walkCoordsMap(geom, fn) {
  function walk(c) {
    if (typeof c[0] === 'number') fn(c[0], c[1]);
    else c.forEach(walk);
  }
  walk(geom.coordinates);
}

window.MapCS = MapCS;
