import React, {
  createContext, useContext, useEffect, useState,
} from 'react';
import PropTypes from 'prop-types';
import { useId } from '@reach/auto-id';

const propTypes = {
  /**
   * Children to set inside the Tabs.
   *
   * @see Tabs
   * @see TabList
   * @see Tab
   * @see TabPanel
   */
  children: PropTypes.node,
  /**
   * Use this property to control the selected name.
   */
  name: PropTypes.string,
  /**
   * Function called on tab change.
   */
  onChange: PropTypes.func,
};

const defaultProps = {
  children: '',
  name: undefined,
  onChange: undefined,
};

export const TabContext = createContext();
export const useTabContext = () => useContext(TabContext);

/**
 * TabsProvider is the main component to manage tabs using context.
 */
export const TabsProvider = ({
  children,
  onChange,
  name: controlledName,
}) => {
  // On init, we want to use the name
  const [selectedName, setSelectedName] = useState(controlledName || '');

  // If the name property of the component changes, we want to update the
  // selected name.
  useEffect(() => {
    if (controlledName) {
      setSelectedName(controlledName);
    }
  }, [controlledName]);

  const handleChangeTab = (name) => {
    setSelectedName(name);

    if (onChange) {
      onChange(name);
    }
  };

  // Ensure unicity of id if there are multiple Tabs on the same page.
  const id = useId();

  return (
    <TabContext.Provider value={{
      id,
      selectedName,
      handleChangeTab,
    }}
    >
      {children}
    </TabContext.Provider>
  );
};

TabsProvider.propTypes = propTypes;
TabsProvider.defaultProps = defaultProps;
