import { useMemo } from 'react';

import { type Editor, type JSONContent } from '@tiptap/react';
import { type SuggestionProps } from '@tiptap/suggestion';

import useInfiniteUsersPublicSearch from 'src/hooks/useInfiniteUsersPublicSearch';
import { USER_ALL } from 'src/pages/dashboard/Conversations/constants';
import { type Member } from 'src/pages/dashboard/Conversations/types';
import useInfiniteMembersSearch from 'src/pages/dashboard/groups/hooks/useInfiniteMembersSearch';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { type MentionSuggestion } from '../mentions/mentionOptions';

const splitCamelCase = (query: string): string =>
  query.replace(/([a-z])([A-Z])/g, '$1 $2');

const getMentionedUserIds = (editorJSON: JSONContent) => {
  const ids: number[] = [];

  function traverseContent(content: JSONContent[]) {
    content.forEach(node => {
      if (node.type === 'mention' && node.attrs && node.attrs.id) {
        ids.push(parseInt(node.attrs.id, 10));
      } else if (node.content) {
        traverseContent(node.content);
      }
    });
  }

  if (editorJSON.content) {
    traverseContent(editorJSON.content);
  }

  return ids;
};

export type MentionUserListProps = SuggestionProps<MentionSuggestion>;

type UseGetUsersProps = {
  editor: Editor;
  query: string;
  members?: Member[] | undefined;
  isGroupPath: boolean;
  groupId: string | undefined;
};

const useGetUsers = ({
  editor,
  query,
  members,
  isGroupPath,
  groupId,
}: UseGetUsersProps) => {
  const { t } = useLokaliseTranslation();
  const mentionAllKey = t('general:all').toLowerCase();
  const mentionedUserIds = getMentionedUserIds(editor.getJSON());
  const normalizedQuery = splitCamelCase(query);

  const allUsers = useInfiniteUsersPublicSearch(
    {
      search: normalizedQuery,
      notIncludingIds: mentionedUserIds,
      status: 'ACTIVE,UNCLAIMED',
    },
    { enabled: !isGroupPath && !members },
  );

  const groupMemberUsers = useInfiniteMembersSearch(
    {
      groupId: groupId ?? '',
      search: normalizedQuery,
    },
    { enabled: !!isGroupPath && !members },
  );

  const filteredExternalUsers = useMemo(() => {
    if (!members || !query) return members;

    const searchQuery = query.toLowerCase();

    return members.filter(user => {
      if (user.id === USER_ALL.id) {
        return (
          mentionAllKey.startsWith(searchQuery) || 'all'.startsWith(searchQuery)
        );
      }

      const firstName = user.first_name.toLowerCase();
      const lastName = user.last_name.toLowerCase();
      const fullName = `${firstName} ${lastName}`;
      const concatenatedName = `${firstName}${lastName}`;
      return (
        concatenatedName.includes(searchQuery) ||
        fullName.includes(searchQuery) ||
        firstName.includes(searchQuery) ||
        lastName.includes(searchQuery)
      );
    });
  }, [members, query, mentionAllKey]);

  const getUsers = () => {
    if (isGroupPath) {
      return groupMemberUsers;
    }

    return allUsers;
  };

  const getResults = () => {
    if (isGroupPath) {
      return (
        groupMemberUsers.data?.pages.flatMap(page => page.data.items) || []
      );
    }

    return allUsers.data?.pages.flatMap(page => page.data.items) || [];
  };

  const getProcessedUsers = () => {
    return members ? filteredExternalUsers : getResults();
  };

  return {
    users: getUsers(),
    processedUsers: getProcessedUsers(),
  };
};

export default useGetUsers;
