import { removeUndefined } from "./../../theme/utils/utils";
import _ from "lodash";
import { getKeys } from "../../theme/utils/type-helpers";
export const MOTI_PROPS = ["animate", "from", "transition", "delay", "state", "stylePriority", "onDidAnimate", "exit", "exitTransition", "animateInitialState"];

/**
 * Checks if a key exists in an object and throws an error if it doesn't.
 * @param key - The key to check for.
 * @param object - The object to check in.
 * @param objectVarName - Optional name of the object variable to include in the error message.
 * @throws {Error} - If the key does not exist in the object.
 */
export const checkKeyAvailability = (key, object, objectVarName = undefined) => {
  if (!object.hasOwnProperty(key)) {
    throw new Error(`Key '${key}' does not exist in ${objectVarName ? objectVarName : object}`);
  }
};

/**
 * Composes style properties from an array of style functions.
 * @param styleFunctions - An array of style functions.
 * @returns An object containing a buildStyle function and an array of property names.
 */
export const composeStyleProps = styleFunctions => {
  // Create a single array of all property objects
  const flattenedStyleFunctions = styleFunctions.reduce((acc, item) => {
    return acc.concat(item);
  }, []);

  // Array of all property names
  const properties = flattenedStyleFunctions.map(styleFunc => {
    return styleFunc.property;
  });
  const funcs = flattenedStyleFunctions.map(styleFunc => {
    return styleFunc.func;
  });

  /**
   * Converts component props to the equivalent style properties.
   * @param props - The component props.
   * @param theme - The theme object.
   * @param dimensions - The dimensions object.
   * @returns An object containing the style properties.
   */
  const buildStyle = (props, {
    theme,
    colorMode,
    dimensions
  }) => {
    return funcs.reduce((acc, func) => {
      return Object.assign(acc, func(props, {
        theme,
        colorMode,
        dimensions
      }));
    }, {});
  };
  return {
    buildStyle,
    properties
  };
};

/**
 * Filters out properties from an object based on a list of properties to omit.
 * @param props - The object to filter.
 * @param omitList - The list of properties to omit.
 * @returns An object with the omitted properties removed.
 */
export const filterStyledProps = (props, omitList) => {
  const omittedProp = omitList.reduce((acc, prop) => {
    acc[prop] = true;
    return acc;
  }, {});
  return getKeys(props).reduce((acc, key) => {
    if (!omittedProp[key]) {
      acc[key] = props[key];
    }
    return acc;
  }, {});
};

/**
 * Builds the final style properties object by composing the core visual style with the component props.
 * @param props - The component props.
 * @param buildStyleProperties - The style properties to build.
 * @param theme - The theme object.
 * @param dimensions - The dimensions object.
 * @returns An object containing the final style properties.
 */
export const buildFinalStyleProps = (props, buildStyleProperties, {
  theme,
  colorMode,
  dimensions
}) => {
  const coreVisualStyle = buildStyleProperties.buildStyle(props, {
    theme,
    colorMode,
    dimensions
  });
  const cleanStyleProps = filterStyledProps(props, buildStyleProperties.properties);
  if (Array.isArray(props.style)) {
    cleanStyleProps.style = [coreVisualStyle, ...props.style];
  } else {
    cleanStyleProps.style = {
      ...coreVisualStyle,
      ...removeUndefined(props.style)
    };
  }
  return cleanStyleProps;
};

/**
 * Composes the clean style properties object by filtering out unnecessary properties.
 * @param props - The component props.
 * @param buildStyleProperties - The style properties to build.
 * @param theme - The theme object.
 * @param dimensions - The dimensions object.
 * @returns An object containing the clean style properties.
 */
export const composeCleanStyleProps = (props, buildStyleProperties, {
  theme,
  colorMode,
  dimensions
}) => {
  let motiStyleProps = buildFinalStyleProps(props, buildStyleProperties, {
    theme,
    colorMode,
    dimensions
  });
  motiStyleProps = {
    ...motiStyleProps,
    ...removeUndefined(motiStyleProps.style)
  };
  motiStyleProps = _.omit(motiStyleProps, ["style", "display", "shadowOffset"]);
  return motiStyleProps;
};
//# sourceMappingURL=utils.js.map