// frontend/src/KGMap/KyrgyzstanMap.jsx

import React, { useRef, useEffect, useState } from 'react';
import mapboxgl from 'mapbox-gl';
import './KyrgyzstanMap.scss';
import 'mapbox-gl/dist/mapbox-gl.css';
import Header from '../Header/Header'; // Импортируем Header
import Button from '../Button/Button'; // Импортируем Button для возможных кнопок

// Замените на ваш реальный токен доступа Mapbox
mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_ACCESS_TOKEN;

const KyrgyzstanMap = ({ user }) => {
  const mapContainer = useRef(null);
  const map = useRef(null);

  // Состояния для управления картой
  const [mapLoaded, setMapLoaded] = useState(false);
  const [selectedFeature, setSelectedFeature] = useState(null);
  const [hoveredFeature, setHoveredFeature] = useState(null);
  const [layersVisibility, setLayersVisibility] = useState({
    'admin_boundaries-fill': true,
    'admin_boundaries-outline': true,
    'mountains': true,
    'rivers': true,
    'waterbodies-fill': true,
    'cities-symbol': true,
  });

  useEffect(() => {
    if (map.current) return; // Инициализируем карту только один раз

    // Инициализация карты, центрированной на Кыргызстане
    map.current = new mapboxgl.Map({
      container: mapContainer.current,
      style: 'mapbox://styles/mapbox/streets-v12', // Выберите предпочтительный стиль
      center: [74.7661, 41.2044], // Координаты Бишкека
      zoom: 7,
    });

    // Добавление навигационных контролей
    map.current.addControl(new mapboxgl.NavigationControl());

    // Обработка события загрузки карты
    map.current.on('load', () => {
      // Загрузка GeoJSON источников
      const layers = ['admin_boundaries', 'mountains', 'rivers', 'waterbodies', 'cities'];

      layers.forEach(layer => {
        map.current.addSource(layer, {
          type: 'geojson',
          data: `/geo/${layer}`, // Убедитесь, что эти эндпоинты обслуживают правильные GeoJSON данные
        });
      });

      // Добавление слоев с конкретными стилями

      // Административные границы
      map.current.addLayer({
        id: 'admin_boundaries-fill',
        type: 'fill',
        source: 'admin_boundaries',
        paint: {
          'fill-color': '#627BC1',
          'fill-opacity': 0.1,
        },
      });

      map.current.addLayer({
        id: 'admin_boundaries-outline',
        type: 'line',
        source: 'admin_boundaries',
        paint: {
          'line-color': '#627BC1',
          'line-width': 2,
        },
      });

      // Горы
      map.current.addLayer({
        id: 'mountains',
        type: 'circle',
        source: 'mountains',
        paint: {
          'circle-radius': 6,
          'circle-color': '#B8860B',
          'circle-stroke-color': '#FFA500',
          'circle-stroke-width': 2,
        },
      });

      // Реки
      map.current.addLayer({
        id: 'rivers',
        type: 'line',
        source: 'rivers',
        layout: {
          'line-join': 'round',
          'line-cap': 'round',
        },
        paint: {
          'line-color': '#00BFFF',
          'line-width': 3,
        },
      });

      // Водоемы
      map.current.addLayer({
        id: 'waterbodies-fill',
        type: 'fill',
        source: 'waterbodies',
        paint: {
          'fill-color': '#1E90FF',
          'fill-opacity': 0.5,
        },
      });

      // Города
      map.current.addLayer({
        id: 'cities-symbol',
        type: 'symbol',
        source: 'cities',
        layout: {
          'icon-image': 'harbor-15', // Использование встроенной иконки; измените по необходимости
          'icon-size': 1.5,
          'text-field': ['get', 'name'],
          'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],
          'text-offset': [0, 1.25],
          'text-anchor': 'top',
        },
        paint: {
          'text-color': '#000000',
          'text-halo-color': '#FFFFFF',
          'text-halo-width': 1,
        },
      });

      // Указываем, что карта загружена
      setMapLoaded(true);

      // Настройка интерактивности после добавления слоев
      setupInteractivity();
    });

    // Очистка при размонтировании компонента
    return () => map.current.remove();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!mapLoaded) return; // Убедиться, что карта загружена перед манипуляциями

    // Переключение видимости слоев на основе состояния
    Object.keys(layersVisibility).forEach(layer => {
      if (map.current.getLayer(layer)) {
        map.current.setLayoutProperty(
          layer,
          'visibility',
          layersVisibility[layer] ? 'visible' : 'none'
        );
      } else {
        console.warn(`Layer '${layer}' не существует на карте.`);
      }
    });
  }, [layersVisibility, mapLoaded]);

  const setupInteractivity = () => {
    // Инициализация всплывающего окна
    const popup = new mapboxgl.Popup({
      closeButton: true,
      closeOnClick: true,
    });

    // Обработка кликов по слоям
    map.current.on('click', ['mountains', 'rivers', 'waterbodies-fill', 'cities-symbol'], (e) => {
      const feature = e.features[0];
      const coordinates = e.lngLat;
      let description = '';

      switch (feature.layer.id) {
        case 'mountains':
          description = `<strong>Гора:</strong> ${feature.properties.name}<br/><strong>Высота:</strong> ${feature.properties.height} м`;
          break;
        case 'rivers':
          description = `<strong>Река:</strong> ${feature.properties.name}<br/><strong>Протяженность:</strong> ${feature.properties.length} км`;
          break;
        case 'waterbodies-fill':
          description = `<strong>Водоем:</strong> ${feature.properties.name}<br/><strong>Тип:</strong> ${feature.properties.type}`;
          break;
        case 'cities-symbol':
          description = `<strong>Город:</strong> ${feature.properties.name}<br/><strong>Население:</strong> ${feature.properties.population}`;
          break;
        default:
          description = 'Нет информации';
      }

      // Установка содержимого и позиции всплывающего окна
      popup.setLngLat(coordinates).setHTML(description).addTo(map.current);

      // Установка выбранного объекта для дополнительных функций, если необходимо
      setSelectedFeature(feature.properties);
    });

    // Изменение курсора на указатель при наведении
    map.current.on('mouseenter', ['mountains', 'rivers', 'waterbodies-fill', 'cities-symbol'], () => {
      map.current.getCanvas().style.cursor = 'pointer';
    });

    map.current.on('mouseleave', ['mountains', 'rivers', 'waterbodies-fill', 'cities-symbol'], () => {
      map.current.getCanvas().style.cursor = '';
    });

    // Обработка наведения для отображения информации
    map.current.on('mousemove', ['mountains', 'rivers', 'waterbodies-fill', 'cities-symbol'], (e) => {
      const feature = e.features[0];
      setHoveredFeature(feature.properties);
    });

    // Удаление информации при покидании области наведения
    map.current.on('mouseleave', ['mountains', 'rivers', 'waterbodies-fill', 'cities-symbol'], () => {
      setHoveredFeature(null);
    });
  };

  const toggleLayer = (layerName) => {
    setLayersVisibility(prev => ({
      ...prev,
      [layerName]: !prev[layerName],
    }));
  };

  return (
    <div className="kyrgyzstan-map">
      {/* Интеграция Header */}
      <Header user={user} title="Карта Кыргызстана" />

      <main className="map-main">
        <div ref={mapContainer} className="map-box" />

        {/* Панель управления слоями */}
        <div className="layer-controls">
          <h3>Управление слоями</h3>
          {Object.keys(layersVisibility).map(layer => (
            <div key={layer} className="layer-control">
              <input
                type="checkbox"
                id={`toggle-${layer}`}
                checked={layersVisibility[layer]}
                onChange={() => toggleLayer(layer)}
              />
              <label htmlFor={`toggle-${layer}`}>
                {layer
                  .replace('_fill', '')
                  .replace('_outline', '')
                  .replace('_symbol', '')
                  .replace('_', ' ')
                  .replace(/\b\w/g, l => l.toUpperCase())}
              </label>
            </div>
          ))}
        </div>

        {/* Панель информации о выбранном объекте */}
        {selectedFeature && (
          <div className="info-panel">
            <h3>Информация об объекте</h3>
            <p><strong>Название:</strong> {selectedFeature.name}</p>
            {selectedFeature.height && <p><strong>Высота:</strong> {selectedFeature.height} м</p>}
            {selectedFeature.length && <p><strong>Протяженность:</strong> {selectedFeature.length} км</p>}
            {selectedFeature.type && <p><strong>Тип:</strong> {selectedFeature.type}</p>}
            {selectedFeature.population && <p><strong>Население:</strong> {selectedFeature.population}</p>}
            <Button variant="danger" onClick={() => setSelectedFeature(null)}>Закрыть</Button>
          </div>
        )}

        {/* Всплывающая информация при наведении */}
        {hoveredFeature && (
          <div className="hover-info">
            <p>{hoveredFeature.name}</p>
          </div>
        )}
      </main>
    </div>
  );
};

