import * as React from 'react'
import {
  useMemo, useState, useCallback, useEffect,
} from 'react'
import * as PropTypes from 'prop-types'
import { InferProps } from 'prop-types'
import { useParams } from 'react-router-dom'
import {
  usePreloadedQuery, useRefetchableFragment,
} from 'react-relay'
import { useApplicationContext } from '@aztlan/ui'

import Context from './Context.js'

function RawProvider({
  children,
  FRAGMENT,
  data,
  basePath,
  baseOrganizationPath,
}: // ...otherProps
InferProps<typeof RawProvider.propTypes>): React.ReactElement {
  const { organization: currentOrganizationUrl } = useParams()

  const [
    result,
    refetchOrganization,
  ] = useRefetchableFragment(
    FRAGMENT, data,
  )

  const selectedOrganization = result.organization

  useEffect(
    () => {
      if (
        currentOrganizationUrl
      && currentOrganizationUrl !== selectedOrganization?.url
      ) {
        refetchOrganization({ url: currentOrganizationUrl })
      }
    }, [currentOrganizationUrl],
  )

  const contextValue = useMemo(
    () => ({
      data:selectedOrganization,
      id  :selectedOrganization?.id,
      uuid:selectedOrganization && atob(selectedOrganization.id).split(':')[1],
      currentOrganizationUrl,
      basePath,
      baseOrganizationPath,
    }),
    [
      baseOrganizationPath,
      basePath,
      selectedOrganization,
      currentOrganizationUrl,
      data,
    ],
  )

  return <Context.Provider value={contextValue}>{children}</Context.Provider>
}

RawProvider.propTypes = {
  /** The children JSX */
  children:PropTypes.node,

  /** The fragment to use */
  FRAGMENT:PropTypes.object,

  /** The base path */
  basePath:PropTypes.string,

  /** The base organization path */
  baseOrganizationPath:PropTypes.string,

  /** The data to use */
  data:PropTypes.any,
}

export { RawProvider }

function Provider(props): React.ReactElement {
  const { data } = useApplicationContext()

  return (
    <RawProvider
      data={data}
      {...props}
    />
  )
}

export default Provider
