/* @aztlan/generator-front 1.1.3 */
import * as React from 'react'
import {
  useEffect,
  useInsertionEffect,
  useLayoutEffect,
  useState,
  useCallback,
} from 'react'

import * as PropTypes from 'prop-types'
import { InferProps } from 'prop-types'

/*
import {
  MapContainer, TileLayer, Marker, useMap,
} from 'react-leaflet'
   */
// import L from 'leaflet'

import styleNames from '@aztlan/bem'

const baseClassName = styleNames.base
const componentClassName = 'map'

/**
 * description
 * @param {InferProps<typeof Map.propTypes>} props -
 * @returns {React.ReactElement} - Rendered Map
 */
function Map({
  id,
  className: userClassName,
  style,
  wireframe,
  latitude,
  longitude,
  height = '10em',
  zoom = 13,
}: InferProps<typeof Map.propTypes>): React.ReactElement {
  /* Fix for "Map container is already initialized" in React 18
   * @see [https://github.com/PaulLeCam/react-leaflet/issues/936]
   */
  const [
    unmountMap,
    setunmountMap,
  ] = useState(false)

  const [
    LeafletLib,
    setLeafletLib,
  ] = useState(null)

  useEffect(
    () => {
      (async () => {
        if (typeof window !== 'undefined') {
          const LeafletLibMainExport = await import('react-leaflet')
          setLeafletLib(LeafletLibMainExport)
        }
      })()
    }, [],
  )

  const {
    MapContainer, TileLayer, Marker, useMap,
  } = LeafletLib || {}

  useInsertionEffect(
    () => {
    // @ts-ignore
      import('leaflet/dist/leaflet.css')
      // @ts-ignore
      import('./styles.scss')
    }, [],
  )

  useLayoutEffect(
    () => {
      setunmountMap(false)
      return () => {
        setunmountMap(true)
      }
    }, [],
  )

  const position: [number, number] = [
    latitude,
    longitude,
  ]

  const Wrapper = useCallback(
    (otherProps) => React.createElement(
      'div', {
        id,
        className:[
          baseClassName,
          componentClassName,
          userClassName,
          'container',
        ]
          .filter((e) => e)
          .join(' '),
        style:{
          '--height':height,
          ...style,
        },
        ...otherProps,
      },
    ),

    [
      id,
      userClassName,
      height,
    ],
  )

  if (!LeafletLib) {
    return <Wrapper>LOADING LEAFLET</Wrapper>
  }

  function SetViewOnClick({ coords }: { coords: [number, number] }) {
    const map = useMap()
    map.setView(
      coords, map.getZoom(),
    )
    return null
  }

  if (unmountMap || wireframe) {
    return <Wrapper>LOADING WIREFRAME</Wrapper>
  }

  return (
    <Wrapper>
      <MapContainer
        // @ts-ignore
        center={position}
        zoom={zoom}
        style={{
          height,
          width   :'100%',
          fontSize:'1rem',
        }}
      >
        <SetViewOnClick coords={position} />
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          // @ts-ignore
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />
        <Marker position={position} />
      </MapContainer>
    </Wrapper>
  )
}

Map.propTypes = {
  /** The HTML id for this element */
  id:PropTypes.string,

  /** The HTML class names for this element */
  className:PropTypes.string,

  /** The React-written, css properties for this element. */
  style:PropTypes.objectOf(PropTypes.string),

  /** The latitude for the map center */
  latitude:PropTypes.number,

  /** The longitude for the map center */
  longitude:PropTypes.number,

  /** The zoom level for the map */
  zoom:PropTypes.number,

  /** The height of the map, a css value */
  height:PropTypes.string,

  /** The wireframe mode */
  wireframe:PropTypes.bool,
}

export default Map
