import {useCallback, useEffect, useRef, useState} from 'react';
import debounce from 'lodash.debounce';
import {getChannelUsersForMentions} from '@modules/chats/db';
import {MentionUser} from '@modules/chats/interfaces';
import {persistedUserId} from '@services/localStorage';

const PAGE_SIZE = 20;

/**
 * Hook to get users for mentions in a channel, excluding the current user.
 *
 * @param channel - The channel to get users for mentions.
 * @param search - The search query to filter users.
 * @returns An object containing the users for mentions and a function to get more users.
 */
export const useChannelUsersForMentions = ({
  channel,
  search,
  onSearchResultIsEmpty,
}: {
  channel: string;
  search: string;
  onSearchResultIsEmpty: (searchText?: string) => void;
}) => {
  const [groupMembers, setGroupMembers] = useState<MentionUser[]>([]);
  const page = useRef(1);
  const userId = persistedUserId!;
  const hasNextPage = groupMembers.length >= PAGE_SIZE;

  // Using ref to avoid re-declaring the callback function
  const searchRef = useRef(search);
  searchRef.current = search;

  /**
   * Get first page of members
   */
  const getMembers = useCallback(
    async (searchText?: string) => {
      page.current = 1;
      const members = await getChannelUsersForMentions({
        channel,
        page: page.current,
        search: searchText,
        excludeUserIds: [userId],
        limit: PAGE_SIZE,
      });

      setGroupMembers(members);

      if (members.length === 0) {
        onSearchResultIsEmpty(searchText);
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [channel, userId],
  );
  const debouncedSearch = useRef(debounce(getMembers, 300));

  const getMoreMembers = useCallback(async () => {
    if (!hasNextPage) {
      return;
    }

    page.current += 1;
    const currentUsersMemberships = await getChannelUsersForMentions({
      channel,
      page: page.current,
      search: searchRef.current,
      excludeUserIds: [userId],
      limit: PAGE_SIZE,
    });
    if (currentUsersMemberships.length) {
      setGroupMembers(prev => [...prev, ...currentUsersMemberships]);
    }
  }, [channel, userId, hasNextPage]);

  useEffect(() => {
    debouncedSearch.current(search);
  }, [search]);

  return {
    groupMembers,
    getMoreMembers,
    getMembers: debouncedSearch.current,
    hasNextPage,
    pageSize: PAGE_SIZE,
  };
};
