// world-map.jsx — mapa mundial real (fronteiras verdadeiras via D3 + world-atlas)
// Carrega d3 + topojson-client + dados de países (110m) via CDN em tempo real no navegador.
// Sem pontos fictícios: os pinos vêm exclusivamente de compromissos reais enviados no formulário.

const MAP_W = 900, MAP_H = 460;

function loadScriptOnce(src) {
  return new Promise((resolve, reject) => {
    const existing = document.querySelector('script[data-src="' + src + '"]');
    if (existing) {
      if (existing.dataset.loaded === '1') return resolve();
      existing.addEventListener('load', () => resolve());
      existing.addEventListener('error', reject);
      return;
    }
    const s = document.createElement('script');
    s.src = src;
    s.dataset.src = src;
    s.onload = () => { s.dataset.loaded = '1'; resolve(); };
    s.onerror = reject;
    document.head.appendChild(s);
  });
}

function WorldMap({ pins }) {
  const canvasRef = React.useRef(null);
  const [status, setStatus] = React.useState('loading'); // loading | ready | error
  const projectionRef = React.useRef(null);
  const [, forceRender] = React.useState(0);

  React.useEffect(() => {
    let cancelled = false;

    async function init() {
      try {
        if (!window.d3) await loadScriptOnce('https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js');
        if (!window.topojson) await loadScriptOnce('https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js');
        const res = await fetch('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json');
        const topo = await res.json();
        if (cancelled) return;
        const countries = window.topojson.feature(topo, topo.objects.countries);

        const canvas = canvasRef.current;
        const dpr = Math.min(window.devicePixelRatio || 1, 2);
        canvas.width = MAP_W * dpr;
        canvas.height = MAP_H * dpr;
        canvas.style.width = '100%';
        canvas.style.height = 'auto';
        const ctx = canvas.getContext('2d');
        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

        const projection = window.d3.geoNaturalEarth1().fitSize([MAP_W, MAP_H - 20], countries);
        projection.translate([projection.translate()[0], projection.translate()[1] + 10]);
        const path = window.d3.geoPath(projection, ctx);

        ctx.clearRect(0, 0, MAP_W, MAP_H);
        ctx.beginPath();
        path(countries);
        ctx.fillStyle = 'rgba(230,197,124,0.30)';
        ctx.fill();
        ctx.lineWidth = 0.6;
        ctx.strokeStyle = 'rgba(230,197,124,0.55)';
        ctx.stroke();

        projectionRef.current = projection;
        setStatus('ready');
        forceRender((n) => n + 1);
      } catch (e) {
        if (!cancelled) setStatus('error');
      }
    }

    init();
    return () => { cancelled = true; };
  }, []);

  return (
    <div className="worldmap-wrap">
      <canvas ref={canvasRef} className="worldmap-canvas" aria-label="Mapa mundial da Cruzada"></canvas>
      {status === 'loading' && <div className="worldmap-status">Carregando mapa…</div>}
      {status === 'error' && <div className="worldmap-status">Mapa indisponível no momento.</div>}
      {status === 'ready' && (
        <div className="worldmap-pins">
          {pins.map((p, i) => {
            const proj = projectionRef.current;
            if (!proj) return null;
            const xy = proj([p.lng, p.lat]);
            if (!xy) return null;
            const left = (xy[0] / MAP_W) * 100;
            const top = (xy[1] / MAP_H) * 100;
            return (
              <div
                key={i}
                className={'worldmap-pin' + (p.isNew ? ' worldmap-pin-new' : '')}
                style={{ left: left + '%', top: top + '%' }}
                title={p.city}
              >
                <span className="worldmap-pin-dot"></span>
                <span className="worldmap-pin-ring"></span>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

window.WorldMap = WorldMap;
