import React, {useEffect} from 'react';
import {View} from 'react-native';
import {useQueryClient} from '@tanstack/react-query';
import {Spinner} from '@components';
import {useGoBack} from '@hooks/useGoBack';
import {Navigation} from '@interfaces/navigation';
import {
  CourseStatus,
  LessonStatus,
  PathItem,
} from '@modules/learning/interfaces';
import {
  getModuleByLessonId,
  hasSurveyToComplete,
} from '@modules/learning/utils';
import {
  useGetCourse,
  useGetPathFinished,
  useGetNextCourse,
  usePathNavigation,
} from '@modules/learning/hooks';
import useGetCertificate from '@modules/learning/hooks/useGetCertificate';
import {useGetPathId} from '@modules/learning/hooks/useGetPathId';
import {DELAY_TIME_SURVEY, QUERY_KEYS} from '@modules/learning/constants';
import {useAppSelector} from '@redux/utils';
import {logAmplitudeEvent} from '@shared/utils';
import {useTheme} from '@shared/theme';
import {AMPLITUDE_EVENTS, Screens} from '@shared/constants';

import EndOfModule from './EndOfModule';
import EndOfCourse from './EndOfCourse';
import EndOfCourseWithPath from './EndOfCourseWithPath';
import {styles} from './styles';

function ModuleEnd({
  navigation,
  route: {
    params: {isLastLesson, courseId, moduleId, lessonId},
  },
}: Navigation<Screens.MODULE_END>) {
  const {goBack} = useGoBack();
  const {iconSizes} = useTheme();
  const instanceId = useAppSelector(({instance}) => instance.id);
  const userId = useAppSelector(({user}) => user.id);
  const {data, isFetching, onNextModule} = useGetCourse(courseId);
  const {exitToPaths} = usePathNavigation();
  const lessonModule =
    data && !!lessonId && getModuleByLessonId(data, lessonId);
  const isModuleFinished =
    !!lessonModule &&
    lessonModule?.tasks.every(task => task.status === LessonStatus.FINISHED_OK);

  const {getCertificate, isLoading: certificateLoading} = useGetCertificate({
    id: courseId,
    title: data?.title,
    type: 'course',
    data,
  });
  const learningPathId = useGetPathId();
  const isCourseFinished = data?.status === CourseStatus.FINISHED;
  const isCourseFromPath =
    data?.learningPathIds?.length && data?.learningPathIds?.length > 0;

  const queryClient = useQueryClient();

  const pathData = queryClient.getQueryData<PathItem>(
    QUERY_KEYS.path(learningPathId!),
  );

  useEffect(() => {
    queryClient.invalidateQueries({queryKey: QUERY_KEYS.learning});
    queryClient.invalidateQueries({queryKey: QUERY_KEYS.allPaths});
    queryClient.invalidateQueries({queryKey: QUERY_KEYS.allCourses});
    if (learningPathId) {
      queryClient.invalidateQueries({
        queryKey: QUERY_KEYS.path(learningPathId!),
      });
    }
  }, [queryClient, learningPathId]);

  const {nextPendingCourse, isFetching: isFetchingNextCourse} =
    useGetNextCourse(learningPathId);
  const {data: isPathFinished} = useGetPathFinished({
    pathId: learningPathId,
    enabled: !!learningPathId,
  });

  const isEndOfCourse = isLastLesson || isCourseFinished;
  const title =
    (isEndOfCourse ? data?.title : lessonModule && lessonModule?.title) || '';
  const hasToCompleteSurvey = hasSurveyToComplete(data);

  useEffect(() => {
    if (hasToCompleteSurvey && !isCourseFromPath) {
      const timeoutId = setTimeout(() => {
        navigation.navigate(Screens.SATISFACTION_SURVEY, {courseId});
      }, DELAY_TIME_SURVEY);

      return () => clearTimeout(timeoutId);
    }
  }, [courseId, hasToCompleteSurvey, isCourseFromPath, navigation]);
  useEffect(() => {
    if (isModuleFinished) {
      logAmplitudeEvent(AMPLITUDE_EVENTS.COURSE_MODULE_FINISHED, {
        userId,
        instanceId,
        courseId,
        moduleId,
      });
    }
  }, [courseId, instanceId, isModuleFinished, moduleId, userId]);

  useEffect(() => {
    if (isCourseFinished) {
      logAmplitudeEvent(AMPLITUDE_EVENTS.COURSE_FINISHED, {
        userId,
        instanceId,
        courseId,
        isFromPath: isCourseFromPath,
      });
    }
  }, [courseId, isCourseFinished, instanceId, userId, isCourseFromPath]);

  const onClose = () => {
    const state = navigation.getState();
    const coursesExists = state.routes.some(r => r.name === Screens.COURSES);

    if (coursesExists) {
      navigation.popTo(Screens.COURSES);
    } else {
      navigation.popTo(Screens.COURSE, {courseId});
      navigation.replace(Screens.COURSES);
    }
  };

  const onClosePath = () => {
    exitToPaths();
  };

  const handleContinue = () => {
    lessonId && onNextModule(lessonId);
  };

  const onPressNextCourse = () => {
    if (nextPendingCourse) {
      navigation.navigate(Screens.COURSE, {courseId: nextPendingCourse.id});
      logAmplitudeEvent(AMPLITUDE_EVENTS.LEARNING_COINTINUE_COURSE, {
        userId,
        instanceId,
        courseId: nextPendingCourse.id,
      });
    }
  };

  if (isFetching || isFetchingNextCourse) {
    return (
      <View style={styles.spinnerContainer}>
        <Spinner size={iconSizes.x8} />
      </View>
    );
  }

  return (
    <>
      {isEndOfCourse ? (
        isCourseFromPath ? (
          <EndOfCourseWithPath
            title={title}
            nextCourse={nextPendingCourse}
            onPressNextCourse={onPressNextCourse}
            isCourseFinished={isCourseFinished}
            isPathFinished={!!isPathFinished}
            onClose={onClosePath}
            canGetCertificate={!!(pathData?.issueCertificate && isPathFinished)}
          />
        ) : (
          <EndOfCourse
            title={title}
            isCourseFinished={isCourseFinished}
            onClose={onClose}
            canGetCertificate={!!(data?.passed && data?.issueCertificate)}
            getCertificate={getCertificate}
            certificateLoading={certificateLoading}
          />
        )
      ) : (
        <EndOfModule
          title={title}
          isModuleFinished={!!isModuleFinished}
          onClose={onClose}
          onContinue={handleContinue}
          onBack={goBack}
        />
      )}
    </>
  );
}

export default ModuleEnd;
