import { useCallback, useMemo, useState } from 'react';
import { useQuery } from 'react-query';
import { useOutletContext } from 'react-router-dom';

import { IconInfoCircle } from '@material-hu/icons/tabler';
import { Stack, useTheme } from '@material-hu/mui/index';

import LikertChart from '@material-hu/components/composed-components/peopleExperience/surveyResults/LikertChart';
import TableHeaderDecorator from '@material-hu/components/composed-components/peopleExperience/surveyResults/SatisfactionDrawerCommentList/components/TableHeaderDecorator';
import SatisfactionDrawerStats from '@material-hu/components/composed-components/peopleExperience/surveyResults/SatisfactionDrawerStats';
import ScoreDifferenceIndicator from '@material-hu/components/composed-components/peopleExperience/surveyResults/ScoreDifferenceIndicator';
import SelectChart from '@material-hu/components/composed-components/peopleExperience/surveyResults/SelectChart';
import TextChart from '@material-hu/components/composed-components/peopleExperience/surveyResults/TextChart';
import Spinner from '@material-hu/components/design-system/ProgressIndicators/Spinner';
import StateCard from '@material-hu/components/design-system/StateCard';

import { pxKeys } from '../../../../../../../../queries';
import { formatAmount } from '../../../../../../../../utils/formatting';
import { getQuestionStats } from '../../../../../../../../services';
import {
  QuestionTemplateType,
  type SegmentationFilterParams,
} from '../../../../../../../../types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import ScoreDifferenceDescription from '../../../../../ScoreDifferenceDescription';
import { SELECT_QUESTION_TYPE } from '../../types';

import ChartFooter from './ChartFooter';
import QuestionCommentList from './components/QuestionCommentList';
import { type QuestionDrawerProps } from './types';
import {
  getKeyValueChartData,
  getLikertChartData,
  getQuestionStatColors,
} from './utils';

