import { type FC, Fragment } from 'react';
import { type InfiniteQueryObserverBaseResult } from 'react-query';

import Divider from '@material-hu/mui/Divider';
import ListItemButton from '@material-hu/mui/ListItemButton';
import ListSubheader from '@material-hu/mui/ListSubheader';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox';

import { BUNNY_IMAGE_CLASSES } from 'src/pages/dashboard/Conversations/constants';
import {
  type ConversationUser,
  type Member,
} from 'src/pages/dashboard/Conversations/types';
import { getChatablesForList } from 'src/pages/dashboard/Conversations/utils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getInitials } from 'src/utils/userUtils';

import LazySecureImage from '../shared/LazySecureImage';
import ThreadInfiniteList from '../shared/ThreadInfiniteList';

type UsersListProps = {
  withCheckbox?: boolean;
  onSelectMember: (member: any) => void;
  members: ConversationUser[];
  selectedMembers?: Member[];
  withoutContainer?: boolean;
  hasNextPage: boolean;
  listWrapperProps: Pick<
    InfiniteQueryObserverBaseResult<unknown, unknown>,
    'hasNextPage' | 'fetchNextPage' | 'isFetchingNextPage' | 'isLoading'
  >;
  membersToExclude?: number[];
};

const UsersList: FC<UsersListProps> = props => {
  const {
    onSelectMember,
    withCheckbox = false,
    selectedMembers,
    members,
    hasNextPage,
    listWrapperProps,
    withoutContainer = false,
    membersToExclude = [],
  } = props;
  const { t } = useLokaliseTranslation('chat');

  const results = members.reduce<
    {
      character: string;
      chatables: Member[];
    }[]
  >((resultsAcc, member) => getChatablesForList(member, resultsAcc), []);

  const renderChatable = ({
    character,
    chatables,
  }: {
    character: string;
    chatables: Member[];
  }) => {
    const Container = withoutContainer ? Stack : HuCardContainer;

    return (
      <Stack
        sx={{ pb: 2, alignItems: 'center' }}
        key={character}
      >
        <ListSubheader
          sx={{
            zIndex: 1,

            backgroundColor: theme =>
              theme.palette.new.background.layout.tertiary,
            width: '100%',
          }}
        >
          <Typography
            sx={{ pb: 2 }}
            variant="globalS"
          >
            {character}
          </Typography>
        </ListSubheader>
        <Container
          sx={{
            pb: 0,
            ...(!withoutContainer && { '& .MuiCardContent-root': { p: 0 } }),
            ...(withoutContainer && { width: '100%', px: 2 }),
          }}
        >
          {chatables.map((member, index) => {
            const isNonAddableMember = membersToExclude?.some(
              id => id === member.id,
            );

            const isChecked =
              selectedMembers?.some(
                selectedMember => selectedMember.id === member.id,
              ) || isNonAddableMember;

            return (
              <Fragment key={member.id}>
                <ListItemButton
                  onClick={() => {
                    onSelectMember(member);
                  }}
                  sx={{ p: 0, px: 2 }}
                >
                  <Stack
                    sx={{
                      my: 2,
                      flexDirection: 'row',
                      gap: 1,
                      width: '100%',
                      alignItems: 'center',
                    }}
                  >
                    {withCheckbox && (
                      <HuCheckbox
                        sx={{ zIndex: 0 }}
                        label=""
                        disabled={isNonAddableMember}
                        checked={isChecked}
                        onClick={e => {
                          onSelectMember(member);
                          e.stopPropagation();
                        }}
                      />
                    )}
                    <LazySecureImage
                      url={member.picture_asset_url}
                      isAvatar
                      imageClass={BUNNY_IMAGE_CLASSES.AVATAR}
                      avatarProps={{
                        text: getInitials(
                          `${member.first_name} ${member.last_name}`,
                        ),
                      }}
                    />
                    <Stack>
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {`${member.first_name} ${member.last_name}`}
                      </Typography>
                      {isNonAddableMember && (
                        <Typography
                          variant="globalXXS"
                          sx={{
                            color: theme =>
                              theme.palette.new.text.neutral.lighter,
                          }}
                        >
                          {t('groups.already_member')}
                        </Typography>
                      )}
                    </Stack>
                  </Stack>
                </ListItemButton>
                {index !== chatables.length - 1 && <Divider sx={{ mx: 2 }} />}
              </Fragment>
            );
          })}
        </Container>
      </Stack>
    );
  };

  return (
    <ThreadInfiniteList
      isSuccess={!!members?.length}
      isEmpty={!members?.length}
      hasNextPage={hasNextPage}
      isLoading={listWrapperProps.isLoading}
      listWrapperProps={listWrapperProps}
    >
      {results.map(renderChatable)}
    </ThreadInfiniteList>
  );
};

export default UsersList;
