import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import {IconEdit, IconNotesOff} from '@tabler/icons-react-native';
import {IconButton} from '@components';
import DynamicForm, {FormStep, SubmitData} from '@components/DynamicForm';
import {useInsensitiveTranslation} from '@config/i18n/useInsensitiveTranslation';
import {Navigation} from '@interfaces/navigation';
import {
  useDraftForm,
  useGetPerformanceReview,
  useReviewSummary,
  useSendReview,
} from '@modules/performance/hooks';
import {
  EmptyReviewsList,
  GoalStepBody,
  ShareButton,
} from '@modules/performance/components';
import {
  Competency,
  PerformanceReviewCycleStatus,
  PerformanceReviewSharedStatus,
  PerformanceReviewStatus,
} from '@modules/performance/interfaces';
import {transformFormResult} from '@modules/performance/utils';
import {Goal} from '@modules/goals/interfaces';
import {PERFORMANCE_QUERY_KEYS} from '@modules/performance/constants';
import {PerformanceReviewFormSK} from '@modules/performance/skeletons/PerformanceReviewFormSK';
import {CompetencyStepBody} from '@modules/performance/components/CompetencyStepBody';
import {AMPLITUDE_EVENTS, Screens} from '@shared/constants';
import {logAmplitudeEvent} from '@shared/utils';
import {useTheme} from '@shared/theme';
import {commonStyles} from '@shared/styles';

import {RequestEditionModal} from './components/RequestEditionModal';
import {ReviewFormHeader} from './components/ReviewFormHeader';
import {FinishModal} from './components/FinishModal';