const QuestionDrawer = ({
  question,
  surveyId,
  onScrollTop,
}: QuestionDrawerProps) => {
  const { t } = useLokaliseTranslation('people_experience');
  const theme = useTheme();
  const [selectedFilter, setSelectedFilter] = useState<number | null>(null);

  const { filters } = useOutletContext<{ filters: SegmentationFilterParams }>();

  const { data: chartData, isLoading: isChartLoading } = useQuery(
    pxKeys.questionStats({
      formId: surveyId,
      questionId: question.id,
      ...filters,
    }),
    () =>
      getQuestionStats({
        formId: surveyId,
        questionId: question.id,
        ...filters,
      }),
    {
      select: res => res.data,
    },
  );

  const hasDisplayData =
    !!chartData?.answersCount && chartData?.passedThreshold;

  const processedLikertChartData = useMemo(() => {
    if (!chartData || question.type !== QuestionTemplateType.LIKERT) return [];
    return getLikertChartData(chartData);
  }, [chartData, question.type]);

  const processedKeyValueChartData = useMemo(() => {
    if (!chartData || question.type === QuestionTemplateType.LIKERT) return [];
    return getKeyValueChartData(chartData);
  }, [chartData, question.type]);

  const renderChart = () => {
    if (isChartLoading) {
      return (
        <Stack sx={{ alignItems: 'center', p: 4 }}>
          <Spinner />
        </Stack>
      );
    }

    if (!hasDisplayData) {
      return (
        <StateCard
          title={t('not_enough_data_title')}
          description={t('not_enough_data_description')}
          icon={IconInfoCircle}
          variant="primary"
        />
      );
    }

    if (!chartData) {
      return null;
    }

    switch (question.type) {
      case QuestionTemplateType.LIKERT:
        return (
          <LikertChart
            data={processedLikertChartData}
            onBarClick={setSelectedFilter}
            footer={<ChartFooter />}
          />
        );
      case QuestionTemplateType.TEXT:
        return <TextChart data={processedKeyValueChartData} />;
      case SELECT_QUESTION_TYPE:
        return (
          <SelectChart
            data={processedKeyValueChartData}
            onSegmentClick={setSelectedFilter}
            footer={<ChartFooter />}
          />
        );
      default:
        return null;
    }
  };

  const answerFilters = useMemo(() => {
    if (selectedFilter === null) {
      return { integerAnswer: undefined, stringAnswer: undefined };
    }

    switch (question.type) {
      case QuestionTemplateType.LIKERT:
        return { integerAnswer: selectedFilter + 1, stringAnswer: undefined };
      case SELECT_QUESTION_TYPE:
        return {
          integerAnswer: undefined,
          stringAnswer: chartData?.choices[selectedFilter],
        };
      case QuestionTemplateType.TEXT:
        return {
          integerAnswer: undefined,
          stringAnswer: Object.keys(chartData?.stats ?? {})[selectedFilter],
        };
      default:
        return { integerAnswer: undefined, stringAnswer: undefined };
    }
  }, [selectedFilter, question.type, chartData]);

  const selectedChartItem = useMemo(() => {
    if (selectedFilter === null) return null;

    switch (question.type) {
      case QuestionTemplateType.LIKERT: {
        if (processedLikertChartData.length === 0) return null;
        const item = processedLikertChartData[selectedFilter];
        if (!item) return null;
        const colors = getQuestionStatColors(theme, item.sentimentType);
        return { label: item.label, percentage: item.percentage, colors };
      }
      case SELECT_QUESTION_TYPE: {
        if (processedKeyValueChartData.length === 0 || !chartData) return null;
        const item = processedKeyValueChartData[selectedFilter];
        if (!item) return null;
        const percentage = chartData.percentageStats[item.label] ?? 0;
        return {
          label: item.label,
          percentage,
          colors: {
            backgroundColor: theme.palette.new.background.feedback.highlight,
            textColor: theme.palette.new.text.feedback.highlight,
          },
        };
      }
      default:
        return null;
    }
  }, [
    selectedFilter,
    question.type,
    processedLikertChartData,
    processedKeyValueChartData,
    chartData,
    theme.palette.new,
  ]);

  const renderDecorator = useCallback(
    (count: number) => {
      if (!selectedChartItem) return null;

      return (
        <TableHeaderDecorator
          backgroundColor={selectedChartItem.colors.backgroundColor}
          textColor={selectedChartItem.colors.textColor}
          title={`"${selectedChartItem.label}"`}
          description={`${t('comment.percent_selected', {
            count: selectedChartItem.percentage,
          })} • ${t('comment_count', {
            count,
            value: formatAmount(count),
          })}`}
        />
      );
    },
    [selectedChartItem, t],
  );

  return (
    <Stack sx={{ gap: 2 }}>
      <SatisfactionDrawerStats
        score={question.score ?? 0}
        answers={question.answersAmount}
        comments={question.commentsAmount}
        format={question.typeLabel}
        scoreLabel={t('score')}
        answersLabel={t('answer.answers')}
        commentsLabel={t('comment.comments')}
        formatLabel={t('question.format')}
        scoreInfo={t('score_description')}
        scoreDifferenceIndicator={
          question.scoreDifference &&
          question.baseScore &&
          question.score && (
            <ScoreDifferenceIndicator
              difference={question.scoreDifference}
              popoverMeta={{
                baseScoreLabel: t('survey.survey'),
                scoreLabel: t('filter.title'),
                footerLabel: t('comparing_results'),
                scoreDifferenceDescription: (
                  <ScoreDifferenceDescription
                    difference={question.scoreDifference}
                  />
                ),
                score: question.score,
                baseScore: question.baseScore,
              }}
              slotProps={{
                popover: {
                  anchorOrigin: {
                    vertical: 24,
                    horizontal: 'left',
                  },
                  transformOrigin: {
                    vertical: 'top',
                    horizontal: 'left',
                  },
                },
              }}
            />
          )
        }
        hideScore={question.type !== QuestionTemplateType.LIKERT}
      />
      {renderChart()}
      <QuestionCommentList
        questionId={question.id}
        surveyId={surveyId}
        questionType={question.type}
        onScrollTop={onScrollTop}
        stringAnswer={answerFilters.stringAnswer}
        integerAnswer={answerFilters.integerAnswer}
        renderDecorator={renderDecorator}
      />
    </Stack>
  );
};

export default QuestionDrawer;
