import { FC, useEffect } from 'react';
import { FormProvider } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
import { useNavigate, useSearchParams } from 'react-router-dom';

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

import useGeneralError from 'src/hooks/useGeneralError';
import usePosting from 'src/hooks/usePosting';
import useRequiredParams from 'src/hooks/useRequiredParams';
import { getGif } from 'src/services/attachments';
import { getDraftFeed, updatePostDraft } from 'src/services/posts';
import { FileTypes } from 'src/types/attachments';
import { DraftRequest, PostData } from 'src/types/posts';
import { checkAndShowError } from 'src/utils/errorHandlers';
import { getFormFileFromAttachment } from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  getPollEditWithVotesErrorKey,
  getPollDeadlineValidationErrorKey,
} from 'src/utils/poll';

import { attachmentKeys } from 'src/components/attachment/queries';

import { invalidateDraftDetail, postDraftKeys } from '../queries';
import { draftsForReviewRoutes } from '../routes';

import DraftStepperLayout from './DraftStepper/DraftStepperLayout';
import PostDraft from './DraftSteps/PostDraft';
import ScheduledPostAlert from './ScheduledPostAlert';

type PostDraftEditCardProps = {
  draftDetail: DraftRequest;
};

const PostDraftEditCard: FC<PostDraftEditCardProps> = props => {
  const { draftDetail } = props;

  const { t } = useLokaliseTranslation(['communication', 'drafts', 'general']);
  const { t: tError } = useTranslation();
  const { id: draftId } = useRequiredParams(['id']);
  const showGeneralError = useGeneralError();
  const { enqueueSnackbar } = useHuSnackbar();
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const gifAttachment = draftDetail?.post?.attachments?.find(
    attachment => attachment.type === FileTypes.GIF,
  );
  const gifId = gifAttachment?.externalReference?.id;

  const { data: gif } = useQuery(
    attachmentKeys.gif(gifId!),
    () => getGif(gifId!),
    { enabled: !!draftDetail && !!gifId },
  );

  const { form, handleSubmit, submit, ...rest } = usePosting({
    defaultBody: draftDetail?.post?.body,
    defaultBodyHtml: draftDetail?.post?.bodyHtml,
    deafultBodyAttributes: draftDetail?.post?.bodyAttributes,
    defaultLinkPreviews: draftDetail?.post?.linkPreviews,
    defaultImages: draftDetail?.post?.attachments
      .filter(attachment => attachment.type === FileTypes.IMAGE)
      .map(getFormFileFromAttachment),
    defaultVideos: draftDetail?.post?.attachments
      .filter(attachment => attachment.type === FileTypes.VIDEO)
      .map(getFormFileFromAttachment),
    defaultFiles: draftDetail?.post?.attachments
      .filter(attachment => attachment.type === FileTypes.FILE)
      .map(getFormFileFromAttachment),
    defaultAudios: draftDetail?.post?.attachments
      .filter(attachment => attachment.type === FileTypes.AUDIO)
      .map(getFormFileFromAttachment),
    defaultGif: gif?.data,
    defaultGroupTitle: draftDetail?.post?.group?.title,
    request: (newBody: PostData) => updatePostDraft(draftDetail?.id, newBody),
    onSuccess: () => {
      enqueueSnackbar({
        title: t('drafts:detail.draft_edited'),
        description: t(
          'communication:drafts_for_review.success_edit_draft_description',
        ),
        variant: 'success',
      });
      invalidateDraftDetail(draftId);
      navigate(draftsForReviewRoutes.detail(draftId));
    },
    onError: error => {
      checkAndShowError(error, showGeneralError, tError, [
        getPollEditWithVotesErrorKey,
        getPollDeadlineValidationErrorKey,
      ]);
    },
    isEdit: true,
    isDraft: true,
    defaultDateTimeSchedule: draftDetail.isScheduled
      ? draftDetail?.post?.publicationDatetime
      : undefined,
    defaultSendNotification: draftDetail?.post?.sendNotification,
    poll: draftDetail?.post?.poll || undefined,
  });

  const { data: feedData } = useQuery(
    postDraftKeys.feed(draftDetail?.draftPermissionId),
    () => getDraftFeed(draftDetail?.draftPermissionId),
    {
      select: res => res?.data,
      enabled: !!draftDetail?.draftPermissionId,
    },
  );

  useEffect(() => {
    // Populate the form and search params with the draft data
    const isGroupPost = !!draftDetail?.post?.group;
    form.setValue(
      'groupId',
      isGroupPost ? (draftDetail?.post?.group?.id ?? null) : null,
    );
    form.setValue(
      'groupTitle',
      isGroupPost ? (draftDetail?.post?.group?.title ?? '') : '',
    );
    form.setValue('toFeed', !isGroupPost);
    setSearchParams({
      ...Object.fromEntries(searchParams.entries()),
      groupId: isGroupPost
        ? (draftDetail?.post?.group?.id?.toString() ?? '')
        : '',
      canSendPostNotification: (isGroupPost
        ? !!draftDetail?.post?.group?.loggedUserIsAdmin
        : !!feedData?.canSendPostNotification
      ).toString(),
      canCreatePoll: isGroupPost
        ? 'true'
        : (!!feedData?.canCreatePoll).toString(),
    });
  }, [feedData]);

  return (
    <FormProvider {...form}>
      <DraftStepperLayout
        primaryButtonProps={{
          onClick: () => handleSubmit(submit)(),
          text: t('general:save'),
          isLoading: rest.isSubmitting,
          disabled: rest.disabledSubmitButton,
        }}
        tertiaryButtonProps={{
          text: t('general:back'),
          onClick: () => navigate(draftsForReviewRoutes.detail(draftId!)),
          disabled: rest.isSubmitting,
        }}
      >
        <ScheduledPostAlert draftDetail={draftDetail} />
        <PostDraft
          usePostingProps={rest}
          isEdit
          isScheduled={draftDetail?.isScheduled}
        />
      </DraftStepperLayout>
    </FormProvider>
  );
};

export default PostDraftEditCard;
