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

import useGeneralError from 'src/hooks/useGeneralError';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getNextPageParam } from 'src/utils/pagination';

import useModuleConfiguration from '../../hooks/useModuleConfiguration';
import { serviceManagementKeys } from '../../queries';
import {
  getCsatMetrics,
  getCsatResponses,
  getTaskMetrics,
} from '../../services';
import {
  type CsatRating,
  type DateRange,
  type MetricFiltersForm,
  SurveyQuestionType,
} from '../../types';
import { deriveDateRangeFromFilters, getStateName } from '../../utils';
import { DEFAULT_FILTERS } from '../Metrics';

type ChartData = [string[], number[]] | [null, null];

const CSAT_PAGE_LIMIT = 10;

const useMetrics = () => {
  const { t } = useLokaliseTranslation('service_management');
  const showGeneralError = useGeneralError();
  const { moduleActivated } = useModuleConfiguration();

  const [filtersVersion, setFiltersVersion] = useState(0);
  const [appliedFilters, setAppliedFilters] =
    useState<MetricFiltersForm | null>(DEFAULT_FILTERS);
  const [selectedDates, setSelectedDates] = useState<DateRange | null>(
    deriveDateRangeFromFilters(DEFAULT_FILTERS),
  );
  const [appliedRatings, setAppliedRatings] = useState<string[]>([]);

  // Service Metrics
  const {
    data: tasksMetrics,
    isLoading: isTasksLoading,
    isError: isTasksError,
    refetch: refetchTaskData,
  } = useQuery(
    serviceManagementKeys.metrics.serviceItems(filtersVersion),
    () => getTaskMetrics(appliedFilters!),
    {
      onError: showGeneralError,
      select: data => data.data,
      enabled: moduleActivated,
    },
  );

  const {
    data: csatMetrics,
    isLoading: isCsatLoading,
    isError: isCsatError,
    refetch: refetchCsatData,
    isRefetching: isCsatRefetching,
  } = useQuery(
    serviceManagementKeys.metrics.csat(filtersVersion),
    () => getCsatMetrics(appliedFilters!),
    {
      onError: showGeneralError,
      select: res => res.data,
      enabled: moduleActivated,
    },
  );

  const {
    data: csatResponsesData,
    isLoading: isLoadingTableData,
    isError: isErrorTableData,
    refetch: refetchTableData,
    isRefetching: isRefetchingTableData,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery(
    serviceManagementKeys.metrics.csatResponses(filtersVersion, appliedRatings),
    ({ pageParam = 1 }) =>
      getCsatResponses(appliedFilters, appliedRatings, {
        page: pageParam,
        limit: CSAT_PAGE_LIMIT,
      }),
    {
      getNextPageParam,
      onError: showGeneralError,
      enabled: moduleActivated,
    },
  );

  const tasksChartData: ChartData = useMemo(() => {
    if (!tasksMetrics) {
      return [null, null];
    }
    const labels = Object.keys(tasksMetrics.tasksByStatus).map(status =>
      t(getStateName(status)),
    );

    const values = Object.values(tasksMetrics.tasksByStatus);
    return [labels, values];
  }, [tasksMetrics]);

  const csatChartData: ChartData = useMemo(() => {
    if (!csatMetrics) {
      return [null, null];
    }

    const labels = Object.keys(csatMetrics.csatResponseByRating).map(
      ratingValue => ratingValue,
    );
    const values = Object.values(csatMetrics.csatResponseByRating);
    return [labels, values];
  }, [csatMetrics]);

  const csatTableData: CsatRating[] = useMemo(() => {
    if (!csatResponsesData) {
      return [];
    }

    return csatResponsesData.pages.flatMap(page => {
      const items = page.data.items;
      return items.map(currentSurveyAnswer => {
        const currentSurveyAnswers = currentSurveyAnswer.csatQuestionAnswers;
        const comment =
          currentSurveyAnswers.find(
            s => s.csatQuestionType === SurveyQuestionType.COMMENT,
          )?.value || null;

        const surveyRating =
          currentSurveyAnswers.find(
            s => s.csatQuestionType === SurveyQuestionType.RATING,
          )?.value || null;

        return {
          id: currentSurveyAnswer.id,
          comment,
          rating: surveyRating,
        };
      });
    });
  }, [csatResponsesData]);

  const updateAppliedFilters = (newFilters: MetricFiltersForm | null) => {
    setAppliedFilters(newFilters);
    setFiltersVersion(prev => prev + 1);
    if (newFilters) {
      const computedDates = deriveDateRangeFromFilters(newFilters);
      setSelectedDates(computedDates);
    } else {
      setSelectedDates(null);
    }
  };

  return {
    tasksMetrics,
    tasksChartData,
    csatMetrics,
    csatTableData,
    csatChartData,
    isTasksLoading,
    isTasksError,
    refetchTaskData,
    isCsatLoading,
    isCsatError,
    refetchCsatData,
    isCsatRefetching,
    isLoadingTableData,
    isErrorTableData,
    updateAppliedFilters,
    appliedFilters,
    selectedDates,
    setSelectedDates,
    refetchTableData,
    isRefetchingTableData,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    setAppliedRatings,
    appliedRatings,
  };
};

export default useMetrics;
