'use client';

import { useEffect, useRef, useState } from 'react';
import { useMediaQuery } from 'react-responsive';

import ArcGISMap from '@arcgis/core/Map';
import Extent from '@arcgis/core/geometry/Extent';
import MapView from '@arcgis/core/views/MapView';
import Basemap from '@arcgis/core/Basemap';
import MapImageLayer from '@arcgis/core/layers/MapImageLayer';
import WMTSLayer from '@arcgis/core/layers/WMTSLayer';
import SpatialReference from '@arcgis/core/geometry/SpatialReference';
import Search from '@arcgis/core/widgets/Search';
import ScaleBar from '@arcgis/core/widgets/ScaleBar';
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer';
import Graphic from '@arcgis/core/Graphic';
import LayerList from '@arcgis/core/widgets/LayerList';
import Zoom from '@arcgis/core/widgets/Zoom';
import Legend from '@arcgis/core/widgets/Legend';
import FeatureLayer from '@arcgis/core/layers/FeatureLayer';
import Polygon from '@arcgis/core/geometry/Polygon';
import esriConfig from '@arcgis/core/config';
import { watch } from '@arcgis/core/core/reactiveUtils';
import type SimpleFillSymbol from '@arcgis/core/symbols/SimpleFillSymbol';

import './esri-ui-grundlagenkarte.css';
import { Vienna, Austria } from '@/public/borders-vienna-austria';
import { BASEMAP_AT_URL, AMPEL_EWS_URL, RESOURCES_EWS_URL, SRS } from '@/app/config/config';
import getAddress from '@/app/utils/getAddress';
import identifyAllLayers from '@/app/utils/identify';
import takeScreenshot from '@/app/utils/screenshot';

import { updateAmpelkarteEWS } from '@/redux/ampelkarteEWSSlice';
import { updateResourcesEWS } from '@/redux/resourcesEWSSlice';
import { updateScreenshot } from '@/redux/screenshotSlice';
import { useAppDispatch } from '@/redux/hooks';

import PanelGrundlagenkarte from './panel-grundlagenkarte';

// set path for local assets
esriConfig.assetsPath = '/assets';

export default function MapComponent() {
  const dispatch = useAppDispatch();

  const mapDiv = useRef<HTMLDivElement | null>(null);
  const [address, setAddress] = useState<string[] | null>([]);

  const isMobile = useMediaQuery({ maxWidth: 480 });

  useEffect(() => {
    let handle: IHandle;
    let view: MapView;
    if (mapDiv.current) {
      dispatch(updateAmpelkarteEWS([]));
      dispatch(updateResourcesEWS([]));
      dispatch(updateScreenshot(''));

      view = new MapView({
        container: mapDiv.current,
        extent: new Extent({
          xmin: -19000,
          ymin: 325000,
          xmax: 29000,
          ymax: 360000,
          spatialReference: new SpatialReference({ wkid: SRS }),
        }),
        popupEnabled: false,
      });

      let viennaGraphic = new Graphic({
        geometry: new Polygon({ rings: [Austria, Vienna], spatialReference: { wkid: SRS } }),
        symbol: {
          type: 'simple-fill',
          color: [209, 213, 219, 0.65],
          style: 'solid',
          outline: {
            color: 'white',
            width: 0,
          },
        } as unknown as SimpleFillSymbol,
      });

      // graphic layers
      let viennaGraphicsLayer = new GraphicsLayer({ title: 'Wien', listMode: 'hide' });
      viennaGraphicsLayer.add(viennaGraphic);

      const ampelkarte_ews = new FeatureLayer({
        url: AMPEL_EWS_URL + '/0',
        title: 'Mögliche Einschränkungen',
        visible: false,
        listMode: 'show',
        opacity: 0.5,
      });

      const resources_ews = new MapImageLayer({
        title: 'Ressourcen',
        url: RESOURCES_EWS_URL,
        visible: false,
        listMode: 'show',
        opacity: 0.5,
      });

      // basemap in Viennese coordinate system due to tranformation inaccuracies from MGI to WGS84
      // default transformation in ArcGIS API from MGI to WGS84 is 1306
      // transformation 1618 is recommended
      const basemap_at = new WMTSLayer({
        url: BASEMAP_AT_URL,
        listMode: 'hide',
      });

      let basemap = new Basemap({
        baseLayers: [basemap_at],
        title: 'basemap.at',
        id: 'basemap.at',
        spatialReference: { wkid: SRS },
      });

      let arcgisMap = new ArcGISMap({
        basemap: basemap,
        layers: [resources_ews, ampelkarte_ews, viennaGraphicsLayer],
      });

      const layerList = new LayerList({
        view,
        listItemCreatedFunction: addPanelInfo,
      });

      const search = new Search({
        view,
        popupEnabled: true,
      });

      const scaleBar = new ScaleBar({
        view: view,
        unit: 'metric',
      });

      const zoom = new Zoom({
        view,
        layout: 'horizontal',
      });

      const legend = new Legend({
        view,
      });

      // register event handler for mouse clicks
      view.on('immediate-click', (event) => {
        if (setAddress && dispatch) {
          takeScreenshot(view, event.mapPoint, dispatch, true);
          getAddress(event.mapPoint, setAddress);
          identifyAllLayers(view, event.mapPoint, dispatch, 'EWS');
        }
      });

      // add map to view
      view.map = arcgisMap;

      // add UI components
      view.ui.components = [];
      if (!isMobile) {
        view.ui.add([zoom, search, layerList], 'top-left');
        view.ui.add(scaleBar, 'bottom-left');
      }

      view.when(() => {
        handle = watch(
          () => view.map?.layers?.map((layer) => layer.visible),
          () => {
            if (view.map?.layers?.some((layer) => layer.title !== 'Wien' && layer.visible === true)) {
              view.ui?.add(legend, 'top-left');
            } else {
              view.ui?.remove(legend);
            }
          }
        );
      });
    }

    return () => {
      handle?.remove();
      view?.destroy();
    };
  }, [dispatch, isMobile, mapDiv]);

  return (
    <div ref={mapDiv} className="absolute top-16 bottom-0 w-full">
      <PanelGrundlagenkarte address={address}></PanelGrundlagenkarte>
    </div>
  );
}

