import { type FC, useMemo } from 'react';
import { useQueryClient } from 'react-query';

import { type AxiosResponse } from 'axios';
import Box from '@material-hu/mui/Box';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

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

import useGeneralError from 'src/hooks/useGeneralError';
import PostAddForm from 'src/pages/dashboard/feed/components/PostAddForm';
import { feedKeys, pushFeedListData } from 'src/pages/dashboard/feed/queries';
import {
  groupsKeys,
  invalidateGroupPostList,
} from 'src/pages/dashboard/groups/queries';
import { createGroupPost } from 'src/services/groups';
import { createPost } from 'src/services/posts';
import { type GroupPost } from 'src/types/groups';
import { type Post, type PostData } from 'src/types/posts';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { withShareMetadata } from 'src/utils/sharedPost';

import { SharedPostEmbedded } from 'src/components/post/SharedPost';

import { SHARE_FORM_ID, type ShareDestination } from './types';

type ShareEditorStepProps = {
  originalPost: Post | GroupPost;
  destination: ShareDestination;
  onSuccess: () => void;
  onSubmittingChange?: (isSubmitting: boolean) => void;
};

const isFeed = (
  destination: ShareDestination,
): destination is { type: 'feed' } => destination.type === 'feed';

export const ShareEditorStep: FC<ShareEditorStepProps> = ({
  originalPost,
  destination,
  onSuccess,
  onSubmittingChange,
}) => {
  const { t } = useTranslation(['post']);
  const queryClient = useQueryClient();
  const { enqueueSnackbar } = useHuSnackbar();
  const showGeneralError = useGeneralError();

  const metadataPayload = useMemo(
    () => withShareMetadata.fromSourcePost(originalPost),
    [originalPost],
  );

  const destinationLabel = isFeed(destination)
    ? undefined
    : destination.groupTitle;

  const request = useMemo((): ((
    body: PostData,
  ) => Promise<AxiosResponse<Post | GroupPost>>) => {
    if (isFeed(destination)) {
      return body => createPost(body);
    }
    const groupId = destination.groupId;
    return body => createGroupPost(groupId, body);
  }, [destination]);

  const handleSuccess = (post: Post | GroupPost) => {
    if (isFeed(destination)) {
      if (!('groupId' in post)) pushFeedListData(post);
      queryClient.invalidateQueries(feedKeys.list());
    } else {
      invalidateGroupPostList(destination.groupId);
      queryClient.invalidateQueries(
        groupsKeys.postList(String(destination.groupId)),
      );
    }
    enqueueSnackbar({
      title: t('post:share_success_snackbar'),
      variant: 'success',
    });
    onSuccess();
  };

  const handleError = (error: unknown) => {
    showGeneralError(error, t('post:share_error_snackbar'));
  };

  return (
    <Box>
      <Stack sx={{ mb: 2 }}>
        <Typography
          variant="globalM"
          fontWeight="fontWeightSemiBold"
        >
          {t('post:share_editor_title')}
        </Typography>
      </Stack>
      <CardContainer
        fullWidth
        noHover
      >
        <PostAddForm
          request={request}
          metadataPayload={metadataPayload}
          onSuccess={handleSuccess}
          onError={handleError}
          embeddedSlot={<SharedPostEmbedded post={originalPost} />}
          hideSegmentate={!isFeed(destination)}
          hideSchedule
          hideLiveStream
          isGroups={!isFeed(destination)}
          formId={SHARE_FORM_ID}
          hideSubmitRow
          onSubmittingChange={onSubmittingChange}
          destinationLabel={destinationLabel}
        />
      </CardContainer>
    </Box>
  );
};

export default ShareEditorStep;
