// Карта Центральной Азии на реальных границах стран (GeoJSON)
const { useEffect, useState, useRef } = React;

const COUNTRY_META = {
  KAZ: { id: 'KAZ', label: 'КАЗАХСТАН', fill: 'rgba(10,26,47,0.92)', hover: '#0A1A2F' },
  UZB: { id: 'UZB', label: 'УЗБЕКИСТАН', fill: 'rgba(10,26,47,0.78)', hover: '#0A1A2F' },
  KGZ: { id: 'KGZ', label: 'КЫРГЫЗСТАН', fill: 'rgba(10,26,47,0.72)', hover: '#0A1A2F' },
  RUS: { id: 'RUS', label: 'РОССИЯ', fill: 'rgba(10,26,47,0.10)', stroke: 'rgba(10,26,47,0.30)' },
};

const FILES = ['KAZ', 'UZB', 'KGZ', 'RUS'];

// Города в широте/долготе
const CITIES = [
  { lon: 37.6173, lat: 55.7558, name: 'МОСКВА', role: 'origin', delay: 0.0 },
  { lon: 76.8897, lat: 43.2389, name: 'АЛМАТЫ · ШТАБ', role: 'hq', delay: 0.85 },
  { lon: 69.2401, lat: 41.2995, name: 'ТАШКЕНТ', role: 'sub', delay: 0.6 },
  { lon: 74.5698, lat: 42.8746, name: 'БИШКЕК', role: 'sub', delay: 0.7 },
  { lon: 71.4491, lat: 51.1694, name: 'АСТАНА', role: 'capital', delay: 0.4 },
];

const COUNTRY_LABELS = {
  KAZ: { lon: 66.7, lat: 47.5 },
  UZB: { lon: 64.8, lat: 40.5 },
  KGZ: { lon: 73.9, lat: 42.8 },
  RUS: { lon: 42.4, lat: 55.55 },
};

const MAP_BOUNDS = {
  minLon: 34,
  maxLon: 86,
  minLat: 39,
  maxLat: 58,
};

const VIEWBOX = { w: 1000, h: 700, padL: 25, padR: 25, padT: 35, padB: 35 };

function projectLonLat(lon, lat) {
  const innerW = VIEWBOX.w - VIEWBOX.padL - VIEWBOX.padR;
  const innerH = VIEWBOX.h - VIEWBOX.padT - VIEWBOX.padB;
  const x = VIEWBOX.padL + ((lon - MAP_BOUNDS.minLon) / (MAP_BOUNDS.maxLon - MAP_BOUNDS.minLon)) * innerW;
  const y = VIEWBOX.padT + ((MAP_BOUNDS.maxLat - lat) / (MAP_BOUNDS.maxLat - MAP_BOUNDS.minLat)) * innerH;
  return [x, y];
}

function ringToPath(ring) {
  if (!ring || !ring.length) return '';
  const commands = ring.map((pair, index) => {
    const [x, y] = projectLonLat(pair[0], pair[1]);
    return `${index === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`;
  });
  return `${commands.join(' ')} Z`;
}

function polygonToPath(coordinates) {
  // Берем внешнее кольцо, без внутренних дырок для чистой визуализации
  return ringToPath(coordinates[0]);
}

function featureToPath(feature) {
  if (!feature || !feature.geometry) return '';
  if (feature.geometry.type === 'Polygon') return polygonToPath(feature.geometry.coordinates);
  if (feature.geometry.type === 'MultiPolygon') {
    return feature.geometry.coordinates.map((poly) => polygonToPath(poly)).join(' ');
  }
  return '';
}

function getFeature(entry) {
  if (!entry) return null;
  if (entry.type === 'Feature') return entry;
  if (entry.type === 'FeatureCollection' && Array.isArray(entry.features) && entry.features.length) {
    return entry.features[0];
  }
  return null;
}

function ringIntersectsBounds(ring, pad = 1.2) {
  const minLon = MAP_BOUNDS.minLon - pad;
  const maxLon = MAP_BOUNDS.maxLon + pad;
  const minLat = MAP_BOUNDS.minLat - pad;
  const maxLat = MAP_BOUNDS.maxLat + pad;
  return ring.some(([lon, lat]) => lon >= minLon && lon <= maxLon && lat >= minLat && lat <= maxLat);
}

function sanitizeFeature(entry) {
  const feature = getFeature(entry);
  if (!feature?.geometry) return null;

  if (feature.geometry.type === 'Polygon') {
    if (!ringIntersectsBounds(feature.geometry.coordinates[0])) return null;
    return feature;
  }

  if (feature.geometry.type === 'MultiPolygon') {
    const filtered = feature.geometry.coordinates.filter((polygon) => ringIntersectsBounds(polygon[0]));
    if (!filtered.length) return null;
    return {
      ...feature,
      geometry: {
        ...feature.geometry,
        coordinates: filtered,
      },
    };
  }
  return null;
}

