import { useCallback, useRef } from 'react';
import { useNavigate } from 'react-router-dom';

import useVirtualizer from '@material-hu/hooks/useVirtualizer';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';

import ListItem from '@material-hu/components/design-system/List/components/ListItem';
import StateCard from '@material-hu/components/design-system/StateCard';

import { profileRoutes } from 'src/pages/dashboard/profile/routes';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  RANKING_MAX_HEIGHT,
  RANKING_ROW_HEIGHT_ESTIMATE,
} from '../../constants';
import { useGetKudosRanking } from '../../hooks/useGetKudosRanking';
import { useKudosRankingFilters } from '../../hooks/useKudosRankingFilters';
import { getThinScrollbarStyles } from '../../utils';

import { RankingHeader } from './RankingHeader';
import { RankingListFooter } from './RankingListFooter';
import { RankingListItem } from './RankingListItem';

type RankingListProps = {
  canSeeRanking: boolean;
};

export const RankingList = ({ canSeeRanking }: RankingListProps) => {
  const { t } = useLokaliseTranslation('acknowledgements');
  const navigate = useNavigate();
  const { palette } = useTheme();
  const { appliedFilters, appliedFiltersCount } = useKudosRankingFilters();
  const scrollElementRef = useRef<HTMLDivElement>(null);

  const handleClickUser = useCallback(
    (userId: number) => navigate(profileRoutes.profile(userId)),
    [navigate],
  );

  const {
    users = [],
    isLoading,
    hasNextPage,
    isFetchingNextPage,
    showRankingEnd,
    fetchNextPage,
  } = useGetKudosRanking({ enabled: !!canSeeRanking, filters: appliedFilters });

  const { virtualRows, rowVirtualizer } = useVirtualizer({
    scrollElementRef,
    registers: users,
    hasNextPage,
    isFetchingNextPage,
    fetchNextPage,
    virtualizerOptions: {
      count: users.length,
      enabled: users.length > 0,
      estimateSize: () => RANKING_ROW_HEIGHT_ESTIMATE,
      getScrollElement: () => scrollElementRef.current,
    },
  });

  if (isLoading) {
    return (
      <Stack sx={{ height: RANKING_MAX_HEIGHT }}>
        {Array.from({ length: 6 }).map((_, i) => (
          <ListItem
            key={i}
            loading
          />
        ))}
      </Stack>
    );
  }

  if (!users.length) {
    const empty =
      appliedFiltersCount > 0
        ? {
            title: t('ranking_empty_filtered.title'),
            description: t('ranking_empty_filtered.description'),
          }
        : {
            title: t('ranking_empty.title'),
            description: t('ranking_empty.description'),
          };

    return (
      <StateCard
        variant="primary"
        title={empty.title}
        description={empty.description}
        slotProps={{
          card: {
            sx: {
              border: 'none',
              '.MuiCardContent-root': { py: 2, px: 1 },
            },
          },
        }}
      />
    );
  }

  return (
    <>
      <RankingHeader />
      <Stack
        ref={scrollElementRef}
        sx={{
          maxHeight: RANKING_MAX_HEIGHT,
          ...getThinScrollbarStyles(palette),
        }}
      >
        <Stack
          sx={{
            height: `${rowVirtualizer.getTotalSize()}px`,
            width: '100%',
            position: 'relative',
            overflow: 'hidden',
            flexShrink: 0,
          }}
        >
          {virtualRows.map(virtualRow => {
            const user = users[virtualRow.index];
            if (!user) return null;
            return (
              <RankingListItem
                key={user.userId}
                virtualRow={virtualRow}
                measureElement={rowVirtualizer.measureElement}
                showDivider={virtualRow.index < users.length - 1}
                user={user}
                onClickUser={handleClickUser}
              />
            );
          })}
        </Stack>
        {isFetchingNextPage && <ListItem loading />}
        {showRankingEnd && <RankingListFooter />}
      </Stack>
    </>
  );
};
