import { useMemo } from 'react';
import { useMutation, useQuery } from 'react-query';
import { useParams, useSearchParams } from 'react-router-dom';

import { differenceInSeconds } from 'date-fns';

import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { logEvent } from 'src/config/logging';
import { usePerformanceReview } from 'src/pages/dashboard/performance/PerformanceReviewContext';
import {
  checkReviewAsCompleted,
  invalidateExternalReview,
  performanceKeys,
} from 'src/pages/dashboard/performance/queries';
import {
  completeExternalReview,
  getExternalReview,
} from 'src/pages/dashboard/performance/services';
import { type ReviewBody } from 'src/pages/dashboard/performance/types';
import { createReviewAnswers } from 'src/pages/dashboard/performance/utils';
import { EventName } from 'src/types/amplitude';
import { useLokaliseTranslation } from 'src/utils/i18n';

type UseExternalReviewParams = {
  reviewId: number;
  onCompleted: () => void;
};

/**
 * Encapsulates the data layer of the external review flow:
 * URL identifier parsing, fetching the review, submitting answers,
 * and post-submit side-effects (Amplitude event, snackbar, cache invalidation, next-review navigation).
 */
const useExternalReview = ({
  reviewId,
  onCompleted,
}: UseExternalReviewParams) => {
  const { id } = useParams();
  const cycleId: string = id ?? '';
  const { t } = useLokaliseTranslation(['performance']);
  const { enqueueSnackbar } = useSnackbar();
  const { nextReview } = usePerformanceReview();

  const [searchParams] = useSearchParams();
  const rawExternalReviewerId = searchParams.get('id');
  const externalReviewerId = rawExternalReviewerId
    ? Number(rawExternalReviewerId)
    : null;

  const startTime = useMemo(() => new Date(), []);

  const { data: review, isLoading: reviewLoading } = useQuery({
    queryKey: performanceKeys.externalReview(
      cycleId,
      reviewId,
      externalReviewerId,
    ),
    queryFn: () => getExternalReview(cycleId, reviewId, externalReviewerId),
    cacheTime: 0,
    select: response => response.data,
  });

  const { mutate, isLoading: isSubmittingReview } = useMutation({
    mutationFn: (values: Record<string, unknown>) => {
      const fillingTime = differenceInSeconds(new Date(), startTime);
      const questionAnswers = createReviewAnswers(
        values,
        review?.form?.questions || [],
      ) as ReviewBody['questionAnswers'];

      return completeExternalReview(cycleId, reviewId, externalReviewerId, {
        fillingTime,
        questionAnswers,
      });
    },
    onSuccess: response => {
      onCompleted();
      document.getElementById('review-layout')?.scrollTo(0, 0);
      if (id && reviewId && externalReviewerId) {
        checkReviewAsCompleted(cycleId, reviewId);
        invalidateExternalReview(cycleId, reviewId, externalReviewerId);
      }
      logEvent(EventName.PERF_REV_REVIEW_COMPLETED, {
        cycleId,
        reviewId,
        direction: response.data.type,
      });
      nextReview();
      enqueueSnackbar({
        title: t('review_completed.success'),
        variant: 'success',
      });
    },
    onError: () => {
      enqueueSnackbar({
        title: t('general:error_general'),
        variant: 'error',
      });
    },
  });

  return {
    review,
    reviewLoading,
    submitReview: mutate,
    isSubmittingReview,
  };
};

export default useExternalReview;