function PerformanceReviewForm({
  navigation,
  route: {
    params: {cycleId, reviewId, shareable, showOptions},
  },
}: Navigation<Screens.PERFORMANCE_REVIEW_FORM>) {
  const {t} = useInsensitiveTranslation();
  const {theme} = useTheme();
  const [showConfirmationModal, setShowConfirmationModal] = useState(false);
  const [showRequestEdit, setShowRequestEdit] = useState(false);
  const [submitData, setSubmitData] = useState<SubmitData>();
  const {draftForm, removeDraftForm, updateDraftForm} = useDraftForm(reviewId);
  const {
    review,
    reviewForm,
    withSummary,
    canEdit,
    isReviewer,
    isSelfReview,
    isOmitted,
    isFinished,
    isLoading: isGetFormLoading,
    canBeShared,
    cycleStatus,
    canEditSummary,
    isAnswered,
    isBossReview,
    cycleIsShareable,
    isReviewsVisibleAfterFinishedReviewCycle,
    canBeSharedBeforeCycleFinish,
  } = useGetPerformanceReview({cycleId, reviewId, draftForm});

  const {sendReview, isLoading: isSendReviewLoading} = useSendReview({
    cycleId: cycleId,
    reviewId: reviewId,
    isEdition: review?.status === PerformanceReviewStatus.EDIT_PENDING,
    onSuccess: () => {
      logAmplitudeEvent(AMPLITUDE_EVENTS.PERF_REV_REVIEW_COMPLETED, {
        reviewId: reviewId,
        cycleId: cycleId,
        direction: review?.type,
      });

      navigation.replace(Screens.PERFORMANCE_REVIEW_FORM_COMPLETED);
    },
  });

  const showEditPill =
    review?.status === PerformanceReviewStatus.EDIT_REQUESTED;

  const onFormSubmit = useCallback((values: SubmitData) => {
    setSubmitData(values);
    setShowConfirmationModal(true);
  }, []);

  const onFinishPress = useCallback(() => {
    setShowConfirmationModal(false);
    sendReview({
      questionAnswers: transformFormResult(submitData!.formValues),
      fillingTime: submitData!.fillingTime,
    });
    removeDraftForm();
  }, [sendReview, submitData, removeDraftForm]);

  const onCloseFinishModal = () => setShowConfirmationModal(false);

  const onRequestEdit = () => setShowRequestEdit(true);

  const onRequestEditClose = () => setShowRequestEdit(false);

  const isShared = useMemo(
    () =>
      review?.shareStatus &&
      [
        PerformanceReviewSharedStatus.SHARED_UNCONFIRMED,
        PerformanceReviewSharedStatus.SHARED_CONFIRMED,
      ].includes(review?.shareStatus),
    [review?.shareStatus],
  );

  useEffect(() => {
    if (review && (isReviewer || isFinished)) {
      const isCycleActive =
        cycleStatus !== PerformanceReviewCycleStatus.FINISHED;
      const headerRight = () =>
        isFinished && showOptions && isCycleActive && !isShared ? (
          <IconButton
            Icon={IconEdit}
            onPress={onRequestEdit}
            variant="tertiary"
          />
        ) : null;
      navigation.setOptions({
        title: t(`performance.types.${review?.type}`),
        headerRight,
      });
    }
  }, [
    review,
    navigation,
    isReviewer,
    isFinished,
    showOptions,
    t,
    cycleStatus,
    isShared,
  ]);

  const onGoalPress = useCallback(
    (goalId: number) =>
      navigation.navigate(Screens.GOAL_DETAIL, {
        id: goalId,
        invalidateQueryKeyOnUpdate: PERFORMANCE_QUERY_KEYS.formDetail(
          cycleId,
          reviewId!,
        ),
      }),
    [cycleId, navigation, reviewId],
  );

  const {summaryText, setSummaryText} = useReviewSummary({
    cycleId,
    userId: review?.reviewed.userId,
    enabled: !isSelfReview && isAnswered && withSummary && !isBossReview,
  });

  const withSummaryComponent = useMemo(
    () =>
      (!!summaryText || !!withSummary) &&
      !isSelfReview &&
      isAnswered &&
      !isBossReview,
    [summaryText, withSummary, isSelfReview, isAnswered, isBossReview],
  );

  const FormHeader = useMemo(
    () => (
      <ReviewFormHeader
        isOmitted={isOmitted}
        showEditPill={showEditPill}
        score={review?.score}
        reviewed={review?.reviewed}
        isAnswered={isAnswered}
        withSummary={withSummaryComponent}
        summaryText={summaryText}
        canEditSummary={canEditSummary}
        setSummaryText={setSummaryText}
        cycleId={cycleId}
        scoreTag={review?.scoreTag}
      />
    ),
    [
      isOmitted,
      showEditPill,
      review?.score,
      review?.reviewed,
      isAnswered,
      withSummaryComponent,
      summaryText,
      canEditSummary,
      setSummaryText,
      cycleId,
      review?.scoreTag,
    ],
  );

  // Custom step body render when the review has goal valuation
  const StepBodyComponent = useCallback(
    (stepData: FormStep) =>
      stepData.metadata ? (
        (stepData.metadata as {type: 'goal' | 'competency'}).type === 'goal' ? (
          <GoalStepBody
            goal={stepData.metadata as Goal}
            onGoalPress={onGoalPress}
            canViewGoalsOfReviewed={review?.loggedUserCanViewGoalsOfReviewed}
          />
        ) : (
          <CompetencyStepBody competency={stepData.metadata as Competency} />
        )
      ) : null,
    [onGoalPress, review?.loggedUserCanViewGoalsOfReviewed],
  );

  if (isGetFormLoading) {
    return <PerformanceReviewFormSK />;
  }

  return (
    <>
      <View
        style={[
          commonStyles.flex,
          {backgroundColor: theme.background.layout.default},
        ]}>
        {review && reviewForm?.length ? (
          <>
            <DynamicForm
              data={reviewForm}
              onSubmit={onFormSubmit}
              withSteps={canEdit}
              disabled={!canEdit}
              onFormChange={updateDraftForm}
              FormHeader={FormHeader}
              StepBodyComponent={StepBodyComponent}
              title={t(`performance.types.review_titles.${review?.type}`)}
              buttonIsLoading={isSendReviewLoading}
              reviewedUser={
                !isSelfReview
                  ? {
                      firstName: review?.reviewed.firstName,
                      lastName: review?.reviewed.lastName,
                      profilePicture: review?.reviewed.profilePicture,
                    }
                  : undefined
              }
            />
            {canBeShared && shareable && review.reviewed && (
              <ShareButton
                cycleId={cycleId}
                reviewId={reviewId}
                summary={summaryText}
                user={review.reviewed}
              />
            )}
          </>
        ) : (
          <EmptyReviewsList
            Icon={IconNotesOff}
            title={t('performance.error_review.title')}
            description={t('performance.error_review.description')}
          />
        )}
      </View>
      <FinishModal
        isVisible={showConfirmationModal}
        onFinishPress={onFinishPress}
        onCloseFinishModal={onCloseFinishModal}
        isSelfReview={isSelfReview}
        isReviewsVisibleAfterFinishedReviewCycle={
          isReviewsVisibleAfterFinishedReviewCycle
        }
        cycleIsShareable={cycleIsShareable}
        canBeSharedBeforeCycleFinish={canBeSharedBeforeCycleFinish}
      />
      {showRequestEdit && (
        <RequestEditionModal
          onClose={onRequestEditClose}
          reviewId={reviewId}
          cycleId={cycleId}
        />
      )}
    </>
  );
}

export default PerformanceReviewForm;
