// PostalAddressQueryMap.tsx
import * as React from 'react'
import {
  useEffect, useMemo, useCallback,
} from 'react'
import {
  graphql, useQueryLoader,
} from 'react-relay/hooks'
import debounce from 'lodash.debounce'
import PropTypes, { InferProps } from 'prop-types'
import { withPreloadedQuery } from '@aztlan/react-relay'
import DataMap from './DataMap.js'
import Map from './Map.js'

export const DEFAULT_GEOCODE_QUERY = graphql`
  query PostalAddressMapGeocodeQuery($input: PostalAddressInput!) {
    geocode(input: $input) {
      ...DataMapCoordinatesFragment
    }
  }
`

const PreloadedDataMap = withPreloadedQuery(
  DataMap, {
    accessor:'geocode',
    callback:(data) => {
      console.log(
        'C1 CALLBACK', data,
      )
    },
  },
)

function PostalAddressMap({
  streetAddress,
  addressLocality,
  addressRegion,
  postalCode,
  addressCountry,
  debounceMs = 500,
  QUERY = DEFAULT_GEOCODE_QUERY,
  Component = PreloadedDataMap,
  ...otherProps
}: InferProps<typeof PostalAddressMap.propTypes>): React.ReactElement {
  const [
    queryReference,
    loadGeocodeQuery,
  ] = useQueryLoader(QUERY)

  const shouldFetch = useMemo(
    () => streetAddress && addressLocality && postalCode && addressCountry,
    [
      streetAddress,
      addressLocality,
      postalCode,
      addressCountry,
    ],
  )

  const loadDebouncedGeocodeQuery = useCallback(
    debounce(
      (variables) => loadGeocodeQuery(variables), debounceMs,
    ),
    [
      loadGeocodeQuery,
      debounceMs,
    ],
  )

  useEffect(
    () => {
      if (!shouldFetch) {
        return
      }
      const variables = {
        input:{
          streetAddress,
          addressLocality,
          addressRegion,
          postalCode,
          addressCountry,
        },
      }
      loadDebouncedGeocodeQuery(variables)
    }, [
      loadGeocodeQuery,
      shouldFetch,
      streetAddress,
      addressLocality,
      addressRegion,
      postalCode,
      addressCountry,
    ],
  )

  if (!shouldFetch) return null

  return (
    <React.Suspense fallback={<Map wireframe />}>
      {queryReference !== null ? (
        <Component
          queryReference={queryReference}
          QUERY={QUERY}
          {...otherProps}
        />
      ) : (
        // This will display the first time the map loads only (no queryReference)
        <Map wireframe />
      )}
    </React.Suspense>
  )
}

PostalAddressMap.propTypes = {
  /** Street address according to [schema.org/Place] */
  streetAddress:PropTypes.string,

  /** Locality according to [schema.org/Place] */
  addressLocality:PropTypes.string,

  /** Region according to [schema.org/Place] */
  addressRegion:PropTypes.string,

  /** Postal code according to [schema.org/Place] */
  postalCode:PropTypes.string,

  /** Country according to [schema.org/Place] */
  addressCountry:PropTypes.string,

  /** The query to use */
  QUERY:PropTypes.object,

  /** The debounce time in milliseconds */
  debounceMs:PropTypes.number,

  /** The component to use */
  Component:PropTypes.elementType,
}

PostalAddressMap.C = PreloadedDataMap

PostalAddressMap.QUERY = DEFAULT_GEOCODE_QUERY

export default PostalAddressMap
