/* eslint-disable import/prefer-default-export */
import React, { useCallback, useEffect } from "react";

/**
 * A factory function that creates a provider and a hook to track events inside a feature component.
 * @typedef createEventTrackerReturn
 * @property {EventsProvider} A provider that should wrap the feature component.
 * @property {useTrackEvent} A hook that should be used inside the feature component to track events.
 * 
* @returns {createEventTrackerReturn}
 * @example <caption>Usage:</caption>
 * type Events = { key: "step_goal_seen" } | { key: "step_connect_seen" };
 *
 * const { EventsProvider, useTrackEvent } = createEventTracker<Events>("ParentComponent");
 *
 * function ParentComponent() {
 *   const onTrackEvent = (event) => {
 *   console.log(event);
 *   };
 *
 *   return (
 *   <EventsProvider onTrack={onTrackEvent}>
 *   <ChildComponent />
 *   </EventsProvider>
 *   );
 * };
 *
 * function ChildComponent() {
 * const trackEvent = useTrackEvent();
 *
 * return <button onClick={() => trackEvent({ key: "step_goal_seen" })}>Click me</button>;
 * }
 *
 */
export function createEventTracker(name) {
  var EventsContext = /*#__PURE__*/React.createContext(null);

  var EventsProvider = function EventsProvider(props) {
    var children = props.children,
        onTrack = props.onTrack;
    var onTrackRef = React.useRef(); // Latest ref pattern

    useEffect(function () {
      onTrackRef.current = onTrack;
    });
    return /*#__PURE__*/React.createElement(EventsContext.Provider, {
      value: onTrackRef
    }, children);
  };

  var useTrackEvent = function useTrackEvent() {
    var onTrackRef = React.useContext(EventsContext);

    if (onTrackRef === null) {
      throw new Error("useTrackEvent must be used within a EventProvider inside the component ".concat(name));
    }

    return useCallback(function (event) {
      var _onTrackRef$current;

      (_onTrackRef$current = onTrackRef.current) === null || _onTrackRef$current === void 0 ? void 0 : _onTrackRef$current.call(onTrackRef, event);
    }, []);
  };

  return {
    EventsProvider: EventsProvider,
    useTrackEvent: useTrackEvent
  };
}