import { useEffect, useState } from 'react';

import { useQueryClient } from '@tanstack/react-query';
import { useAtom } from 'jotai';
import { equals, isNil, map, pick, reject } from 'ramda';

import { filtersAtom } from '../../atoms';
import { Filter, NamedEntity } from '../../models';
import { filtersInitialValues } from '../../utils';

interface UseFiltersState {
  changeCreator: (_, values) => void;
  changeName: (event) => void;
  changeUser: (_, values) => void;
  deleteCreator: (_, item) => void;
  deleteUser: (_, item) => void;
  filterCreators: (options) => Array<NamedEntity>;
  filters: Filter;
  isClearDisabled: boolean;
  isOptionEqualToValue: (option, selectedValue) => boolean;
  reload: () => void;
  reset: () => void;
}

export const getUniqData = (data): Array<NamedEntity> => {
  const result = [
    ...new Map(data.map((item) => [item.name, item])).values()
  ] as Array<NamedEntity>;

  return result || [];
};

const useFilters = (): UseFiltersState => {
  const queryClient = useQueryClient();

  const [isClearClicked, setIsClearClicked] = useState(false);

  const [filters, setFilters] = useAtom(filtersAtom);

  const isClearDisabled = equals(filters, filtersInitialValues);

  const changeName = (event): void => {
    setFilters({ ...filters, name: event.target.value });
  };

  const changeUser = (_, values): void => {
    const users = map(pick(['id', 'alias']), values);
    setFilters({ ...filters, users });
  };

  const changeCreator = (_, values): void => {
    const creators = map(pick(['id', 'name']), values);
    setFilters({ ...filters, creators });
  };

  const filterCreators = (options): Array<NamedEntity> => {
    const creatorsData = options?.map(({ creator }) => creator);

    return getUniqData(creatorsData);
  };

  const deleteCreator = (_, item): void => {
    const creators = reject(
      ({ name }) => equals(item.name, name),
      filters.creators
    );

    setFilters({ ...filters, creators });
  };

  const deleteUser = (_, item): void => {
    const users = reject(
      ({ alias }) => equals(item.alias, alias),
      filters.users
    );

    setFilters({ ...filters, users });
  };

  const isOptionEqualToValue = (option, selectedValue): boolean => {
    return isNil(option)
      ? false
      : equals(option.name?.toString(), selectedValue.name?.toString());
  };

  const reload = (): void => {
    queryClient.invalidateQueries({ queryKey: ['listTokens'] });
  };

  const reset = (): void => {
    setFilters(filtersInitialValues);

    setIsClearClicked(true);
  };

  useEffect(() => {
    if (isClearClicked) {
      reload();
      setIsClearClicked(false);
    }
  }, [filters, isClearClicked]);

  return {
    changeCreator,
    changeName,
    changeUser,
    deleteCreator,
    deleteUser,
    filterCreators,
    filters,
    isClearDisabled,
    isOptionEqualToValue,
    reload,
    reset
  };
};

export default useFilters;
