import { useId, useMemo, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useMutation, useQuery } from 'react-query';
import { useParams } from 'react-router-dom';

import Stack from '@material-hu/mui/Stack';

import HuAlert from '@material-hu/components/design-system/Alert';
import HuPills from '@material-hu/components/design-system/Pills';
import useSnackbar from '@material-hu/components/design-system/Snackbar';
import {
  useDialogLayer,
  useDialogLayerItem,
} from '@material-hu/components/layers/Dialogs';

import { logEvent } from 'src/config/logging';
import { useAuth } from 'src/contexts/JWTContext';
import {
  invalidateAllCycleStats,
  invalidateLeaderUsers,
  invalidateUsersToShare,
  invalidateUserToShare,
  performanceKeys,
} from 'src/pages/dashboard/performance/queries';
import {
  getReviewCycle,
  getUserToShare,
  saveSummary,
  shareReview,
} from 'src/pages/dashboard/performance/services';
import {
  DeliveryStatus,
  ReviewCycleStatus,
  type ReviewedFormReviewItem,
} from 'src/pages/dashboard/performance/types';
import { EventName, SharedReviewOrigin } from 'src/types/amplitude';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getFullName } from 'src/utils/userUtils';

import PerformanceLoading from '../../components/PerformanceLoading';
import UserListRow from '../../components/UserList/UserListRow';
import UserListSection from '../../components/UserList/UserListSection';
import { PILL_TYPE } from '../../constants';
import { usePerformanceReview } from '../../PerformanceReviewContext';
import {
  getIsFinished,
  getIsReviewShared,
  groupReviewsByDirection,
  type ReviewDirectionGroup,
} from '../../utils';

import ReviewHeaderCard from './ReviewHeaderCard';
import Summary from './Summary/Summary';
import ReviewScoreCardByDirection from './score/ReviewScoreCardByDirection';

