import { type FC, useState } from 'react';
import { useInfiniteQuery } from 'react-query';
import { useParams } from 'react-router-dom';

import { uniqBy } from 'lodash-es';
import { useDebounce } from '@material-hu/hooks/useDebounce';
import { IconUsersPlus } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuList from '@material-hu/components/design-system/List';
import HuListItem from '@material-hu/components/design-system/List/components/ListItem';

import useGeneralError from 'src/hooks/useGeneralError';
import {
  CALL_SNACKBAR_BOTTOM_SPACING,
  MAX_CALL_PARTICIPANTS,
} from 'src/pages/dashboard/videoCall/constants';
import { videoCallKeys } from 'src/pages/dashboard/videoCall/queries';
import { getVideoCallParticipants } from 'src/services/streaming';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getNextCursor } from 'src/utils/pagination';
import { getInitials } from 'src/utils/userUtils';

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

import ListEmptyState from '../ListEmptyState';

export type ParticipantListDrawerProps = {
  showAddParticipantModal: () => void;
};

const ParticipantListDrawer: FC<ParticipantListDrawerProps> = props => {
  const { showAddParticipantModal } = props;

  const [query, setQuery] = useState<string>('');
  const debouncedQuery = useDebounce(query);
  const showGeneralError = useGeneralError();
  const { t } = useLokaliseTranslation('calls');
  const { callId } = useParams();

  const { data: callParticipantsData, ...callParticipantsDataProps } =
    useInfiniteQuery(
      videoCallKeys.callParticipants(debouncedQuery),
      ({ pageParam = '' }) => {
        return getVideoCallParticipants({
          id: callId ?? '',
          q: debouncedQuery,
          limit: 10,
          cursor: pageParam,
        });
      },
      {
        enabled: !!callId,
        getNextPageParam: getNextCursor,
        onError: err =>
          showGeneralError(err, t('ERROR_GET_LIST_USERS'), true, {
            spacing: {
              bottom: CALL_SNACKBAR_BOTTOM_SPACING,
            },
          }),
      },
    );

  const callParticipants = callParticipantsData?.pages.flatMap(
    page => page.data.items,
  );

  const uniqueProviderParticipants = uniqBy(callParticipants, 'id');
  const sortedParticipants = uniqueProviderParticipants.sort((a, b) => {
    if (a.isCalling && !b.isCalling) return 1;
    if (!a.isCalling && b.isCalling) return -1;
    return 0;
  });

  return (
    <Stack sx={{ height: '100%' }}>
      <Stack
        sx={{
          flexDirection: 'row',
          alignItems: 'center',
          gap: 3,
          mb: 2,
        }}
      >
        <HuSearch
          variant="custom"
          onChange={setQuery}
          value={query}
          sx={{ flex: 1 }}
        />
        <Button
          variant="contained"
          size="small"
          startIcon={<IconUsersPlus size={16} />}
          onClick={showAddParticipantModal}
          disabled={callParticipants?.length === MAX_CALL_PARTICIPANTS}
        >
          {t('ADD_MEMBER')}
        </Button>
      </Stack>
      <Typography
        variant="globalM"
        fontWeight="fontWeightSemiBold"
        sx={{ mb: 2 }}
      >
        {t('PARTICIPANTS_IN_CALL')}
      </Typography>
      <InfiniteList
        isSuccess={callParticipantsDataProps?.isSuccess}
        hasNextPage={callParticipantsDataProps?.hasNextPage}
        fetchNextPage={callParticipantsDataProps?.fetchNextPage}
        isFetchingNextPage={callParticipantsDataProps?.isFetchingNextPage}
        isLoading={callParticipantsDataProps?.isLoading}
        isEmpty={
          callParticipantsDataProps?.isSuccess && !callParticipants?.length
        }
        showNoResultsMessage={false}
      >
        <HuList>
          {sortedParticipants.map(participant => (
            <HuListItem
              key={participant.id}
              avatar={{
                src: participant.profilePicture || '',
                text: getInitials(participant.fullName),
              }}
              text={{
                title: participant.fullName,
              }}
              sx={{
                '& li': { py: 1, px: 0 },
              }}
              sideContent={
                participant.isCalling && (
                  <Typography
                    variant="globalXS"
                    color="new.text.neutral.lighter"
                  >
                    {t('CALLING')}
                  </Typography>
                )
              }
            />
          ))}
        </HuList>
      </InfiniteList>
      {sortedParticipants.length === 0 &&
        !callParticipantsDataProps?.isLoading && (
          <ListEmptyState
            title={t('EMPTY_SEARCH_RESULTS')}
            description={t('EMPTY_SEARCH_RESULTS_DESCRIPTION')}
          />
        )}
    </Stack>
  );
};

export default ParticipantListDrawer;
