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 HuAvatar from '@material-hu/components/design-system/Avatar';
import HuCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox';

import { type Participant, type ParticipantList } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getParticipantsForList } from 'src/utils/stream';
import { getInitials } from 'src/utils/userUtils';

import InfiniteList from 'src/components/list/InfiniteList';

import ListEmptyState from '../ListEmptyState';

type AddParticipantListProps = {
  onSelectParticipant: (participant: Participant) => void;
  participants: Participant[];
  selectedParticipants?: Participant[];
  listWrapperProps: Pick<
    InfiniteQueryObserverBaseResult<unknown, unknown>,
    | 'hasNextPage'
    | 'fetchNextPage'
    | 'isFetchingNextPage'
    | 'isLoading'
    | 'isSuccess'
  > & { isEmpty: boolean; showNoResultsMessage: boolean };
  disabledSelectMoreParticipant: boolean;
};

const AddParticipantList: FC<AddParticipantListProps> = props => {
  const {
    onSelectParticipant,
    selectedParticipants,
    participants,
    listWrapperProps,
    disabledSelectMoreParticipant,
  } = props;
  const { t } = useLokaliseTranslation('calls');

  const results = participants.reduce(
    (resultsAcc: ParticipantList[], participant) =>
      getParticipantsForList(participant, resultsAcc),
    [],
  );

  const renderParticipants = ({
    character,
    participants: participantList,
  }: {
    character: string;
    participants: Participant[];
  }) => {
    return (
      <Stack key={character}>
        <ListSubheader sx={{ width: '100%', px: 0, lineHeight: '38px' }}>
          <Typography
            variant="globalS"
            fontWeight="fontWeightSemiBold"
          >
            {character}
          </Typography>
        </ListSubheader>

        <Stack sx={{ width: '100%' }}>
          {participantList.map((participant, index) => {
            const isChecked = selectedParticipants?.some(
              selectedParticipant => selectedParticipant.id === participant.id,
            );

            const isDisabled =
              (!isChecked && disabledSelectMoreParticipant) ||
              participant.isCalling;

            return (
              <Fragment key={participant.id}>
                <ListItemButton
                  onClick={() => onSelectParticipant(participant)}
                  disabled={isDisabled}
                  sx={{ px: 0.25, py: 1 }}
                >
                  <Stack
                    sx={{
                      flexDirection: 'row',
                      width: '100%',
                      alignItems: 'center',
                      justifyContent: 'space-between',
                    }}
                  >
                    <Stack
                      sx={{
                        flexDirection: 'row',
                        alignItems: 'center',
                        gap: 1,
                      }}
                    >
                      <HuCheckbox
                        sx={{ p: 0 }}
                        checked={isChecked}
                        onClick={e => {
                          onSelectParticipant(participant);
                          e.stopPropagation();
                        }}
                      />
                      <HuAvatar
                        src={participant.profilePicture ?? undefined}
                        text={getInitials(participant.fullName)}
                      />
                      <Typography
                        variant="globalXS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {participant.fullName}
                      </Typography>
                    </Stack>
                    {participant.isCalling && (
                      <Typography
                        variant="globalXXS"
                        color="new.text.neutral.lighter"
                      >
                        {t('CALLING')}
                      </Typography>
                    )}
                  </Stack>
                </ListItemButton>
                {index !== participantList.length - 1 && <Divider />}
              </Fragment>
            );
          })}
        </Stack>
      </Stack>
    );
  };

  return (
    <Stack
      sx={{
        flexGrow: 1,
        overflowY: 'auto',
        '::-webkit-scrollbar': {
          height: '0px',
          background: 'transparent',
        },
        '::-webkit-scrollbar-thumb': {
          borderRadius: '0px',
          backgroundColor: 'transparent',
        },
        '::-webkit-scrollbar-track': {},
      }}
    >
      <InfiniteList {...listWrapperProps}>
        {results.map(renderParticipants)}
      </InfiniteList>
      {participants?.length === 0 && !listWrapperProps.isLoading && (
        <ListEmptyState
          title={t('EMPTY_SEARCH_RESULTS')}
          description={t('EMPTY_SEARCH_RESULTS_DESCRIPTION')}
        />
      )}
    </Stack>
  );
};

export default AddParticipantList;
