import { useRef, useEffect, lazy } from 'react';
import { createRoot } from 'react-dom/client';

import '@esri/calcite-components/dist/calcite/calcite.css';

import MapView from '@arcgis/core/views/MapView.js';
import WebMap from '@arcgis/core/WebMap.js';
import esriConfig from '@arcgis/core/config.js';
import LayerList from '@arcgis/core/widgets/LayerList';
import Expand from '@arcgis/core/widgets/Expand';
import ScaleBar from '@arcgis/core/widgets/ScaleBar.js';
import WMTSLayer from '@arcgis/core/layers/WMTSLayer';
import Map from '@arcgis/core/Map.js';
import Basemap from '@arcgis/core/Basemap';
import * as reactiveUtils from '@arcgis/core/core/reactiveUtils.js';
import * as intl from '@arcgis/core/intl.js';

// set asset path for ArcGIS Maps SDK widgets
esriConfig.assetsPath = './assets';

let mapView: MapView;
const webMapID = '7d0768f73d3e4be2b32c22274c600cb3';

// lazy load Print component
const Print = lazy(() => import('./print'));

export default function MapComponent({ locale }: { locale: string }) {
  const printRoot = useRef<any>(null);
  const mapRef = useRef(null);
  const maskRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (mapRef.current) {
      // set locale for ArcGIS Maps SDK widgets
      intl.setLocale(locale);

      const webMap = new WebMap({
        portalItem: {
          id: webMapID,
          portal: {
            url: 'https://gis.geosphere.at/portal',
          },
        },
      });

      const wmtsLayer = new WMTSLayer({
        url: 'https://mapsneu.wien.gv.at/basemapneu',
      });

      const basemap = new Basemap({
        baseLayers: [wmtsLayer],
      });

      const map = new Map({
        basemap: basemap,
      });

      const mapView = new MapView({
        container: mapRef.current,
        map: map,
      });

      webMap.load().then(() => {
        map.layers = webMap.layers;
      });

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

      const layerListExpand = new Expand({
        content: layerList,
      });

      const container = document.createElement('div');

      const printExpand = new Expand({
        content: container,
        expandIcon: 'print',
        label: 'Print',
      });

      reactiveUtils.watch(
        () => printExpand.expanded,
        (expanded) => {
          if (expanded) {
            printRoot.current = createRoot(container);
            printRoot.current.render(<Print view={mapView} mask={maskRef}></Print>);
          } else {
            maskRef.current?.classList.add('hidden');
            printRoot.current.unmount();
          }
        }
      );

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

      mapView.ui.add([layerListExpand, printExpand], 'top-right');
      mapView.ui.add([scaleBar], 'bottom-left');
    }
    return () => {
      mapView.destroy();
      if (printRoot.current) {
        printRoot.current.unmount();
      }
    };
  }, [mapRef, maskRef]);

  return (
    <div className="h-screen overflow-hidden">
      <div ref={mapRef} className="h-screen"></div>
      <div
        ref={maskRef}
        className="hidden absolute bg-red-300 border-2 border-red-600 pointer-events-none opacity-50"
      ></div>
    </div>
  );
}
