/* Cobertura — mapa de México vectorial, tilt 3D, marcadores animados + arcos */
(function () {
  const { useRef, useMemo, useState, useEffect } = React;

  /* Contorno de México (lon,lat). Lado E/S de datos reales (johan/world.geo.json),
     resto con anclas geográficas conocidas. Baja California va como polígono aparte
     (el hueco entre ambos lee como el Golfo de California) para evitar auto-cruces. */
  const MX_MAINLAND = [
    [-114.8,32.5],[-113.0,32.0],[-111.07,31.33],[-108.21,31.33],[-106.51,31.78],
    [-104.5,29.7],[-102.3,29.88],[-101.4,29.78],[-100.0,28.4],[-99.5,27.5],[-99.1,26.4],[-97.9,26.06],
    [-97.14,25.87],[-97.528,24.992],[-97.703,24.272],[-97.776,22.933],[-97.872,22.444],
    [-97.699,21.899],[-97.389,21.411],[-97.189,20.635],[-96.526,19.891],[-96.292,19.32],
    [-95.901,18.828],[-94.839,18.563],[-94.426,18.144],[-93.549,18.424],[-92.786,18.525],
    [-92.037,18.705],[-91.408,18.876],[-90.772,19.284],[-90.534,19.867],[-90.451,20.708],
    [-90.279,21.0],[-89.601,21.262],[-88.544,21.494],[-87.658,21.459],[-87.052,21.544],
    [-86.812,21.332],[-86.846,20.85],[-87.383,20.255],[-87.621,19.647],[-87.437,19.472],
    [-87.587,19.04],[-87.837,18.26],[-88.091,18.517],[-88.3,18.5],[-88.49,18.487],
    [-88.848,17.883],[-89.15,17.955],[-89.143,17.808],
    [-90.6,17.82],[-91.0,17.13],[-90.99,16.07],[-92.2,15.0],[-92.23,14.54],
    [-93.36,15.5],[-94.5,16.3],[-95.3,15.9],[-96.5,15.65],[-98.0,16.3],[-99.9,16.85],
    [-101.5,17.6],[-103.5,18.4],[-104.99,19.32],[-105.49,20.4],[-105.69,21.5],
    [-106.42,23.2],[-108.2,25.0],[-109.2,26.5],[-110.5,27.5],[-111.8,28.8],
    [-112.8,30.0],[-113.6,31.0],[-114.8,32.0],
  ];
  const MX_BAJA = [
    [-117.0,32.5],[-115.0,32.3],[-114.6,31.4],[-113.4,29.8],[-112.4,28.2],
    [-111.2,26.3],[-110.2,24.5],[-109.5,23.2],[-109.9,22.85],
    [-111.8,24.8],[-112.6,26.0],[-113.7,27.3],[-114.8,28.8],[-116.0,30.3],[-117.0,31.8],
  ];

  function useProjection() {
    return useMemo(() => {
      const W = 1000;
      const lat0 = 24, k = Math.cos((lat0 * Math.PI) / 180);
      const raw = (lon, lat) => [lon * k, -lat];
      const all = [...MX_MAINLAND, ...MX_BAJA].map(([lo, la]) => raw(lo, la));
      let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
      all.forEach(([x, y]) => { minX = Math.min(minX, x); maxX = Math.max(maxX, x); minY = Math.min(minY, y); maxY = Math.max(maxY, y); });
      const pad = 40;
      const scale = (W - pad * 2) / (maxX - minX);
      const H = (maxY - minY) * scale + pad * 2;
      const project = (lon, lat) => {
        const [x, y] = raw(lon, lat);
        return [pad + (x - minX) * scale, pad + (y - minY) * scale];
      };
      const toPath = (ring) => ring.map(([lo, la], i) => (i ? "L" : "M") + project(lo, la).map((n) => n.toFixed(1)).join(" ")).join(" ") + " Z";
      const pct = (lon, lat) => { const [x, y] = project(lon, lat); return { left: (x / W) * 100, top: (y / H) * 100 }; };
      return { W, H, project, paths: [toPath(MX_MAINLAND), toPath(MX_BAJA)], pct };
    }, []);
  }

  function Cobertura({ data }) {
    const c = data.coverage;
    const proj = useProjection();
    const planeRef = useRef(null);
    const [active, setActive] = useState("CDMX");

    useEffect(() => {
      const el = planeRef.current; if (!el) return;
      if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
      const onMove = (e) => {
        const r = el.getBoundingClientRect();
        const px = (e.clientX - r.left) / r.width - 0.5;
        const py = (e.clientY - r.top) / r.height - 0.5;
        el.style.transform = `rotateX(${18 - py * 10}deg) rotateZ(${px * 6}deg) rotateY(${px * 4}deg)`;
      };
      const reset = () => { el.style.transform = "rotateX(18deg) rotateZ(0deg) rotateY(0deg)"; };
      reset();
      el.addEventListener("mousemove", onMove);
      el.addEventListener("mouseleave", reset);
      return () => { el.removeEventListener("mousemove", onMove); el.removeEventListener("mouseleave", reset); };
    }, []);

    const actuales = c.states.filter((s) => !s.soon);
    const proximos = c.states.filter((s) => s.soon);
    const hub = c.states.find((s) => s.name === "CDMX") || c.states[0];
    const hubP = proj.project(hub.ll[0], hub.ll[1]);
    const arcs = c.states.filter((s) => s.hub && !s.soon && s.name !== "CDMX").map((s) => {
      const p = proj.project(s.ll[0], s.ll[1]);
      const mx = (hubP[0] + p[0]) / 2, my = (hubP[1] + p[1]) / 2;
      const lift = Math.hypot(p[0] - hubP[0], p[1] - hubP[1]) * 0.18;
      return `M${hubP[0].toFixed(1)} ${hubP[1].toFixed(1)} Q${mx.toFixed(1)} ${(my - lift).toFixed(1)} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`;
    });

    return (
      <section id="cobertura" className="section cobertura">
        <div className="cob__bg dotgrid" />
        <div className="wrap cob__head reveal">
          <span className="eyebrow">{c.eyebrow}</span>
          <h2 className="h2">{c.title}</h2>
          <p className="lead">{c.lead}</p>
        </div>

        <div className="wrap cob__layout">
          <div className="cob__stage reveal" data-d="1">
            <div className="cob__glow" />
            <div className="cob__plane" ref={planeRef}>
              <svg className="cob__svg" viewBox={`0 0 ${proj.W} ${proj.H}`} preserveAspectRatio="xMidYMid meet">
                <defs>
                  <linearGradient id="landg" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0" stopColor="var(--map-land-2)" />
                    <stop offset="1" stopColor="var(--map-land)" />
                  </linearGradient>
                </defs>
                {/* extrusión (grosor) */}
                {[10, 8, 6, 4, 2].map((dy, i) => (
                  proj.paths.map((d, j) => (
                    <path key={i + "-" + j} d={d} transform={`translate(0 ${dy})`} fill="var(--map-edge)" opacity={0.9} />
                  ))
                ))}
                {proj.paths.map((d, i) => (
                  <path key={"top" + i} d={d} fill="url(#landg)" stroke="var(--accent)" strokeOpacity="0.45" strokeWidth="1.5" />
                ))}
                {/* arcos de red */}
                <g className="cob__arcs">
                  {arcs.map((d, i) => <path key={i} d={d} fill="none" stroke="var(--accent)" strokeWidth="1.6" strokeLinecap="round" />)}
                </g>
              </svg>

              <div className="cob__markers">
                {c.states.map((s) => {
                  const p = proj.pct(s.ll[0], s.ll[1]);
                  const on = active === s.name;
                  return (
                    <button
                      key={s.name}
                      className={"mk " + (s.hub ? "mk--hub " : "") + (s.soon ? "mk--soon " : "") + (on ? "mk--on" : "")}
                      style={{ left: p.left + "%", top: p.top + "%" }}
                      onMouseEnter={() => setActive(s.name)}
                      onFocus={() => setActive(s.name)}
                      aria-label={s.soon ? s.name + " (próximamente)" : s.name}
                    >
                      {!s.soon && <span className="mk__ring" />}
                      <span className="mk__dot" />
                      <span className="mk__label">{s.soon ? s.name + " · Próximamente" : s.name}</span>
                    </button>
                  );
                })}
              </div>
            </div>
          </div>

          <aside className="cob__aside reveal" data-d="2">
            <div className="cob__count card">
              <span className="cob__count-n">{actuales.length}</span>
              <span className="cob__count-l">estados con presencia</span>
            </div>
            <div className="cob__chips">
              {actuales.map((s) => (
                <button
                  key={s.name}
                  className={"cob__chip " + (active === s.name ? "cob__chip--on" : "")}
                  onMouseEnter={() => setActive(s.name)}
                  onClick={() => setActive(s.name)}
                >
                  <Icon name="mapPin" size={14} /> {s.name}
                </button>
              ))}
            </div>
            {proximos.length > 0 && (
              <div>
                <span className="cob__soon-h">Próximamente</span>
                <div className="cob__chips">
                  {proximos.map((s) => (
                    <button
                      key={s.name}
                      className={"cob__chip cob__chip--soon " + (active === s.name ? "cob__chip--on" : "")}
                      onMouseEnter={() => setActive(s.name)}
                      onClick={() => setActive(s.name)}
                    >
                      <Icon name="clock" size={14} /> {s.name}
                    </button>
                  ))}
                </div>
              </div>
            )}
            <a className="btn btn-primary" href="#contacto" onClick={(e) => { e.preventDefault(); document.querySelector("#contacto")?.scrollIntoView({ behavior: "smooth" }); }}>
              ¿Tu estado no aparece? Contáctanos <Icon name="arrowRight" size={18} />
            </a>
          </aside>
        </div>
      </section>
    );
  }

  window.Cobertura = Cobertura;
})();
