import { type FC, Suspense } from 'react';
import { useFormContext } from 'react-hook-form';
import { useMutation } from 'react-query';
import { useParams } from 'react-router-dom';

import ImageIcon from '@material-hu/icons/material/Image';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAvatarGroup from '@material-hu/components/design-system/AvatarGroup';
import HuPills from '@material-hu/components/design-system/Pills';
import HuSpinner from '@material-hu/components/design-system/ProgressIndicators/Spinner';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import useGeneralError from 'src/hooks/useGeneralError';
import { type PostForm, type UsePostingReturn } from 'src/hooks/usePosting';
import PreviewLinkCard from 'src/pages/dashboard/feed/components/PreviewLinkCard';
import {
  PollAdd,
  PollReadOnly,
  usePollDrawer,
} from 'src/pages/dashboard/feed/components/poll';
import { updatePostDraftSchedule } from 'src/services/posts';
import { insertIf } from 'src/utils/arrays';
import { bytesFrom } from 'src/utils/bytes';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { lazyRetry } from 'src/utils/lazyRetry';
import { getFullName, getInitials } from 'src/utils/userUtils';

import {
  AttachmentsAdd,
  AttachmentsList,
  AttachmentsSize,
} from 'src/components/attachment';
import ErrorDialog from 'src/components/dialogs/ErrorDialog';

import { invalidateDraftDetail } from '../queries';

import SchedulePostDraft from './SchedulePostDraft';

const RichTextEditor = lazyRetry(() => import('src/components/RichTextEditor'));

type PostDraftAddFormProps = {
  displayCancelButton?: boolean;
  noNotification?: boolean;
  secondaryFullName?: string;
  secondaryProfilePicture?: string;
  secondaryMiddleText?: string;
  segmentationGroupName?: string;
  usePostingProps: Omit<UsePostingReturn, 'form' | 'handleSubmit' | 'submit'>;
  isEdit?: boolean;
  isScheduled?: boolean;
  canSendPostNotification?: boolean;
  canCreatePoll?: boolean;
};

