import { FC, ChangeEvent, useState } from 'react';
import { useInfiniteQuery } from 'react-query';
import { useNavigate } from 'react-router-dom';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import GroupIcon from '@material-hu/icons/material/GroupOutlined';
import TagIcon from '@material-hu/icons/material/TagOutlined';
import Box from '@material-hu/mui/Box';
import Input from '@material-hu/mui/Input';
import List from '@material-hu/mui/List';
import ListItemButton from '@material-hu/mui/ListItemButton';
import ListSubheader from '@material-hu/mui/ListSubheader';
import Typography from '@material-hu/mui/Typography';

import useGeneralError from 'src/hooks/useGeneralError';
import usePermissions from 'src/hooks/usePermissions';
import SearchIcon from 'src/icons/Search';
import NewTicketDialog from 'src/pages/dashboard/tickets/components/NewTicketDialog';
import TicketItem from 'src/pages/dashboard/tickets/components/TicketItem';
import { getAllChatables } from 'src/services/chats';
import { ChatableType } from 'src/types/chats';
import { Topic } from 'src/types/tickets';
import { UserPermissions } from 'src/utils/permissions';
import { getChatablesForList } from 'src/utils/userUtils';

import { useTranslation } from 'src/components/dashboard/chat/i18n';
import { chatRoutes } from 'src/components/dashboard/chat/routes';
import PeopleItem from 'src/components/dashboard/people/PeopleItem';
import InfiniteList from 'src/components/list/InfiniteList';

import { chatKeys } from './queries';

const { VIEW_REGULAR_CHATS, VIEW_TICKETS, CREATE_REGULAR_GROUP_CHAT } =
  UserPermissions;

const { USER, TOPIC } = ChatableType;

export type PeopleAndTicketSearchProps = {
  onUserSelect?: (user) => void;
  limit?: number;
};

const PeopleAndTicketSearch: FC<PeopleAndTicketSearchProps> = props => {
  const { onUserSelect, limit } = props;
  const [query, setQuery] = useState<string>('');
  const [topicSelected, setTopicSelected] = useState<Topic>(null);
  const navigate = useNavigate();

  const { hasAll: canViewChats } = usePermissions([
    VIEW_REGULAR_CHATS,
    CREATE_REGULAR_GROUP_CHAT,
  ]);
  const { hasAll: canViewTickets } = usePermissions([VIEW_TICKETS]);

  const { t } = useTranslation();
  const showGeneralError = useGeneralError();
  const debouncedQuery = useDebounce(query);

  const { data, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } =
    useInfiniteQuery(
      chatKeys.allChatables(debouncedQuery),
      ({ pageParam = 1 }) => getAllChatables(pageParam, debouncedQuery, limit),
      {
        getNextPageParam: (_, pages) => {
          const { page, totalPages } = pages[pages.length - 1]?.data || {};
          return page < totalPages ? pages.length + 1 : undefined;
        },
        onError: err => showGeneralError(err, t('ERROR_LOADING_CHATS')),
      },
    );

  const results = data?.pages.reduce(
    (resultsAcc, page) => getChatablesForList(page.data.items, resultsAcc),
    [],
  );

  const handleChange = (event: ChangeEvent<HTMLInputElement>): void => {
    const { value } = event.target;
    setQuery(value);
  };

  const goToTickets = () => navigate(chatRoutes.new.ticket());

  const goToGroups = () => navigate(chatRoutes.new.group());

  const handleSelect = (topic: Topic) => setTopicSelected(topic);

  const handleCancel = () => {
    setTopicSelected(null);
  };

  const renderChatable = chatable => {
    if (chatable.type === USER) {
      return (
        <PeopleItem
          user={chatable}
          onSelect={onUserSelect}
        />
      );
    } else if (chatable.type === TOPIC && chatable.status !== 'DISABLED') {
      return (
        <TicketItem
          topic={chatable}
          onSelect={handleSelect}
        />
      );
    }
    return null;
  };

  const hasOnePerson = results?.some(e => e.character !== 'CHANNELS');

  return (
    <>
      {topicSelected !== null && (
        <NewTicketDialog
          open={topicSelected !== null}
          onClose={handleCancel}
          {...topicSelected}
        />
      )}
      <Box
        sx={{
          alignItems: 'center',
          backgroundColor: 'background.default',
          borderRadius: 22,
          display: 'flex',
          height: 44,
          px: 2,
          m: 1,
        }}
      >
        <SearchIcon
          color="action"
          fontSize="small"
        />
        <Box
          sx={{
            flexGrow: 1,
            m: 2,
          }}
        >
          <Input
            fullWidth
            disableUnderline
            onChange={handleChange}
            placeholder={t('SEARCH')}
            value={query}
          />
        </Box>
      </Box>
      <InfiniteList
        isSuccess={!!results}
        isLoading={isLoading}
        isEmpty={results?.length === 0}
        fetchNextPage={fetchNextPage}
        hasNextPage={hasNextPage}
        isFetchingNextPage={isFetchingNextPage}
        sx={{
          position: 'relative',
          zIndex: 0,
          overflow: 'auto',
          height: '100%',
        }}
      >
        {!debouncedQuery && (
          <>
            {canViewTickets && (
              <ListItemButton
                onClick={goToTickets}
                sx={{ py: 1 }}
              >
                <TagIcon
                  htmlColor="#1565C0"
                  sx={{
                    width: '32px',
                    height: '32px',
                    backgroundColor: '#E0E0E0',
                    borderRadius: '20px',
                    mr: 1,
                    p: 0.8,
                  }}
                />
                <Typography color="#1565C0">
                  {t('NEW_SUPPORT_TICKET')}
                </Typography>
              </ListItemButton>
            )}
            {canViewChats && (
              <ListItemButton
                onClick={goToGroups}
                sx={{ py: 1 }}
              >
                <GroupIcon
                  fontSize="large"
                  htmlColor="#1565C0"
                  sx={{
                    width: '32px',
                    height: '32px',
                    backgroundColor: '#E0E0E0',
                    borderRadius: '20px',
                    mr: 1,
                    p: 0.8,
                  }}
                />
                <Typography color="#1565C0">{t('NEW_GROUP')}</Typography>
              </ListItemButton>
            )}
          </>
        )}
        <List subheader={<li />}>
          {hasOnePerson && (
            <li key={'section-person'}>
              <ul>
                <ListSubheader sx={{ lineHeight: '45px' }}>
                  {t('PEOPLE')}
                </ListSubheader>
              </ul>
            </li>
          )}
          {results?.map(item => (
            <li key={`section-${item.character}`}>
              <ul>
                <ListSubheader style={{ top: '-2px' }}>
                  {t(item.character)}
                </ListSubheader>
                {item.chatables.map(renderChatable)}
              </ul>
            </li>
          ))}
        </List>
      </InfiniteList>
    </>
  );
};

export default PeopleAndTicketSearch;
