import React from 'react'
import ugh from 'ugh'
import { ProviderContext } from 'Provider'
import { MultiMapContext, SafeParent } from 'MultiMapManager'
import { ErrorBoundary } from 'ErrorBoundary'
let contextConflictWarning = false

/**
 * A wrapper utility function designed to automatically pass down provider conntext as props from the Provider component
 * @function
 * @category Provider
 * @since 1.0.0
 * @param {Component} component - A React component you want wrapped
 * @returns {Component} A wrapped React component which will automatically be passed a reference to provider context
 */
export function connectToContext (Component) {
  if (!Component) return ugh.throw('Pass a React component to \'connectToContext\'')

  return explicitProps => { // eslint-disable-line react/display-name
    const { defaultProps = {} } = Component

    // if no context exists, just render the component with inline props
    if (!MultiMapContext && !ProviderContext) return <Component {...defaultProps} {...explicitProps} />
    if (!contextConflictWarning && !!MultiMapContext && !!ProviderContext) {
      contextConflictWarning = true
      ugh.warn('MultiMapContext and ProviderContext are both mounted on the page. MultiMapContext will supersede ProviderContext and may result in unexpected behavior!') // eslint-disable-line max-len
    }

    // multimap context will take precedence over the provider context
    return (
      <ErrorBoundary>
        {
          MultiMapContext
            ? (
              <MultiMapContext.Consumer>
                {
                  (providerProps = {}) => {
                    return (
                      <SafeParent
                        defaultProps={defaultProps}
                        explicitProps={explicitProps}
                        providerProps={providerProps}
                        Component={Component} />
                    )
                  }
                }
              </MultiMapContext.Consumer>
            ) : (
              <ProviderContext.Consumer>
                {
                  (providerProps = {}) => {
                    // if propTypes is not defined on the component just pass all providerProps
                    const filteredProviderProps = { ...providerProps }
                    const { propTypes } = Component

                    if (propTypes) {
                      // filter out any props that do not need to get passed to this wrapped component
                      Object.keys(providerProps).forEach(key => {
                        if (!propTypes[key]) delete filteredProviderProps[key]
                      })
                    }

                    // // persistedState logic
                    // const { persistedState, persistState } = providerProps
                    // // set the key to look up component's persisted state
                    // const persistedStateKey = props.persistedStateKey || Component.displayName || Component.name // eslint-disable-line react/prop-types

                    return (
                      <Component
                        // persistedState={persistedState[persistedStateKey]} // note: persistedState is undefined if persistedStateKey key doesn't exist yet (components should check for this)
                        // persistState={persistState}
                        {...defaultProps}
                        {...filteredProviderProps}
                        {...explicitProps} />
                    )
                  }
                }
              </ProviderContext.Consumer>
            )

        }
      </ErrorBoundary>
    )
  }
}