import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import ThemeContext from '../useTheme/Theme.context';
import useTheme from '../useTheme';
import defaultTheme from '../values/default.theme';

// To support composition of theme.
function mergeOuterLocalTheme(outerTheme, localTheme) {
  return _.merge(outerTheme, localTheme);
}

/**
 * This component takes a `theme` prop.
 * It makes the `theme` available down the React tree thanks to React context.
 * This component should preferably be used at **the root of your component tree**.
 */
function ThemeProvider(props) {
  const { children, theme: localTheme } = props;
  const outerTheme = useTheme() || defaultTheme;

  const theme = React.useMemo(() => {
    const output = mergeOuterLocalTheme(outerTheme, localTheme);

    return output;
  }, [localTheme, outerTheme]);

  return (
    <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
  );
}

ThemeProvider.propTypes = {
  children: PropTypes.node.isRequired,
  theme: PropTypes.oneOfType([PropTypes.object]).isRequired,
};

export default ThemeProvider;