function centroidFromBBox(feature) {
  const bbox = feature?.bbox;
  if (bbox && bbox.length >= 4) {
    const [minLon, minLat, maxLon, maxLat] = bbox;
    return projectLonLat((minLon + maxLon) / 2, (minLat + maxLat) / 2);
  }
  const geometry = feature?.geometry;
  if (!geometry) return [500, 350];

  const points = [];
  const pushRing = (ring) => {
    ring.forEach(([lon, lat]) => points.push([lon, lat]));
  };
  if (geometry.type === 'Polygon') {
    pushRing(geometry.coordinates[0]);
  } else if (geometry.type === 'MultiPolygon') {
    geometry.coordinates.forEach((polygon) => pushRing(polygon[0]));
  }
  if (!points.length) return [500, 350];

  const sums = points.reduce(
    (acc, [lon, lat]) => {
      acc.lon += lon;
      acc.lat += lat;
      return acc;
    },
    { lon: 0, lat: 0 }
  );
  return projectLonLat(sums.lon / points.length, sums.lat / points.length);
}

function CentralAsiaMap() {
  const ref = useRef(null);
  const [progress, setProgress] = useState(0);
  const [hovered, setHovered] = useState(null);
  const [features, setFeatures] = useState({});

  useEffect(() => {
    let cancelled = false;
    Promise.all(
      FILES.map((code) =>
        fetch(`geo/${code}.geo.json`).then((r) => r.json()).then((f) => [code, f])
      )
    )
      .then((entries) => {
        if (cancelled) return;
        const next = {};
        entries.forEach(([code, feature]) => {
          next[code] = sanitizeFeature(feature);
        });
        setFeatures(next);
      })
      .catch(() => {
        // Держим страницу рабочей, даже если один из файлов недоступен
      });
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      ([e]) => {
        if (e.isIntersecting) {
          const start = performance.now();
          const dur = 3200;
          const tick = (t) => {
            const p = Math.min(1, (t - start) / dur);
            const eased = 1 - Math.pow(1 - p, 3);
            setProgress(eased);
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
          io.disconnect();
        }
      },
      { threshold: 0.25 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);

  const countryAt = (start, end) => Math.max(0, Math.min(1, (progress - start) / (end - start)));
  const arcLen = 1200;
  const arcP = countryAt(0.55, 1.0);
  const [moscowX, moscowY] = projectLonLat(37.6173, 55.7558);
  const [almatyX, almatyY] = projectLonLat(76.8897, 43.2389);
  const arcPath = `M ${moscowX},${moscowY} C ${moscowX + 120},${moscowY - 35} ${almatyX - 130},${almatyY - 90} ${almatyX},${almatyY}`;
  const kzCenter = projectLonLat(COUNTRY_LABELS.KAZ.lon, COUNTRY_LABELS.KAZ.lat);
  const uzCenter = projectLonLat(COUNTRY_LABELS.UZB.lon, COUNTRY_LABELS.UZB.lat);
  const kgCenter = projectLonLat(COUNTRY_LABELS.KGZ.lon, COUNTRY_LABELS.KGZ.lat);
  const bottomStripY = VIEWBOX.h - 22;
  const bottomLatY = VIEWBOX.h - 10;
  const bottomCoordY = VIEWBOX.h - 2;

  return (
    <div className="map-card" ref={ref}>
      <div className="cap">РИС. 01 — ЦЕЛЕВЫЕ РЫНКИ</div>
      <div className="cap-r">ЦЕНТРАЛЬНАЯ АЗИЯ · 2026</div>

      <svg viewBox={`0 0 ${VIEWBOX.w} ${VIEWBOX.h}`} preserveAspectRatio="xMidYMid meet" aria-hidden="true">
        <defs>
          <pattern id="dotgrid" width="20" height="20" patternUnits="userSpaceOnUse">
            <circle cx="1" cy="1" r="0.7" fill="rgba(10,26,47,0.12)" />
          </pattern>
          <linearGradient id="arcGrad" x1="0" y1="0" x2="1" y2="1">
            <stop offset="0" stopColor="#0A1A2F" />
            <stop offset="1" stopColor="#E2522B" />
          </linearGradient>
          <radialGradient id="hqGlow" cx="0.5" cy="0.5" r="0.5">
            <stop offset="0" stopColor="#E2522B" stopOpacity="0.4" />
            <stop offset="1" stopColor="#E2522B" stopOpacity="0" />
          </radialGradient>
        </defs>

        <rect width="1000" height="700" fill="url(#dotgrid)" />

        <g fontFamily="JetBrains Mono, monospace" fontSize="9" fill="rgba(10,26,47,0.46)" letterSpacing="1.5">
          <text x="14" y={projectLonLat(45, 60)[1] + 2}>60°С.Ш</text>
          <text x="14" y={projectLonLat(45, 55)[1] + 2}>55°С.Ш</text>
          <text x="14" y={projectLonLat(45, 45)[1] + 2}>45°С.Ш</text>
          <text x="14" y={bottomLatY}>38°С.Ш</text>
        </g>
        <g fontFamily="JetBrains Mono, monospace" fontSize="9" fill="rgba(10,26,47,0.46)" letterSpacing="1.5">
          <text x={projectLonLat(50, 36)[0] - 12} y={bottomCoordY}>50°В.Д</text>
          <text x={projectLonLat(65, 36)[0] - 12} y={bottomCoordY}>65°В.Д</text>
          <text x={projectLonLat(75, 36)[0] - 12} y={bottomCoordY}>75°В.Д</text>
          <text x={projectLonLat(85, 36)[0] - 12} y={bottomCoordY}>85°В.Д</text>
        </g>

        {features.RUS && (
          <>
            <path
              d={featureToPath(features.RUS)}
              fill={COUNTRY_META.RUS.fill}
              stroke={COUNTRY_META.RUS.stroke}
              strokeWidth="1.2"
              strokeDasharray="4,4"
              style={{ opacity: countryAt(0, 0.25), transform: `translateY(${(1 - countryAt(0, 0.25)) * 12}px)` }}
            />
            <text
              x={projectLonLat(COUNTRY_LABELS.RUS.lon, COUNTRY_LABELS.RUS.lat)[0]}
              y={projectLonLat(COUNTRY_LABELS.RUS.lon, COUNTRY_LABELS.RUS.lat)[1]}
              fontFamily="Fraunces, serif"
              fontSize="56"
              fill="rgba(90,102,120,0.9)"
              letterSpacing="-0.02em"
              style={{ opacity: countryAt(0.05, 0.3) }}
            >
              РОССИЯ
            </text>
          </>
        )}

        {['KAZ', 'UZB', 'KGZ'].map((code, index) => {
          const feature = features[code];
          if (!feature) return null;
          const meta = COUNTRY_META[code];
          const timings = {
            KAZ: [0.15, 0.5],
            UZB: [0.35, 0.6],
            KGZ: [0.42, 0.65],
          };
          const [start, end] = timings[code];
          return (
            <path
              key={code}
              d={featureToPath(feature)}
              fill={hovered === code ? meta.hover : meta.fill}
              stroke="#0A1A2F"
              strokeWidth={index === 0 ? '1.4' : '1.15'}
              onMouseEnter={() => setHovered(code)}
              onMouseLeave={() => setHovered(null)}
              style={{
                opacity: countryAt(start, end),
                transition: 'fill .25s ease',
                cursor: 'pointer',
              }}
            />
          );
        })}

        <text x={kzCenter[0]} y={kzCenter[1] + 18} textAnchor="middle" fontFamily="Fraunces, serif" fontSize="56" fill="#F5F3EE" letterSpacing="-0.025em" style={{ opacity: countryAt(0.3, 0.6) }}>
          КАЗАХСТАН
        </text>
        <text x={kzCenter[0]} y={kzCenter[1] + 44} textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="11" fill="rgba(245,243,238,0.6)" letterSpacing="3" style={{ opacity: countryAt(0.45, 0.7) }}>
          ИНДЕКС EGDI 24 · НАСЕЛЕНИЕ 19.6М
        </text>
        <text
          x={uzCenter[0]}
          y={uzCenter[1]}
          textAnchor="middle"
          fontFamily="Fraunces, serif"
          fontSize="16"
          fill="rgba(245,243,238,0.98)"
          letterSpacing="-0.01em"
          style={{ opacity: countryAt(0.4, 0.65), paintOrder: 'stroke', stroke: 'rgba(10,26,47,0.55)', strokeWidth: '0.8px' }}
        >
          УЗБЕКИСТАН
        </text>
        <text
          x={uzCenter[0]}
          y={uzCenter[1] + 16}
          textAnchor="middle"
          fontFamily="JetBrains Mono, monospace"
          fontSize="8.5"
          fill="rgba(245,243,238,0.9)"
          letterSpacing="0.9"
          style={{ opacity: countryAt(0.45, 0.72), paintOrder: 'stroke', stroke: 'rgba(10,26,47,0.5)', strokeWidth: '0.65px' }}
        >
          НАСЕЛЕНИЕ 36М · IT РЫНОК ~$4.2МЛРД
        </text>
        <text x={kgCenter[0]} y={kgCenter[1]} textAnchor="middle" fontFamily="Fraunces, serif" fontSize="13" fill="#F5F3EE" letterSpacing="-0.005em" style={{ opacity: countryAt(0.5, 0.7) }}>
          КЫРГЫЗСТАН
        </text>
        <text x={kgCenter[0]} y={kgCenter[1] + 13} textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="7.8" fill="rgba(245,243,238,0.82)" letterSpacing="0.7" style={{ opacity: countryAt(0.52, 0.75) }}>
          НАСЕЛЕНИЕ 7.2М · IT РЫНОК ~$0.45МЛРД
        </text>
        <text x={kzCenter[0]} y={kzCenter[1] + 61} textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="10.5" fill="rgba(245,243,238,0.72)" letterSpacing="1.8" style={{ opacity: countryAt(0.48, 0.76) }}>
          IT РЫНОК ~$3.6МЛРД
        </text>

        <path d={arcPath} fill="none" stroke="url(#arcGrad)" strokeWidth="2" strokeDasharray={arcLen} strokeDashoffset={arcLen - arcLen * arcP} strokeLinecap="round" />

        {arcP > 0.3 && arcP < 1 && (
          <circle r="3.5" fill="#E2522B">
            <animateMotion dur="3s" repeatCount="indefinite" path={arcPath} />
          </circle>
        )}

        <circle cx={almatyX} cy={almatyY} r="60" fill="url(#hqGlow)" style={{ opacity: arcP }} />

        {CITIES.map((c) => {
          const p = countryAt(c.delay, Math.min(1, c.delay + 0.15));
          const isHQ = c.role === 'hq';
          const isOrig = c.role === 'origin';
          const color = isHQ ? '#E2522B' : '#0A1A2F';
          const [x, y] = projectLonLat(c.lon, c.lat);
          return (
            <g key={c.name} style={{ opacity: p }}>
              {isHQ && (
                <>
                  <circle cx={x} cy={y} r="5" fill={color} />
                  <circle cx={x} cy={y} r="14" fill="none" stroke={color} strokeWidth="0.8" opacity="0.5" />
                  <circle cx={x} cy={y} r="22" fill="none" stroke={color} strokeWidth="0.5" opacity="0.3">
                    <animate attributeName="r" values="14;46;14" dur="2.6s" repeatCount="indefinite" />
                    <animate attributeName="opacity" values="0.5;0;0.5" dur="2.6s" repeatCount="indefinite" />
                  </circle>
                </>
              )}
              {isOrig && (
                <>
                  <circle cx={x} cy={y} r="4" fill="#0A1A2F" />
                  <circle cx={x} cy={y} r="9" fill="none" stroke="#0A1A2F" strokeWidth="0.6" opacity="0.4" />
                </>
              )}
              {!isHQ && !isOrig && <circle cx={x} cy={y} r="2.5" fill="#F5F3EE" stroke="#0A1A2F" strokeWidth="1" />}
              <text
                x={x + (c.name === 'БИШКЕК' ? 6 : 12)}
                y={y + (c.name === 'БИШКЕК' ? 12 : -6)}
                fontFamily="JetBrains Mono, monospace"
                fontSize={isHQ ? '13' : '10'}
                fontWeight={isHQ ? '600' : '400'}
                fill={isHQ ? '#E2522B' : isOrig ? '#0A1A2F' : 'rgba(245,243,238,0.9)'}
                letterSpacing="1"
              >
                {c.name}
              </text>
            </g>
          );
        })}

        <g transform={`translate(20, ${bottomStripY})`}>
          <text fontFamily="JetBrains Mono, monospace" fontSize="11" fill="rgba(10,26,47,0.68)" letterSpacing="2">
            КОРИДОР РАСШИРЕНИЯ · {Math.round(progress * 100)}% ПОКРЫТО · IT-ЭКСПОРТ $1.14МЛРД · ВВП +5.1%
          </text>
        </g>

        {hovered && (
          <g transform="translate(505, 42)">
            <rect x="0" y="0" width="445" height="74" fill="#0A1A2F" />
            <text x="14" y="22" fontFamily="JetBrains Mono, monospace" fontSize="10" fill="rgba(245,243,238,0.55)" letterSpacing="2">
              ФОКУС · {COUNTRY_META[hovered]?.label || hovered}
            </text>
            <text x="14" y="50" fontFamily="Fraunces, serif" fontSize="16" fill="#F5F3EE" letterSpacing="-0.005em">
              {hovered === 'KAZ' ? 'Казахстан · 19.6М · IT ~$3.6МЛРД' : hovered === 'UZB' ? 'Узбекистан · 36М · IT ~$4.2МЛРД' : hovered === 'KGZ' ? 'Кыргызстан · 7.2М · IT ~$0.45МЛРД' : 'Россия · 146М · IT ~$43МЛРД'}
            </text>
          </g>
        )}
      </svg>
    </div>
  );
}

window.CentralAsiaMap = CentralAsiaMap;
