import { useMemo } from 'react';
import { useInfiniteQuery } from 'react-query';
import { useOutletContext } from 'react-router-dom';

import Stack from '@material-hu/mui/Stack';
import { fadeIn } from '@material-hu/utils/animations';

import SatisfactionDimensionsTable from '@material-hu/components/composed-components/peopleExperience/surveyResults/SatisfactionDimensionsTable';
import {
  type DimensionDatum,
  type SatisfactionDimensionsTableProps,
} from '@material-hu/components/composed-components/peopleExperience/surveyResults/SatisfactionDimensionsTable/types';
import TableLoader from '@material-hu/components/design-system/Table/components/TableLoader';

import { pxKeys } from '../../../../../queries';
import { distributeRoundedPercentages } from '../../../../../utils/formatting';
import { getFavDimensionStats } from '../../../../../services';
import {
  type ManagerSurvey,
  type SegmentationFilterParams,
} from '../../../../../types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import ScoreDifferenceDescription from '../../ScoreDifferenceDescription';
import useNpsChartTooltip from '../hooks/useNpsChartTooltip';
import { getCountDescription } from '../utils';

type DimensionsTableProps = {
  surveyId: ManagerSurvey['id'];
  onClickRow: SatisfactionDimensionsTableProps['onClickRow'];
  onScrollToTop: () => void;
};

const DimensionsTable = ({
  surveyId,
  onClickRow,
  onScrollToTop,
}: DimensionsTableProps) => {
  const { t } = useLokaliseTranslation('people_experience');
  const { filters } = useOutletContext<{ filters: SegmentationFilterParams }>();
  const { tooltipLabels, getTooltipTitle } = useNpsChartTooltip();

  const requestParams = {
    surveyId,
    ...filters,
  };

  const { data, isLoading, isPreviousData, fetchNextPage, isFetchingNextPage } =
    useInfiniteQuery(
      pxKeys.favDimensionStats(requestParams),
      ({ pageParam = 0 }) => {
        return getFavDimensionStats({
          limit: 30,
          page: pageParam,
          ...requestParams,
        });
      },
      {
        keepPreviousData: true,
        getNextPageParam: lastPage => {
          if (lastPage.page === lastPage.totalPages) {
            return undefined;
          }

          return lastPage.page;
        },
      },
    );

  const tableData: DimensionDatum[] = useMemo(() => {
    return (
      data?.pages.flatMap(page =>
        page.items.map(item => {
          const [promoters, detractors, neutrals] =
            distributeRoundedPercentages([
              item.metadata?.promoters ?? 0,
              item.metadata?.detractors ?? 0,
              item.metadata?.neutrals ?? 0,
            ]);
          return {
            id: item.id,
            name: item.title,
            questionsLabel: getCountDescription(
              'question.question_custom_count',
              item.questionsCount,
              t,
            ),
            hasQuestions: item.questionsCount > 0,
            score: item.score,
            baseScore: item.baseScore,
            scoreDifference: item.baseScoreDifference,
            hasThresholdPassed: item.passedThreshold,
            promoters,
            detractors,
            neutrals,
          };
        }),
      ) ?? []
    );
  }, [data, t]);

  const dimensionsCount = data?.pages[0].count ?? 0;

  return (
    <Stack
      sx={{
        gap: 2,
        ...(isPreviousData && { opacity: 0.5, pointerEvents: 'none' }),
      }}
    >
      <SatisfactionDimensionsTable
        slotProps={{
          tableContainer: {
            sx: {
              animation: `${fadeIn} 200ms ease-in-out backwards`,
            },
          },
        }}
        dimensions={tableData}
        distributionHeading={t('distribution')}
        noAnswerLabel={t('not_enough_answers')}
        noQuestionsLabel={t('no_dimension_questions')}
        dimensionsHeading={t('dimension_other')}
        scoreHeading={t('score')}
        scoreDifferenceHeading={t('difference')}
        tooltipLabels={tooltipLabels}
        getTooltipTitle={getTooltipTitle}
        dimensionsCount={dimensionsCount}
        onClickRow={onClickRow}
        loading={isLoading}
        loadingMore={isFetchingNextPage}
        differenceIndicatorMeta={{
          scoreLabel: t('filter.title'),
          baseScoreLabel: t('survey.survey'),
          footerLabel: t('comparing_results'),
          getScoreDifferenceDescription: row => (
            <ScoreDifferenceDescription difference={row.scoreDifference ?? 0} />
          ),
        }}
      />
      <TableLoader
        loadedCount={tableData.length}
        totalCount={dimensionsCount}
        onLoadMore={fetchNextPage}
        onScrollToTop={onScrollToTop}
      />
    </Stack>
  );
};

export default DimensionsTable;
