import React, {useCallback, useRef, useState} from 'react';
import {shallowEqual} from 'react-redux';
import {TabItem, Tabs, TabsRef, TabsRenderScene} from '@components';
import {User} from '@interfaces/user';
import {getUserList} from '@modules/chat/services';
import SelectChatMembers from '@modules/chat/components/SelectChatMembers';
import {Topic} from '@interfaces/topics';
import {CHAT_QUERY_KEYS} from '@modules/chat/constants';
import {useAppSelector} from '@redux/utils';

import SelectUser from './components/SelectUser';
import SelectTicket from './components/SelectTicket';
import CreateGroup from './components/CreateGroup';
import CreateTicket from './components/CreateTicket';

const selectMembersQueryFn =
  (searchText: string) =>
  ({page}: {page: number}) =>
    getUserList({page, q: searchText});

export function CreateNewChatScreen() {
  const tabsRef = useRef<TabsRef>(null);
  const [selectedUsers, setSelectedUsers] = useState<User[]>([]);
  const [selectedTopic, setSelectedTopic] = useState<Nullable<Topic>>(null);
  const {canCreateChat, canCreateGroupChat, canCreateTicket} = useAppSelector(
    ({user, instance}) => ({
      canCreateChat:
        instance.allowCreateChats && user.permissions.VIEW_REGULAR_CHATS,
      canCreateGroupChat:
        instance.allowCreateChats &&
        user.permissions.VIEW_REGULAR_CHATS &&
        user.permissions.CREATE_REGULAR_GROUP_CHAT,
      canCreateTicket: user.permissions.VIEW_TICKETS,
    }),
    shallowEqual,
  );

  const routes = [
    canCreateChat && {key: 'SELECT_USER', label: ''},
    {key: 'SELECT_TICKET', label: ''},
    {key: 'SELECT_MEMBERS_GROUP', label: ''},
    {key: 'CREATE_GROUP', label: ''},
    {key: 'CREATE_SUPPORT_TICKET', label: ''},
  ].filter(Boolean) as TabItem[];

  const goToFirstTab = useCallback(() => {
    tabsRef.current?.goToIndex(0);
  }, []);

  const goToTickets = useCallback(() => {
    tabsRef.current?.goToRouteKey('SELECT_TICKET');
  }, []);

  const goToSelectMembersGroup = useCallback(() => {
    tabsRef.current?.goToRouteKey('SELECT_MEMBERS_GROUP');
  }, []);

  const goToCreateGroup = useCallback((selection: User[]) => {
    setSelectedUsers(selection);
    tabsRef.current?.goToRouteKey('CREATE_GROUP');
  }, []);

  const goToCreateTicket = useCallback((topic: Topic) => {
    setSelectedTopic(topic);
    tabsRef.current?.goToRouteKey('CREATE_SUPPORT_TICKET');
  }, []);

  const renderScene = useCallback(
    ({route}: TabsRenderScene<TabItem>) => {
      switch (route.key) {
        case 'SELECT_USER':
          return (
            <SelectUser
              onCreateGroupPress={
                canCreateGroupChat ? goToSelectMembersGroup : undefined
              }
              onCreateTicketPress={canCreateTicket ? goToTickets : undefined}
            />
          );
        case 'SELECT_TICKET':
          return (
            <SelectTicket
              onCancel={goToFirstTab}
              onSelectTicket={goToCreateTicket}
              canCreateChat={canCreateChat}
            />
          );
        case 'SELECT_MEMBERS_GROUP':
          return (
            <SelectChatMembers
              onCancel={goToFirstTab}
              onNext={goToCreateGroup}
              queryKey={CHAT_QUERY_KEYS.searchUsers}
              queryFn={selectMembersQueryFn}
            />
          );
        case 'CREATE_GROUP':
          return (
            <CreateGroup
              users={selectedUsers}
              onBack={goToSelectMembersGroup}
            />
          );
        case 'CREATE_SUPPORT_TICKET':
          return <CreateTicket onBack={goToTickets} topic={selectedTopic} />;
        default:
          return null;
      }
    },
    [
      goToCreateGroup,
      goToCreateTicket,
      goToFirstTab,
      goToSelectMembersGroup,
      goToTickets,
      selectedTopic,
      selectedUsers,
      canCreateChat,
      canCreateGroupChat,
      canCreateTicket,
    ],
  );

  return (
    <Tabs
      ref={tabsRef}
      swipeEnabled={false}
      routes={routes}
      renderScene={renderScene}
      showHeader={false}
      lazy={true}
    />
  );
}