const addPanelInfo = (event: any) => {
  let item = event.item;
  switch (item.layer.id) {
    case 0:
      item.panel = {
        content: 'mittlere jährliche Bodentemperatur laut Satellitendaten (MODIS)',
        className: 'esri-icon-description',
      };
      break;
    case 1:
      item.panel = {
        content: 'mittlere Temperatur des Untergrunds für eine Tiefe von 0 bis 100 m',
        className: 'esri-icon-description',
      };
      break;
    case 2:
      item.panel = {
        content: 'mittlere konduktive Wärmeleitfähigkeit des Untergrunds für eine Tiefe von 0 bis 100 m',
        className: 'esri-icon-description',
      };
      break;
    case 3:
      item.panel = {
        content:
          'Entzugsleistung einer 100 m tiefen Einzelsonde im standortbezogenen Normbetrieb (Heizen und Kühlen mit Normbetriebsstunden eines typischen Wohngebäudes am Standort)',
        className: 'esri-icon-description',
      };
      break;
    case 4:
      item.panel = {
        content:
          'Entzugsleistung einer 100 m tiefen Einzelsonde im saisonalem Speicherbetrieb (die im Winter zur Heizung entzogene Wärme wird im Sommer vollständig wieder zurückgegeben)',
        className: 'esri-icon-description',
      };
      break;
    case 5:
      item.panel = {
        content:
          'flächenspezifische Jahresenergie eines 1156 m² großen und 100 m tiefen Sondenfeldes im standortbezogenen Normbetrieb (4 x 4 Sonden mit je 10 m Abstand - Heizen und Kühlen mit Normbetriebsstunden eines typischen Wohngebäudes am Standort)',
        className: 'esri-icon-description',
      };
      break;
    case 6:
      item.panel = {
        content:
          'flächenspezifische Jahresenergie eines 1156 m² großen und 100 m tiefen Sondenfeldes im saisonalem Speicherbetrieb (7 x 7 Sonden mit je 5 m Abstand - die im Winter zur Heizung entzogene Wärme wird im Sommer vollständig wieder zurückgegeben)',
        className: 'esri-icon-description',
      };
      break;
    case 7:
      item.panel = {
        content: 'mittlere Jahresbetriebsstunden für Heizen',
        className: 'esri-icon-description',
      };
      break;
    case 8:
      item.panel = {
        content: 'mittlere Jahresbetriebsstunden für Kühlen',
        className: 'esri-icon-description',
      };
      break;
    default:
      break;
  }
};