export default KyrgyzstanMap;



почему не отображается карта кыргызстана




вот для сравнения код для карты мира здесь все правильно отображается

// src/Map/MapPage.jsx

import React, { useState, useRef, useEffect, useCallback } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import './MapPage.scss';
import Header from '../Header/Header';


const MapPage = ({ user }) => {
  const [is3D, setIs3D] = useState(false);
  const [isPanelOpen, setIsPanelOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [suggestions, setSuggestions] = useState([]);
  const [countryInfo, setCountryInfo] = useState(null);
  const mapContainer = useRef(null);
  const map = useRef(null);

  // Функция инициализации карты
  const initializeMap = useCallback(() => {
    if (map.current) return;

    const mapOptions = {
      container: mapContainer.current,
      style: 'mapbox://styles/mapbox/satellite-streets-v12', // Стиль карты
      center: [0, 0], // Начальная позиция [долгота, широта]
      zoom: 1, // Начальный зум
      projection: is3D ? 'globe' : 'mercator', // 3D глобус или плоская карта
    };

    try {
      map.current = new mapboxgl.Map(mapOptions);
      map.current.addControl(new mapboxgl.NavigationControl(), 'top-right');

      if (is3D) {
        map.current.on('style.load', () => {
          map.current.setFog({}); // Установка атмосферы
        });
      }
    } catch (error) {
      console.error('Ошибка при инициализации карты:', error);
    }
  }, [is3D]);

  // Инициализация карты при монтировании и при изменении is3D
  useEffect(() => {
    const removeMap = () => {
      if (map.current) {
        map.current.remove();
        map.current = null;
      }
    };

    initializeMap();

    // Очищаем карту при размонтировании или изменении is3D
    return () => {
      removeMap();
    };
  }, [initializeMap]);

  // Переключение между 2D и 3D
  const toggle3D = () => {
    setIs3D((prev) => !prev);
  };

  // Переключение панели управления
  const togglePanel = () => {
    setIsPanelOpen((prev) => !prev);
  };

  // Поиск стран через Mapbox Geocoding API
  const searchCountry = async (query) => {
    if (!query) {
      setSuggestions([]);
      return;
    }
    try {
      const response = await fetch(
        `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(
          query
        )}.json?types=country&autocomplete=true&limit=5&access_token=${mapboxgl.accessToken}`
      );
      const data = await response.json();
      if (data.features) {
        setSuggestions(data.features);
      } else {
        setSuggestions([]);
      }
    } catch (error) {
      console.error('Ошибка при поиске страны:', error);
    }
  };

  // Обработка изменения ввода поиска
  const handleSearchChange = (e) => {
    const value = e.target.value;
    setSearchQuery(value);
    searchCountry(value);
  };

  // Выбор страны из подсказок
  const selectCountry = (country) => {
    const [lng, lat] = country.center;
    if (map.current) {
      map.current.flyTo({
        center: [lng, lat],
        zoom: 5,
        essential: true, // Обязательная анимация
      });
  
      if (country.bbox) {
        map.current.fitBounds(country.bbox, { padding: 50 });
      }
    }

    setCountryInfo(country);
    setSuggestions([]);
  };

  // Смена стиля карты
  const addLayer = (layerStyle) => {
    const styleMap = {
      streets: 'mapbox://styles/mapbox/streets-v12',
      satellite: 'mapbox://styles/mapbox/satellite-v9',
      light: 'mapbox://styles/mapbox/light-v10',
      dark: 'mapbox://styles/mapbox/dark-v10',
      outdoors: 'mapbox://styles/mapbox/outdoors-v12',
      'navigation-day': 'mapbox://styles/mapbox/navigation-day-v1',
      'navigation-night': 'mapbox://styles/mapbox/navigation-night-v1',
      'satellite-streets': 'mapbox://styles/mapbox/satellite-streets-v12',
    };
    if (styleMap[layerStyle] && map.current) {
      map.current.setStyle(styleMap[layerStyle]);

      if (is3D) {
        map.current.once('style.load', () => {
          map.current.setFog({});
        });
      }
    }
  };

  // Обновляем карту при изменении is3D
  useEffect(() => {
    // Если карта уже инициализирована, обновляем ее стиль
    if (map.current) {
      map.current.remove();
      map.current = null;
      initializeMap();
    }
  }, [is3D, initializeMap]);

  return (
    <div className="map-page">
      <Header user={user} title="Карта мира" />
      <main className="map-main">
        <div ref={mapContainer} className="map-container" />
        <div className="controls">
          <button onClick={toggle3D} className="toggle-button">
            {is3D ? '2D Карта' : '3D Глобус'}
          </button>
          <button onClick={togglePanel} className="toggle-button">
            {isPanelOpen ? 'Закрыть Панель' : 'Открыть Панель'}
          </button>
        </div>
        {isPanelOpen && (
          <div className="control-panel">
            <div className="search-section">
              <input
                type="text"
                value={searchQuery}
                onChange={handleSearchChange}
                placeholder="Поиск страны..."
              />
              {suggestions.length > 0 && (
                <ul className="suggestions">
                  {suggestions.map((s) => (
                    <li key={s.id} onClick={() => selectCountry(s)}>
                      {s.place_name}
                    </li>
                  ))}
                </ul>
              )}
            </div>
            <div className="layer-section">
              <h3>Стили карты</h3>
              <button onClick={() => addLayer('streets')}>Улицы</button>
              <button onClick={() => addLayer('satellite')}>Спутник</button>
              <button onClick={() => addLayer('light')}>Светлый</button>
              <button onClick={() => addLayer('dark')}>Темный</button>
              <button onClick={() => addLayer('outdoors')}>На открытом воздухе</button>
              <button onClick={() => addLayer('navigation-day')}>Навигация (день)</button>
              <button onClick={() => addLayer('navigation-night')}>Навигация (ночь)</button>
              <button onClick={() => addLayer('satellite-streets')}>Спутник + Улицы</button>
            </div>
            {countryInfo && (
              <div className="country-info">
                <h4>{countryInfo.place_name}</h4>
                <p>Координаты: {countryInfo.center.join(', ')}</p>
              </div>
            )}
          </div>
        )}
      </main>
    </div>
  );
};

export default MapPage;