import { FC, Fragment, useMemo } from 'react';
import { InfiniteQueryObserverBaseResult } from 'react-query';
import { useNavigate, useParams } from 'react-router-dom';

import { AxiosResponse } from 'axios';

import Divider from '@material-hu/mui/Divider';

import {
  ChatListItem,
  ChatType,
  ChatListResponse,
  PaginatedChatResponse,
} from 'src/types/chats';

import { useTranslation } from 'src/components/dashboard/chat/i18n';
import { chatRoutes } from 'src/components/dashboard/chat/routes';
import { formRoutes } from 'src/components/dashboard/form/routes';
import InfiniteList from 'src/components/list/InfiniteList';
import Scrollbar from 'src/components/Scrollbar';

import ThreadItem from './ThreadItem';

export type ThreadListProps = InfiniteQueryObserverBaseResult<
  AxiosResponse<ChatListResponse | PaginatedChatResponse>
> & {
  showArchivedChats: boolean;
  isChat?: boolean;
};

export const ThreadList: FC<ThreadListProps> = props => {
  const {
    data,
    hasNextPage,
    showArchivedChats,
    isChat = false,
    ...listWrapperProps
  } = props;

  const navigate = useNavigate();
  const { id: currentId } = useParams();
  const { t } = useTranslation();

  const handleSelect = (thread: ChatListItem): void => {
    const { id } = thread.chat;
    const state = thread;
    if (thread.chatType === ChatType.FORM) {
      if (!thread.form.needApproval) {
        navigate(formRoutes.form.approvalWorkflow(thread.form?.type, id), {
          state,
        });
      } else {
        navigate(formRoutes.form.chat(thread.form?.type, id), { state });
      }
    } else {
      navigate(chatRoutes.thread.detail(id), { state });
    }
  };

  const chatsPages = useMemo(() => {
    if (showArchivedChats)
      return data?.pages.map((page: any) => ({ data: page.data.items }));
    return data?.pages || [];
  }, [showArchivedChats, data]);

  return (
    <Scrollbar
      options={{ suppressScrollX: true }}
      style={{
        height: 'calc(-44px + 100%)',
        paddingBottom: '3rem',
        minWidth: isChat ? '18em' : '21.8125em',
        width: '100%',
      }}
    >
      {showArchivedChats && (
        <ThreadInfiniteList
          isSuccess={!!chatsPages[0]?.data?.length}
          isEmpty={!chatsPages[0]?.data?.length}
          noResultsLabel={t('NO_CHATS')}
          hasNextPage={hasNextPage}
          listWrapperProps={listWrapperProps}
          chatsPages={chatsPages}
          currentId={currentId}
          handleSelect={handleSelect}
        />
      )}
      {!showArchivedChats && (
        <ThreadInfiniteList
          isSuccess={!!chatsPages[0]?.data?.length}
          isEmpty={!chatsPages[0]?.data?.length}
          noResultsLabel={t('NO_CHATS')}
          hasNextPage={hasNextPage}
          listWrapperProps={listWrapperProps}
          chatsPages={chatsPages}
          currentId={currentId}
          handleSelect={handleSelect}
        />
      )}
    </Scrollbar>
  );
};

export type ThreadInfiniteListProps = {
  isSuccess: boolean;
  isEmpty: boolean;
  noResultsLabel: string;
  hasNextPage: boolean;
  listWrapperProps;
  chatsPages: any;
  currentId: string;
  handleSelect: (thread) => void;
};

const ThreadInfiniteList: FC<ThreadInfiniteListProps> = props => {
  const {
    isSuccess,
    isEmpty,
    noResultsLabel,
    hasNextPage,
    listWrapperProps,
    chatsPages,
    currentId,
    handleSelect,
  } = props;
  return (
    <InfiniteList
      isSuccess={isSuccess}
      isEmpty={isEmpty}
      noResultsLabel={noResultsLabel}
      hasNextPage={hasNextPage}
      sx={{
        mt: 1,
        position: 'relative',
        zIndex: 0,
      }}
      {...listWrapperProps}
    >
      {chatsPages.map((chatPage, i) => (
        <Fragment key={i}>
          {chatPage?.data?.map(thread => (
            <Fragment key={thread.chat.id}>
              <ThreadItem
                active={Number(currentId) === thread.chat.id}
                onClick={(): void => handleSelect(thread)}
                thread={thread}
                isForm={thread.chatType === ChatType.FORM}
              />
              {thread.chatType === ChatType.FORM && (
                <Divider
                  sx={{
                    ml: 11,
                    '&:last-child': {
                      display: 'none',
                    },
                  }}
                />
              )}
            </Fragment>
          ))}
        </Fragment>
      ))}
    </InfiniteList>
  );
};

export default ThreadList;
