import { Component, createEffect, createSignal, onMount } from 'solid-js';
import { useParams, useNavigate } from '@solidjs/router';
import OlMap from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Feature from 'ol/Feature';
import Attribution from 'ol/control/Attribution';
import Rotate from 'ol/control/Rotate';
import ScaleLine from 'ol/control/ScaleLine';
import Control from 'ol/control/Control';
import OSM from 'ol/source/OSM';
import { useGeographic as olUseGeographic } from 'ol/proj';

import 'ol/ol.css';
import './Map.css';
import { Collection } from 'ol';
import { Point } from 'ol/geom';
import { Style, Icon } from 'ol/style';
import GetLocation, { getCurrentLocation } from '../get-location';
import ShowLocationIcon from '../get-location/ShowLocationIcon.svg';
import { Back, Forward } from '../back-forward';
import GpxImport from '../gpx-import';
import AllGpxes from '../all-gpxes';

const [getState, setState] = createSignal({
  lon: 0,
  lat: 0,
  rotation: 0,
  zoom: 0,
});

export { getState };

const Map: Component = () => {
  const [getMap, setMap] = createSignal<OlMap | null>(null);
  const params = useParams();
  const navigate = useNavigate();

  let target: HTMLDivElement;
  console.log({ caller: 'Map', center: params.center });

  createEffect(() => {
    setState({
      lon: +params.lon,
      lat: +params.lat,
      rotation: +params.rotation,
      zoom: +params.zoom,
    });
    const map = getMap();
    const view = map?.getView();
    view?.animate({
      center: [getState().lon, getState().lat],
      rotation: getState().rotation,
      zoom: getState().zoom,
      duration: 1000,
    });
  });

  createEffect(() => {
    const location = getCurrentLocation();
    if (location) {
      console.log({
        caller: 'Map / updateLocation',
        location,
      });
      const source = getMap()
        ?.getAllLayers()
        .at(1)
        ?.getSource() as VectorSource;
      source!.clear(true);
      const point = new Point([location.lon, location.lat]);
      const style = new Style({
        image: new Icon({
          //      size: [20, 20],
          imgSize: [24, 24],
          declutterMode: 'declutter',
          // @ts-ignore
          src: ShowLocationIcon,
        }),
      });
      const feature = new Feature({
        geometry: point,
        //      labelPoint: point,
        //      name: 'current location',
        style: style,
      });
      feature.setStyle(style);
      source.addFeature(feature);
      //    source.changed();
      console.log({
        caller: 'Map / updateLocation',
        location,
        source,
        style,
        feature,
      });
    }
  });

  onMount(() => {
    olUseGeographic();

    const changeListener = (event: any) => {
      const map = getMap();
      const view = map?.getView();
      const center = view?.getCenter();
      if (center) {
        navigate(
          `/map/${center[0]}/${
            center[1]
          }/${view?.getZoom()}/${view?.getRotation()}`
        );
      }
      console.log({
        caller: 'Map / changeListener',
        event,
        params,
        map,
      });
    };

    const olMap = new OlMap({
      view: new View({
        center: [+getState().lon, +getState().lat],
        zoom: +getState().zoom,
        rotation: +getState().rotation,
      }),
      layers: [
        new TileLayer({
          source: new OSM(),
        }),
        new VectorLayer({ source: new VectorSource() }),
      ],
      target: target,
      controls: new Collection<Control>([
        new Attribution({ collapsible: true }),
        new Rotate(),
        new ScaleLine({ bar: true }),
        // // @ts-ignore
        // new Control({
        //   // @ts-ignore
        //   element: (
        //     <div>
        //       <GetLocation />
        //     </div>
        //   ),
        // }),
        // new Control({
        //   // @ts-ignore
        //   element: (
        //     <div>
        //       <Back />
        //     </div>
        //   ),
        // }),
        // new Control({
        //   // @ts-ignore
        //   element: (
        //     <div>
        //       <Forward />
        //     </div>
        //   ),
        // }),
        // new Control({
        //   // @ts-ignore
        //   element: (
        //     <div>
        //       <GpxImport />
        //     </div>
        //   ),
        // }),
      ]),
    });
    olMap.on(['moveend'], changeListener);

    setMap(olMap);
  });

  return (
    // @ts-ignore
    <div class='ol-map' ref={target}>
      <GetLocation />
      <Forward />
      <Back />
      <GpxImport />
      <AllGpxes map={getMap()} />
    </div>
  );
};

export default Map;
