export const kebabCase = (str) =>
  str
    .replace(/([a-z])([A-Z])/g, '$1-$2')
    .replace(/[\s_.]+/g, '-')
    .toLowerCase();

export const kebabCaseJoin = (...args) => kebabCase(args.filter((arg) => !!arg).join('-'));

export const upperFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);

export const camelCaseJoin = (...args) =>
  args
    .filter(Boolean)
    .map((arg, index) => (index === 0 ? arg : upperFirst(arg)))
    .join('');

export const compose =
  (...fns) =>
  (val) =>
    fns.reduceRight((res, fn) => fn(res), val);

export const isFunction = (maybeFunc) => typeof maybeFunc === 'function';

export const isUrl = (maybeUrl) => {
  try {
    // eslint-disable-next-line no-new
    new URL(maybeUrl);

    return true;
  } catch (e) {
    return false;
  }
};

/**
 * Compares two arrays unorderedly.
 * @param {Array} arr1 - The first array to compare.
 * @param {Array} arr2 - The second array to compare.
 * @returns {boolean} - Returns true if the arrays are equal unorderedly, false otherwise.
 */
export const compareArraysUnordered = (arr1, arr2) => {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return false;
  }

  if (arr1.length !== arr2.length) {
    return false;
  }

  const sortedArr1 = arr1.slice().sort();
  const sortedArr2 = arr2.slice().sort();

  for (let i = 0; i < sortedArr1.length; i++) {
    if (sortedArr1[i] !== sortedArr2[i]) {
      return false;
    }
  }

  return true;
};

export const toTitle = (str) =>
  str
    .replace(/([A-Z])/g, ' $1')
    .trim()
    .split(' ')
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