const PostDraftAddForm: FC<PostDraftAddFormProps> = props => {
  const {
    secondaryFullName,
    secondaryProfilePicture,
    secondaryMiddleText = '▸',
    segmentationGroupName,
    usePostingProps,
    isEdit,
    isScheduled = false,
    canSendPostNotification = false,
    canCreatePoll,
  } = props;

  const { watch } = useFormContext<PostForm>();
  const { id: draftId } = useParams();
  const { t } = useLokaliseTranslation(['communication']);
  const showGeneralError = useGeneralError();
  const { enqueueSnackbar } = useHuSnackbar();

  const {
    instance,
    user,
    openError,
    closeErrorDialog,
    imagesAttach,
    filesAttach,
    videosAttach,
    isSubmitting,
    showPreviewLink,
    urls,
    metadata,
    isLoadingPreviewLink,
    handleRemovePreviewLink,
    hasAttachments,
    gif,
    handleDelete,
    handleRemoveGif,
    withPoll,
    setWithPoll,
    handlePollUpdate,
    pollOptionsForEdit,
    pollVotersVisible,
    handlePollVotersVisibilityChange,
    handleAddFiles,
    handleAddGif,
    handleAddMultimedia,
    attachmentsDisabled,
    images,
    videos,
    files,
    handleChangePositionMultimedia,
    handlePaste,
    handleSchedulePost,
    pollState,
    canRemovePoll,
    pollDeadlineEnabled,
    pollEndsAt,
    handlePollDeadlineChange,
    shouldClearPollWhenCancelling,
  } = usePostingProps;

  const { dateTimeSchedule, bodyHtml, sendNotification } = watch();

  const { mutate, isLoading: isScheduling } = useMutation(
    (data: {
      publicationDatetime: string | Date;
      sendNotification?: boolean;
    }) => {
      if (!draftId) {
        throw new Error('Draft ID is required for scheduling');
      }
      return updatePostDraftSchedule(Number(draftId), data);
    },
    {
      onSuccess: () => {
        if (!draftId) return;
        enqueueSnackbar({
          title: t('drafts_for_review.success_edit_schedule_draft'),
          description: t(
            'drafts_for_review.success_edit_schedule_draft_description',
          ),
          variant: 'success',
        });
        invalidateDraftDetail(draftId);
      },
      onError: error => {
        showGeneralError(
          error,
          t('drafts_for_review.error_edit_schedule_draft'),
        );
      },
    },
  );

  const handleDraftSchedulePost = (
    date: string,
    _sendNotification: boolean,
  ) => {
    if (isEdit)
      mutate({
        publicationDatetime: date,
        sendNotification: _sendNotification,
      });
    handleSchedulePost(new Date(date), _sendNotification, true);
  };

  const { drawer: pollCreateDrawer, showDrawer: showPollDrawer } =
    usePollDrawer({
      withPoll,
      canAddPoll: canCreatePoll || false,
      isSubmitting: isSubmitting,
      pollState,
      pollOptionsForEdit,
      pollVotersVisible,
      isEdit,
      onPollUpdate: handlePollUpdate,
      onPollVotersVisibilityChange: handlePollVotersVisibilityChange,
      pollDeadlineEnabled,
      pollEndsAt,
      onPollDeadlineChange: handlePollDeadlineChange,
      setWithPoll,
      shouldClearPollWhenCancelling,
    });

  return (
    <>
      <ErrorDialog
        open={openError}
        onAccept={closeErrorDialog}
        message={t('post:error_max_attachments_size')}
      />
      <>
        <Stack
          sx={{
            flexDirection: 'row',
            justifyContent: 'space-between',
            alignItems: 'center',
            py: 2,
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 1,
            }}
          >
            <HuAvatarGroup
              avatars={[
                {
                  src: user?.profilePicture || '',
                  text: getInitials(getFullName(user)),
                },
                ...insertIf(!!secondaryFullName, {
                  src: secondaryProfilePicture || '',
                  text: getInitials(secondaryFullName!),
                }),
              ]}
            />
            <Stack>
              <Stack
                sx={{
                  flexDirection: 'row',
                  gap: 0.5,
                }}
              >
                <Typography
                  variant="globalS"
                  fontWeight="fontWeightSemiBold"
                >
                  {getFullName(user)}
                  {secondaryFullName && (
                    <>
                      <Typography variant="globalS">
                        &nbsp;{`${secondaryMiddleText}`}&nbsp;
                      </Typography>
                      {secondaryFullName}
                    </>
                  )}
                </Typography>
              </Stack>
              {segmentationGroupName && (
                <HuPills
                  label={segmentationGroupName}
                  size="small"
                  type="info"
                  hasIcon={false}
                  sx={{ width: 'fit-content' }}
                />
              )}
            </Stack>
          </Stack>
          <AttachmentsSize
            sx={{ ml: 1 }}
            images={imagesAttach}
            files={filesAttach}
            videos={videosAttach}
            maxBytes={bytesFrom(instance?.maxPostSizeInMB ?? 0, 'MB')}
            addPost
          />
        </Stack>
        <Suspense fallback={<HuSpinner />}>
          <RichTextEditor
            name="bodyHtml"
            content={bodyHtml}
            isEdit
            handlePaste={handlePaste}
            disabled={isSubmitting}
          />
        </Suspense>
        {showPreviewLink && (
          <PreviewLinkCard
            linkPreviews={{ [urls[0]]: metadata?.data }}
            isLoading={isLoadingPreviewLink}
            onRemove={handleRemovePreviewLink}
          />
        )}
        {hasAttachments && (
          <AttachmentsList
            sx={{ my: 0.5 }}
            gif={gif}
            images={imagesAttach}
            files={filesAttach}
            videos={videosAttach}
            onDelete={handleDelete}
            onRemoveGif={handleRemoveGif}
            disabled={isSubmitting}
            isPost
            handleChangePositionMultimedia={handleChangePositionMultimedia}
          />
        )}

        {/* Show read-only poll when poll options exist */}
        {withPoll &&
          pollOptionsForEdit.length > 0 &&
          pollOptionsForEdit.some(option => option.trim()) && (
            <PollReadOnly
              options={pollOptionsForEdit.filter(option => option.trim())}
              onEdit={() => showPollDrawer({})}
              onRemove={
                canRemovePoll
                  ? () => {
                      handlePollUpdate([]);
                      setWithPoll(false);
                    }
                  : undefined
              }
            />
          )}

        <Stack
          sx={{
            flexDirection: 'row',
            justifyContent: 'space-between',
            alignItems: 'center',
            width: '100%',
            pt: { xs: 1, sm: 1.5 },
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              justifyContent: 'start',
              alignItems: 'center',
              flexWrap: 'wrap',
              color: theme => theme.palette.new.text.neutral.default,
            }}
          >
            <AttachmentsAdd
              onAddMultipleFiles={handleAddFiles}
              onAddGif={handleAddGif}
              onAddMultimedia={handleAddMultimedia}
              gifDisabled={hasAttachments || withPoll}
              disabled={attachmentsDisabled}
              multimediaSize={images.length + videos.length}
              filesSize={files.length}
              iconCustomPhoto={<ImageIcon />}
              checkMax={false}
              direction="bottom"
            />
            {canCreatePoll && (
              <PollAdd
                onAdd={() => setWithPoll(true)}
                disabled={withPoll || !!gif || isSubmitting}
                sx={{ color: 'primary.main' }}
              />
            )}
          </Stack>
          <Stack
            sx={{
              flexDirection: 'row',
              justifyContent: 'flex-end',
            }}
          >
            <Stack
              sx={{
                gap: 1,
                flexDirection: 'row',
                alignItems: 'center',
              }}
            >
              <SchedulePostDraft
                onSchedulePost={handleDraftSchedulePost}
                disabled={isEdit ? false : usePostingProps.disabledSubmitButton}
                isReschedule={isEdit ? isScheduled : !!dateTimeSchedule}
                isLoading={isScheduling}
                initialValues={
                  dateTimeSchedule
                    ? {
                        sendPush: sendNotification,
                        date: new Date(dateTimeSchedule).toISOString(),
                        hours: new Date(dateTimeSchedule).getHours(),
                        minutes: new Date(dateTimeSchedule).getMinutes(),
                      }
                    : undefined
                }
                canSendPostNotification={canSendPostNotification}
              />
            </Stack>
          </Stack>
        </Stack>
      </>
      {pollCreateDrawer}
    </>
  );
};

export default PostDraftAddForm;
