import React, { useState, useEffect, useRef, useCallback } from "react";
// @ts-ignore
import mapboxgl from '!mapbox-gl'; // eslint-disable-line import/no-webpack-loader-syntax

import {
  MAPBOX_ACCESS_TOKEN,
  IMAGE_COORDINATES,
  IMAGES_BASE_URL
} from "./config";

import "mapbox-gl/dist/mapbox-gl.css";

interface MapProps {
  slider: number,
  images: string[],
}

export function Map({ slider, images }: MapProps) {
  const mapContainer = useRef(null);
  const map = useRef<mapboxgl.Map>(null);
  const [lng, setLng] = useState(35);
  const [lat, setLat] = useState(31.9);
  const [zoom, setZoom] = useState(6.3);

  const prevImages = useRef(images).current;
  const prevSlider = useRef(slider).current;

  const updateLayers = useCallback(() => {
    if (!map.current || !map.current.isStyleLoaded()) return;

    // remove old layers
    prevImages.forEach((img) => {
      if (!images.includes(img)) {
        map.current.removeLayer(`layer-${img}`);
        map.current.removeSource(`source-${img}`);
      }
    });

    // add new layers
    images.forEach((img, i) => {
      if (!prevImages.includes(img)) {
        map.current.addSource(`source-${img}`, {
          type: "image",
          url: `${IMAGES_BASE_URL}/${img}`,
          coordinates: IMAGE_COORDINATES
        });
        map.current.addLayer({
          id: `layer-${img}`,
          source: `source-${img}`,
          type: "raster",
          paint: {
            "raster-opacity": 0.5,
            "raster-opacity-transition": {
              duration: 0
            }
          }
        });
      }
    });
  }, [prevImages, images]);

  useEffect(() => {
    if (map.current) return;
    map.current = new mapboxgl.Map({
      accessToken: MAPBOX_ACCESS_TOKEN,
      container: mapContainer.current,
      style: "mapbox://styles/mapbox/dark-v9",
      center: [lng, lat],
      zoom: zoom,
      minZoom: 5,
      maxZoom: 10,
      hash: false,
    });
    map.current.on("style.load", () => { updateLayers(); });
  });

  useEffect(() => {
    if (!map.current || !map.current.isStyleLoaded()) return;
    map.current.on('move', () => {
      setLng(map.current.getCenter().lng.toFixed(4));
      setLat(map.current.getCenter().lat.toFixed(4));
      setZoom(map.current.getZoom().toFixed(2));
    });
  });

  useEffect(() => {
    updateLayers();
  }, [updateLayers, prevImages, images]);

  useEffect(() => {
    if (!map.current || !map.current.isStyleLoaded()) return;
    map.current.setPaintProperty(`layer-${images[prevSlider]}`, "raster-opacity", 0);
    map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0.85);
  }, [prevSlider, slider, images]);

  return (
    <div>
      <div ref={mapContainer} className="map-container" style={{
        height: "100vh",
        width: "100vw"
      }} />
    </div>
  );
}
