import PropTypes from 'prop-types';
import TooltipDisplay from "../TooltipDisplay/index.js";
import TooltipTrigger from "../TooltipTrigger/index.js";
import useTooltip from "../../../hooks/useTooltip/index.js";

/**
 * A tooltip is made up of two primary pieces: a [_trigger_][trigger] and
 * a [_display_][display]. The user hovers over or clicks on the _trigger_ to
 * reveal the _display_. This library provides a "simple" way to render
 * a tooltip, which wraps the trigger and display into a single component, as
 * well as an "advanced" way to render a tooltip, which gives the user more
 * control over the triggers and displays independently.
 *
 * This `Tooltip` component is the simple version. It renders both the tooltip
 * _trigger_, containing the children passed to this component, and the tooltip
 * _display_, containing whatever tooltip content is passed in as the `content`
 * prop. Tooltip content can be specified two different ways:
 *
 * 1. by specifying the rendered content directly as the `content` prop, or
 * 2. by specifying a React component type as the `content` prop and specifying
 *    the props that should be passed to it when it's rendered as the `props`
 *    prop.
 *
 * Note that a `TooltipTrigger` gets rendered around the tooltip's provided
 * children, which creates an extra DOM node to handle user interaction events.
 * By default this renders a plain `div`, which may create an unexpectedly
 * large hover target if you put a `Tooltip` (or a `TooltipTrigger` directly)
 * around, say, an `inline-block` component with a narrow width. If you want
 * a tooltip on a size-bound element, be sure to bound the size of the hover
 * target with a parent element. You may also want to set the `as` prop on the
 * `TooltipTrigger` component to render it as a different kind of element. Note
 * that if you provide a custom component type to the `as` prop it must forward
 * its `ref` to a DOM node that will receive click events and handle the
 * `onMouseEnter`, `onMouseLeave`, `onFocus`, `onBlur`, `onClick`, and
 * `tabIndex` props appropriately.
 *
 * By default the `TooltipDisplay` renders [a `Card` component][card] under the
 * hood, and all extra props beyond those listed below are forwarded to the
 * card, so you can customize the color, corner roundness, border, shadow,
 * padding, and so on just like you would with a normal card.
 *
 * If you need more control over how and where the tooltip display container is
 * rendered, or if you need to share one display container across multiple
 * tooltip triggers, you can use the `useTooltip` hook to coordinate
 * `TooltipDisplay` and `TooltipTrigger` components that you render directly.
 * You can consult the "advanced" stories below for examples of how to do that,
 * and you should also consult the documentation on [the `useTooltip`
 * hook][use-tooltip], [the `TooltipTrigger` component][trigger] and [the
 * `TooltipDisplay` component][display].
 *
 * ```js
 *
 * import { Tooltip } from '@politico/interactive-style';
 * ```
 *
 * [use-tooltip]: ./?path=/docs/hooks-usetooltip--basic
 * [trigger]: ./?path=/docs/components-structure-tooltiptrigger--basic
 * [display]: ./?path=/docs/components-structure-tooltipdisplay--basic
 * [card]: ./?path=/docs/components-structure-card--basic
 */
const Tooltip = function Tooltip(props) {
  const {
    content,
    props: childProps,
    children,
    breakpoint,
    triggerAs,
    ...forwardProps
  } = props;
  const tooltip = useTooltip({
    content,
    props: childProps,
    breakpoint
  });
  return <>
      <TooltipTrigger tooltip={tooltip} as={triggerAs}>
        {children}
      </TooltipTrigger>
      <TooltipDisplay {...forwardProps} tooltip={tooltip} />
    </>;
};
Tooltip.defaultProps = {
  content: undefined,
  props: undefined,
  triggerAs: undefined,
  breakpoint: 'md'
};
Tooltip.propTypes = {
  /**
   * The content to render in this simple tooltip
   */
  content: PropTypes.oneOfType([PropTypes.elementType, PropTypes.node]),
  /**
   * The props to pass to `Component` when rendering this tooltip
   */
  props: PropTypes.shape({}),
  /**
   * The breakpoint at which to switch to the desktop "hover" display.
   */
  breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
  /**
   * An element type to forward to the `TooltipTrigger`'s `as` prop. This will
   * cause the trigger to be rendered as a different kind of element.
   */
  triggerAs: PropTypes.elementType,
  /**
   * The children to render as the tooltip trigger
   */
  children: PropTypes.node.isRequired
};
export default Tooltip;