import React, {useCallback, useState} from 'react';
import {ListRenderItem, Pressable} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useDispatch} from 'react-redux';
import {useMutation, useQueryClient} from 'react-query';
import {IconHash} from '@tabler/icons-react-native';
import {ListItem} from '@components';
import Icon, {IconName} from '@components/Icon';
import {
  BottomModalMenuOption,
  BottomModalMenu,
  BottomModalList,
} from '@components/Modals';
import {useInfiniteQuery} from '@hooks/queries/useInfiniteQuery';
import {Topic} from '@interfaces/topics';
import {FormStepType} from '@modules/form/interfaces';
import {updateTicket} from '@modules/chat/redux';
import {
  assignMeTicket,
  changeTopicOfTicket,
  closeTicket,
  getTopicsQuery,
} from '@modules/chat/services';
import {TICKETS_QUERY_KEYS} from '@modules/chat/constants';
import {goBack} from '@navigation/navigator';
import {showSnackbar} from '@redux/dispatchers';
import {wait} from '@shared/utils';

const filterRule = (item: Topic, searchText: string) =>
  item.name.toLocaleLowerCase().includes(searchText);

const keyExtractor = (item: Topic) => item.id.toString();

interface Props {
  ticketId?: number;
  ticketStatus?: FormStepType;
}

export function TicketActionButton({ticketStatus, ticketId}: Props) {
  const queryClient = useQueryClient();
  const dispatch = useDispatch();
  const {t} = useTranslation();
  const [showModal, setShowModal] = useState(false);
  const [isTopicListVisible, setIsTopicListVisible] = useState(false);
  const options = [
    ticketStatus === FormStepType.UNASSIGNED && {
      key: 'assign',
      leftIcon: 'add' as IconName,
      label: t('chats.assign_me'),
    },
    ticketStatus === FormStepType.ASSIGNED && {
      key: 'finish',
      leftIcon: 'check' as IconName,
      label: t('chats.finalize'),
    },
    {
      key: 'move',
      leftIcon: 'edit' as IconName,
      label: t('chats.change_channel'),
    },
  ].filter(Boolean) as BottomModalMenuOption[];

  const {mutate: changeTopicMutation, isLoading: isChangeTopicLoading} =
    useMutation(changeTopicOfTicket, {
      onSuccess: () => {
        showSnackbar({
          title: t('chats.successfully_changed_channel'),
          variant: 'success',
        });
        goBack();
      },
    });

  const {data: topics, getNextPage} = useInfiniteQuery(
    TICKETS_QUERY_KEYS.topicList,
    ({page}) => getTopicsQuery({page}),
  );

  const onMorePress = () => {
    setShowModal(true);
  };

  const onClose = () => {
    setShowModal(false);
  };

  const onTopicListClose = () => {
    setIsTopicListVisible(false);
  };

  const onOptionPress = async (id: string) => {
    onClose();

    if (!ticketId) {
      return;
    }

    try {
      if (id === 'assign') {
        const response = await assignMeTicket(ticketId);
        dispatch(updateTicket(response));
        showSnackbar({
          title: t('chats.successfully_assigned_query'),
          variant: 'success',
        });
      } else if (id === 'move') {
        await wait(500);
        setIsTopicListVisible(true);
      } else if (id === 'finish') {
        const response = await closeTicket(ticketId);
        dispatch(updateTicket(response));
        showSnackbar({
          title: t('chats.successfully_finalized_query'),
          variant: 'success',
        });
        queryClient.refetchQueries(
          TICKETS_QUERY_KEYS.ticketList(FormStepType.PENDING),
        );
        queryClient.refetchQueries(
          TICKETS_QUERY_KEYS.ticketList(FormStepType.CLOSED),
        );
      }
    } catch (error) {
      // Do nothing
    }
  };

  const onSelectTicket = useCallback(
    (topic: Topic) => {
      if (!isChangeTopicLoading && ticketId) {
        changeTopicMutation({
          ticketId,
          topicId: topic.id,
        });
      }
    },
    [changeTopicMutation, isChangeTopicLoading, ticketId],
  );

  const renderItem: ListRenderItem<Topic> = useCallback(
    ({item}) => (
      <ListItem
        title={item.name}
        avatar={{
          Icon: IconHash,
        }}
        withRightIcon
        onItemPress={() => onSelectTicket(item)}
        presentation="flat"
      />
    ),
    [onSelectTicket],
  );

  return (
    <>
      <Pressable onPress={onMorePress}>
        <Icon name="moreVert" />
      </Pressable>
      <BottomModalMenu
        isVisible={showModal}
        onClose={onClose}
        options={options}
        onOptionPress={onOptionPress}
        title={t('general.options')}
      />
      <BottomModalList
        isVisible={isTopicListVisible}
        title={t('chats.change_channel')}
        onClose={onTopicListClose}
        data={topics}
        filterable
        filterRule={filterRule}
        renderItem={renderItem}
        keyExtractor={keyExtractor}
        onEndReached={getNextPage}
      />
    </>
  );
}
