/**
 * @format
 */

import {Box, Button, Heading, HStack} from '@chakra-ui/react'
import {WrapperBox} from './UIcomponents'
import React, {useEffect, useRef, useState} from 'react'
import {useSelector, useDispatch} from 'react-redux'
import {Loader} from 'google-maps'
import {setMap} from '../redux/mapSlice'
import {RootState} from '../store'
import redDotMarkerIcon from '../assets/images/icons/marker-red-dot.png'
import redMarkerIcon from '../assets/images/icons/marker-red.png'
import greyDotMarkerIcon from '../assets/images/icons/marker-grey-dot.png'
import greyMarkerIcon from '../assets/images/icons/marker-grey.png'
import {CloseIcon} from '@chakra-ui/icons'
import {LatLng, TransactionMapInterface} from '../types/types'
import {Carousel, CarouselPage} from './Carousel'
import {InfoContent} from './infoContent'

export const TransactionMapView = ({
  data
}: {
  data: Array<TransactionMapInterface>
}) => {
  const infoWindowTitle = 'Comparable Transaction History'
  const mapLoaded = useSelector((state: RootState) => state.mapObj.value)
  const dispatch = useDispatch()
  const loader = new Loader('AIzaSyBd1FaKeQuBDZEkaZZrvDwc8Y1nQy_PBf8', {})

  interface XYPos {
    x: number
    y: number
  }
  const infoWindowWidth = 260
  const offset = 30
  const [mapObj, setMapObj] = useState<any>(null)
  const [showInfoWindow, setShowInfoWindow] = useState<boolean>(true)
  const [infoWindowData, setInfoWindowData] = useState<any>(null)
  const [infoWindowPos, setInfoWindowPos] = useState<XYPos>({x: 0, y: 0})
  const infoWindowElm = useRef<HTMLDivElement>(null)
  interface MarkerOptions {
    googleScope: any
    map: any
    position: LatLng
    markerType: 'grey' | 'red'
  }
  const markerArray: Array<any> = []
  const loadMarker = (opts: MarkerOptions) => {
    const icons = {
      grey: greyMarkerIcon,
      greyDot: greyDotMarkerIcon,
      red: redMarkerIcon,
      redDot: redDotMarkerIcon
    }

    return new opts.googleScope.maps.Marker({
      position: opts.position,
      map: opts.map,
      icon: icons[opts.markerType],
      iconType: opts.markerType,
      selected: false
    })
  }
  const toggleMarkerSelected = (mrkr: any) => {
    const isSelected = mrkr.selected

    if (!isSelected) {
      mrkr.setOptions({
        selected: true,
        icon: mrkr.iconType === 'grey' ? greyDotMarkerIcon : redDotMarkerIcon
      })
    } else {
      mrkr.setOptions({
        selected: false,
        icon: mrkr.iconType === 'grey' ? greyDotMarkerIcon : redDotMarkerIcon
      })
    }
  }
  const resetMarkerIcons = (markerAry: Array<any>) => {
    markerAry.forEach(mrkr => {
      mrkr.setIcon(mrkr.iconType === 'grey' ? greyMarkerIcon : redMarkerIcon)
    })
  }
  const infoWindowGroup = true

  useEffect(() => {
    if (!mapLoaded) {
      loader.load().then((googleS: any) => {
        // Map successfully loaded and MapObject is available for play.
        const m = new googleS.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          zoom: 8,
          map: mapObj,
          disableDefaultUI: true,
          zoomControl: true,
          zoomControlOptions: {
            position: googleS.maps.ControlPosition.RIGHT_TOP
          }
        })

        // Setting map styles

        setMapObj(m)
        dispatch(setMap('map'))

        data.forEach((obj: any) => {
          const mrkr: any = loadMarker({
            position: obj.position,
            googleScope: googleS,
            map: m,
            markerType: obj.type === 'secondary' ? 'grey' : 'red'
          })
          markerArray.push(mrkr)

          // eslint-disable-next-line no-undef
          mrkr.addListener('click', (e: google.maps.MapMouseEvent) => {
            const evt = e.domEvent as MouseEvent
            const elm = infoWindowElm.current

            const ht = elm?.getBoundingClientRect().height || 0
            resetMarkerIcons(markerArray)
            toggleMarkerSelected(mrkr)
            setShowInfoWindow(true)
            setInfoWindowData(obj)

            setInfoWindowPos({
              x:
                evt.clientX > infoWindowWidth
                  ? evt.clientX - infoWindowWidth - offset
                  : offset,
              y: evt.clientY - (ht !== 0 ? ht / 2 : offset)
            })
          })
        })
      })
    }
  }, [])

  const infoBoxStyles = {
    p: '0',
    borderRadius: '4px',
    borderColor: 'grey.300',
    bg: 'white',
    zIndex: '100',
    m: 0,
    boxShadow: 'lg'
  }

  const InfoWindowHeading = () => (
    <HStack
      pl="12px"
      w="100%"
      justify="space-between"
      borderBottom={'1px'}
      borderBottomColor="grey.300"
    >
      <Heading variant="size12">{infoWindowTitle}</Heading>
      <Button
        variant="outline"
        borderWidth={0}
        minWidth={'10px'}
        onClick={() => setShowInfoWindow(false)}
      >
        <CloseIcon height={'12px'} />
      </Button>
    </HStack>
  )

  return (
    <WrapperBox>
      <Heading variant="size18" mb="4">
        Map View
      </Heading>
      {showInfoWindow && infoWindowData && (
        <>
          <Box
            ref={infoWindowElm}
            left={`${infoWindowPos.x}px`}
            top={`${infoWindowPos.y}px`}
            width={`${infoWindowWidth}px`}
            css={{position: 'fixed'}}
            {...infoBoxStyles}
          >
            <InfoWindowHeading />
            {!infoWindowGroup ? (
              <Box pb="16px">
                <InfoContent infoData={infoWindowData} />
              </Box>
            ) : (
              <Carousel
                opts={{
                  loop: false,
                  autoStart: false,
                  pageLength: 3,
                  children: [1, 2, 3].map(i => (
                    <CarouselPage key={`Carousel_${i}`}>
                      <InfoContent infoData={infoWindowData} />
                    </CarouselPage>
                  ))
                }}
              />
            )}
          </Box>
        </>
      )}

      <Box border="1px" height="600px" width="100%" borderColor="darkGrey">
        <div id="map" style={{width: '100%', height: '100%'}} />
      </Box>
    </WrapperBox>
  )
}
