import { findNodeList } from '../../../utils/array';
/**
 * The function `TagNameMutationFilter` filters mutations based on whether they involve elements with a
 * specific tag name.
 *
 * @param {string[]} tagNames - The `TagNameMutationFilter` function takes a `tagName` parameter, which is
 * a string representing the tag name of an HTML element. The function then returns a `MutationFilter`
 * function that filters mutations based on whether any added or removed nodes have the specified tag
 * name.
 * @returns {MutationFilter} The `TagNameMutationFilter` function is being returned. It takes a `tagName` parameter of
 * type string and returns a `MutationFilter` function that filters mutations based on whether any
 * added or removed nodes have a tag name matching the provided `tagName`.
 */
export const TagNameMutationFilter = (...tagNames) => {
  return (mutations) => {
    /**
     * The function `filter` takes an `HTMLElement` as input and returns `true` if the element's tag name
     * matches a specified `tagName`.
     *
     * @param {HTMLElement} item - An HTMLElement, which represents an element in the HTML document.
     * @returns {boolean} -
     */
    const filter = (item) => tagNames.includes(item.tagName);
    return (mutations.find((mutation) => findNodeList(mutation.addedNodes, filter) || findNodeList(mutation.removedNodes, filter)) !== undefined);
  };
};
/**
 * The function `AttributeOldValueMutationFilter` filters mutations based on whether the old attribute
 * value differs from the current attribute value on the host element.
 *
 * @returns { MutationFilter }The code snippet defines a function named `AttributeOldValueMutationFilter` that returns a
 * `MutationFilter` function. The `MutationFilter` function takes an array of `MutationRecord` objects
 * and an `HTMLElement` as parameters.
 */
export const AttributeOldValueMutationFilter = () => {
  return (mutations, host) => {
    return (mutations.find((mutation) => mutation.attributeName && mutation.oldValue !== host.getAttribute(mutation.attributeName)) !== undefined);
  };
};
/**
 * Filters mutations based on specified tag names or attribute changes.
 *
 * @param {string[]} tagNames - The tagName of need listened child.
 * @returns {MutationFilter} - Filter function.
 */
export const TagNameAndAttributeMutationFilter = (...tagNames) => {
  return (mutations) => {
    return (TagNameMutationFilter(...tagNames)(mutations) ||
      mutations.find((mutation) => mutation.attributeName && tagNames.includes(mutation.target.tagName)) !== undefined);
  };
};