const ShareResultsDetail = () => {
  const { id } = useParams();
  const { t } = useLokaliseTranslation('performance');
  const { enqueueSnackbar } = useSnackbar();
  const { user: logged } = useAuth();
  const form = useForm();
  const { watch } = form;

  const cycleId = id || '';
  const { userToShareId, setViewingReviewId } = usePerformanceReview();
  const [isSummaryEditing, setIsSummaryEditing] = useState(false);

  const { data: cycle } = useQuery(
    performanceKeys.cycle(cycleId),
    () => getReviewCycle(cycleId),
    { select: response => response.data },
  );

  const {
    withSummary,
    status: cycleStatus,
    canBeShared,
    canBeSharedBeforeCycleFinish,
    reviewsVisibleAfterFinishedReviewCycle,
  } = cycle || {};

  const showAllReviews =
    cycleStatus === ReviewCycleStatus.FINISHED ||
    !reviewsVisibleAfterFinishedReviewCycle ||
    canBeSharedBeforeCycleFinish;

  const { data: userToShare, isLoading } = useQuery(
    performanceKeys.userToShare(cycleId, userToShareId),
    () => getUserToShare(Number(cycleId), userToShareId as number),
    {
      select: response => response.data,
      onSuccess: response => {
        form.reset({ summary: response.summary });
      },
      enabled: !!userToShareId && showAllReviews,
    },
  );

  const { reviewedFormReviews, user, shareStatus, score, scoreTag } =
    userToShare || {};

  const firstName = user?.firstName;
  const isFinished = getIsFinished(cycleStatus);
  const reviewShared = getIsReviewShared(
    shareStatus || DeliveryStatus.NOT_SHARED,
  );

  const showShareButton =
    canBeShared &&
    !reviewShared &&
    (canBeSharedBeforeCycleFinish || isFinished);

  const showInfo = shareStatus === DeliveryStatus.SHARE_DISABLED;

  const { mutate: shareReviewMutate, isLoading: isSharingReview } = useMutation(
    () => shareReview(cycleId, userToShareId as number, watch('summary')),
    {
      onSuccess: () => {
        logEvent(EventName.PERF_REV_REVIEW_SHARED, {
          cycleId,
          reviewId: null,
          origin: SharedReviewOrigin.ADMIN,
        });
        if (userToShareId) {
          invalidateUserToShare(cycleId, userToShareId);
        }
        invalidateUsersToShare(cycleId, Number(logged?.id), {
          order: 'ASC',
          orderBy: 'SHARE_STATUS',
          page: 1,
          limit: 200,
        });
        if (id) {
          invalidateAllCycleStats(id);
          invalidateLeaderUsers(id);
        }
        enqueueSnackbar({ title: t('form.share_success'), variant: 'success' });
      },
    },
  );

  const { mutate: saveSummaryMutate, isLoading: isSavingSummary } = useMutation(
    () => saveSummary(cycleId, userToShareId as number, watch('summary')),
    {
      onSuccess: () => {
        setIsSummaryEditing(false);
        if (userToShareId) {
          invalidateUserToShare(cycleId, userToShareId);
        }
        enqueueSnackbar({ title: t('summary.saved'), variant: 'success' });
      },
      onError: () => {
        enqueueSnackbar({ title: t('general:error_action'), variant: 'error' });
      },
    },
  );

  const shareReviewModalId = useId();
  const { closeDialog } = useDialogLayer();
  const closeShareReviewModal = () => closeDialog(shareReviewModalId);
  const { openDialog: showShareReviewModal } = useDialogLayerItem(
    shareReviewModalId,
    {
      title: t('form.share_modal.title', { name: firstName ?? '' }),
      textBody: t('form.share_modal.description', { name: firstName ?? '' }),
      primaryButtonProps: {
        children: t('form.share_modal.accept'),
        loading: isSharingReview,
        disabled: isSharingReview,
        onClick: () => {
          if (!userToShareId) return;
          closeShareReviewModal();
          shareReviewMutate();
        },
      },
      secondaryButtonProps: {
        children: t('general:CANCEL'),
        disabled: isSharingReview,
        onClick: closeShareReviewModal,
      },
      dialogProps: { fullWidth: true, maxWidth: 'xs' },
    },
  );

  const groups = useMemo<ReviewDirectionGroup<ReviewedFormReviewItem>[]>(() => {
    if (!reviewedFormReviews?.length) return [];
    return groupReviewsByDirection(reviewedFormReviews);
  }, [reviewedFormReviews]);

  const headerUser = user
    ? {
        ...user,
        profilePicture: user.profilePicture ?? null,
      }
    : undefined;

  if (isLoading) {
    return <PerformanceLoading />;
  }

  return (
    <FormProvider {...form}>
      <Stack sx={{ gap: 3, width: '100%' }}>
        <ReviewHeaderCard
          user={headerUser}
          footer={
            showShareButton
              ? {
                  action1: {
                    title: t('form.share_review.share_review_with', {
                      name: firstName,
                    }),
                    onClick: () => showShareReviewModal(),
                    variant: 'contained',
                    disabled: shareStatus !== DeliveryStatus.NOT_SHARED,
                    size: 'small',
                  },
                }
              : undefined
          }
          rightSlot={
            <ReviewScoreCardByDirection
              score={score}
              scoreTag={scoreTag}
            />
          }
        />

        {showInfo && (
          <HuAlert
            severity="info"
            title={t('form.review.still_in_progress_title')}
            description={t(
              withSummary
                ? 'form.review.still_in_progress_description_summary'
                : 'form.review.still_in_progress_description',
              { name: firstName },
            )}
          />
        )}

        <Summary
          summary={userToShare?.summary}
          withSummary={Boolean(withSummary)}
          shareStatus={shareStatus || DeliveryStatus.NOT_SHARED}
          userId={user?.userId}
          saveSummary={() => {
            if (userToShareId) saveSummaryMutate();
          }}
          isSavingSummary={isSavingSummary}
          isEditing={isSummaryEditing}
          onEdit={() => setIsSummaryEditing(true)}
        />

        {groups.map(group => (
          <UserListSection
            key={group.titleKey}
            title={group.titleKey ? t(group.titleKey) : undefined}
          >
            {group.reviews.map(review => {
              const reviewerName =
                getFullName(review.reviewer || {}) || t('general:ANONYMOUS');
              const isAnswered = review.answered;

              return (
                <UserListRow
                  key={review.id}
                  user={{
                    id: review.reviewer?.userId,
                    profilePicture: review.reviewer?.profilePicture ?? null,
                    firstName: review.reviewer?.firstName,
                    lastName: review.reviewer?.lastName,
                    fullName: reviewerName,
                  }}
                  primary={reviewerName}
                  onClick={
                    isAnswered ? () => setViewingReviewId(review.id) : undefined
                  }
                >
                  {isAnswered ? (
                    <ReviewScoreCardByDirection
                      score={review.score}
                      scoreTag={review.scoreTag}
                    />
                  ) : (
                    <HuPills
                      label={t('no_evaluated')}
                      size="small"
                      type={PILL_TYPE.WARNING}
                      hasIcon={false}
                      sx={{ flexShrink: 0, textTransform: 'none' }}
                    />
                  )}
                </UserListRow>
              );
            })}
          </UserListSection>
        ))}
      </Stack>
    </FormProvider>
  );
};

export default ShareResultsDetail;
