import { useMemo, useRef } from 'react';
import { useInfiniteQuery } from 'react-query';

import { useOutletContext } from 'react-router-dom';

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

import SatisfactionQuestionsTable from '@material-hu/components/composed-components/peopleExperience/surveyResults/SatisfactionQuestionsTable';
import Pill from '@material-hu/components/design-system/Pills';
import TableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import { pxKeys } from '../../../../../../queries';
import { getFavQuestionsStats } from '../../../../../../services';
import {
  FavQuestionsStatsParams,
  SegmentationFilterParams,
} from '../../../../../../types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import ScoreDifferenceDescription from '../../../ScoreDifferenceDescription';
import useNpsChartTooltip from '../../hooks/useNpsChartTooltip';

import QuestionDrawer from './components/QuestionDrawer';
import { ParsedQuestionStats, QuestionsTableProps } from './types';
import { parseQuestionStatsToTableFormat } from './utils';

const QuestionsTable = ({
  surveyId,
  dimensionId,
  onScrollToTop,
}: QuestionsTableProps) => {
  const { t } = useLokaliseTranslation('people_experience');
  const { filters } = useOutletContext<{ filters: SegmentationFilterParams }>();
  const { tooltipLabels, getTooltipTitle } = useNpsChartTooltip();
  const drawerLayoutRef = useRef<HTMLDivElement>(null);

  const hasFiltersApplied = useMemo(() => {
    return Object.values(filters).some(filter => filter.length > 0);
  }, [filters]);

  const requestParams: FavQuestionsStatsParams = {
    surveyId,
    topicId: dimensionId,
    ...filters,
  };

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

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

  const tableData = useMemo(
    () =>
      data?.pages.flatMap(page =>
        page.items.map(item => parseQuestionStatsToTableFormat(item, t)),
      ) ?? [],
    [data, t],
  );

  const { showDrawer, drawer } = useDrawer<{
    question: ParsedQuestionStats;
  }>(({ question }) => {
    return {
      title: question?.statement,
      hasBackButton: true,
      PaperProps: {
        sx: {
          width: '100%',
          maxWidth: '1352px',
        },
      },
      titleDecorator: hasFiltersApplied ? (
        <Pill
          label={t('filters_applied')}
          type="warning"
          size="small"
        />
      ) : undefined,
      children: (
        <QuestionDrawer
          question={question}
          surveyId={surveyId}
          onScrollTop={() => {
            drawerLayoutRef.current?.scrollTo({
              top: 0,
              behavior: 'smooth',
            });
          }}
        />
      ),
      slotProps: {
        layout: {
          ref: drawerLayoutRef,
        },
      },
    };
  });

  return (
    <Stack
      sx={{
        gap: 2,
        ...(isPreviousData && {
          opacity: 0.5,
          pointerEvents: 'none',
        }),
      }}
    >
      <SatisfactionQuestionsTable
        questions={tableData}
        questionsCount={questionsCount}
        questionsHeading={t('question_other')}
        distributionHeading={t('distribution')}
        scoreHeading={t('score')}
        scoreDifferenceHeading={t('difference')}
        noAnswerLabel={t('not_enough_answers')}
        openCommentLabel={t('open_comment')}
        tooltipLabels={tooltipLabels}
        getTooltipTitle={getTooltipTitle}
        noScoreMessage={t('warning_likert_exclusive')}
        onRowClick={row => showDrawer({ question: row })}
        slotProps={{
          tableContainer: {
            sx: {
              animation: `${fadeIn} 200ms ease-in-out backwards`,
              opacity: isPreviousData ? 0.5 : 1,
            },
          },
        }}
        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={questionsCount}
        onLoadMore={fetchNextPage}
        onScrollToTop={onScrollToTop}
      />
      {drawer}
    </Stack>
  );
};

export default QuestionsTable;
