import { FC, memo } from 'react';
import { useInfiniteQuery } from 'react-query';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import Box from '@material-hu/mui/Box';
import Checkbox from '@material-hu/mui/Checkbox';
import Container from '@material-hu/mui/Container';
import FormControlLabel from '@material-hu/mui/FormControlLabel';
import FormGroup from '@material-hu/mui/FormGroup';
import List from '@material-hu/mui/List';
import ListSubheader from '@material-hu/mui/ListSubheader';

import useGeneralError from 'src/hooks/useGeneralError';
import { getGroupList } from 'src/services/chats';
import { ChatListItem } from 'src/types/chats';
import { getGroupsForSectionList } from 'src/utils/chats';
import { getNextPage, getListLength } from 'src/utils/pagination';

import { useTranslation } from 'src/components/dashboard/chat/i18n';
import { peopleSearchKeys } from 'src/components/dashboard/people/queries';
import InfiniteList from 'src/components/list/InfiniteList';
import Scrollbar from 'src/components/Scrollbar';

export type GroupListProps = {
  query: string;
  limit?: number;
  listContainerStyle?: any;
  listSubHeaderStyle?: any;
  groups: any;
  setGroups: any;
};

export const GroupList: FC<GroupListProps> = props => {
  const {
    query,
    limit = 100,
    listContainerStyle = {},
    listSubHeaderStyle = {},
    groups,
    setGroups,
  } = props;

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

  const { data, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } =
    useInfiniteQuery(
      peopleSearchKeys.searchGroup(debouncedQuery),
      ({ pageParam = 1 }) => getGroupList(debouncedQuery, pageParam, limit),
      {
        getNextPageParam: (lastPage, pages) =>
          getNextPage(getListLength(pages), limit, pages),
        onError: err => showGeneralError(err, t('ERROR_LOADING_GROUPS')),
      },
    );

  const results = data?.pages
    .reduce(
      (resultsAcc, page) => getGroupsForSectionList(page.data, resultsAcc),
      [],
    )
    .sort((first, second) => (first.character > second.character ? 1 : -1));

  const handleChange = (id: number, checked: boolean) => {
    const newGroups = [...groups];
    const index = newGroups.indexOf(id);
    const finded = index !== -1;

    if (checked && !finded) {
      newGroups.push(id);
    } else if (!checked && finded) {
      newGroups.splice(index, 1);
    }
    setGroups(newGroups);
  };

  const renderUser = (group: ChatListItem) => (
    <Box sx={{ ml: 4 }}>
      <FormGroup key={group.chat?.id}>
        <FormControlLabel
          control={
            <Checkbox
              checked={groups.includes(group.chat?.id)}
              onChange={e => handleChange(group.chat?.id, e.target.checked)}
            />
          }
          label={group.title}
        />
      </FormGroup>
    </Box>
  );

  return (
    <Container sx={{ height: '300px', p: '0 !important' }}>
      <Scrollbar
        options={{ suppressScrollX: true }}
        style={{
          height: 'calc(-44px + 100%)',
          paddingBottom: '1rem',
          ...listContainerStyle,
        }}
      >
        <InfiniteList
          isSuccess={!!results}
          isLoading={isLoading}
          isEmpty={results?.length === 0}
          fetchNextPage={fetchNextPage}
          hasNextPage={hasNextPage}
          isFetchingNextPage={isFetchingNextPage}
          sx={{
            mt: 2,
            position: 'relative',
            zIndex: 0,
          }}
        >
          <List subheader={<li />}>
            {results?.map(item => (
              <li key={`section-${item.character}`}>
                <ul>
                  <ListSubheader
                    style={{
                      ...listSubHeaderStyle,
                    }}
                  >
                    {item.character}
                  </ListSubheader>
                  {item.groups.map(renderUser)}
                </ul>
              </li>
            ))}
          </List>
        </InfiniteList>
      </Scrollbar>
    </Container>
  );
};

export default memo(GroupList);
