import { cloneDeep, isEmpty, orderBy, pick, some } from 'lodash';
import { normalizeString } from '../utils/format';

export function applySearchOnDataSet(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  data: any[],
  filterablePropertyKeys: string[],
  searchInput: string
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
): any[] {
  if (!searchInput) {
    return data;
  }

  const formattedSearchInput = normalizeString(searchInput);

  return data.filter((item) => {
    const values = Object.values(pick(item, filterablePropertyKeys));

    return some(
      values,
      (value) => value && normalizeString(value).includes(formattedSearchInput)
    );
  });
}

export function getPaginatedData(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  data: any[],
  maxPerPage: number
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
): any[] {
  if (!data || !data.length) {
    return [];
  }

  if (maxPerPage === data.length) {
    return [data];
  }

  const arrayToProcess = cloneDeep(data);

  const elementsCount = data.length;

  const paginatedData: unknown[][] = [];

  for (let index = 0; index < elementsCount; index += maxPerPage) {
    const items = arrayToProcess.slice(index, index + maxPerPage);

    paginatedData.push(items);
  }

  return !isEmpty(paginatedData) ? paginatedData : [[]];
}

export function sortListBy( // eslint-disable-next-line @typescript-eslint/no-explicit-any
  data: any[],
  orderByProperty: string,
  orderType: 'asc' | 'desc'
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
): any[] {
  return orderBy(
    data,
    [
      (item) => {
        if (
          !item[orderByProperty] ||
          typeof item[orderByProperty] !== 'string'
        ) {
          return item[orderByProperty];
        }

        return item[orderByProperty].toLowerCase();
      },
    ],
    [orderType]
  );
}

export function filterAndSortListBy(
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  data: any[],
  orderByProperty: string,
  orderType: 'asc' | 'desc',
  filterablePropertyKeys: string[],
  searchInput: string
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
): any[] {
  const filteredData = applySearchOnDataSet(
    data,
    filterablePropertyKeys,
    searchInput
  );

  if (!orderByProperty) {
    return filteredData;
  }

  return sortListBy(filteredData, orderByProperty, orderType);
}
