import { type FC } from 'react';

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

import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import Pills from '@material-hu/components/design-system/Pills';

import { usePostAttachments } from 'src/hooks/usePostAttachments';
import { PostCardApprovalControls } from 'src/pages/dashboard/groups/components/PostCardApprovalControls';
import { type FeedPendingPost } from 'src/types/feed';
import { type GroupPendingPost } from 'src/types/groups';
import { type PostRequestActionType } from 'src/types/posts';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { PostAction } from 'src/components/post/PostAction';
import PostBody from 'src/components/post/PostBody';
import { PostCardFeatures } from 'src/components/post/PostCardFeatures';
import PostCardHeader from 'src/components/post/PostCardHeader';

const MAX_CHARACTERS_LIMIT = 250;
const MAX_NEW_LINES_LIMIT = 4;

type PendingPost = GroupPendingPost | FeedPendingPost;
type PendingEditionPost = Extract<
  PendingPost,
  { actionType: PostRequestActionType.EDITION }
>;
type PendingPostEntity =
  | GroupPendingPost['groupPost']
  | FeedPendingPost['post'];
type PostEditionContent = {
  body?: string;
  bodyHtml?: string;
};

const getEditionBeforeContent = (
  pendingPost: PendingEditionPost,
): PostEditionContent => {
  const post = 'post' in pendingPost ? pendingPost.post : pendingPost.groupPost;

  return {
    bodyHtml: post.bodyHtml,
    body: post.body,
  };
};

const getEditionAfterContent = (
  pendingPost: PendingEditionPost,
): PostEditionContent => {
  return {
    bodyHtml: pendingPost.postContent.bodyHtml ?? undefined,
    body: pendingPost.postContent.body ?? undefined,
  };
};

const getAfterAttachments = (
  pendingPost: PendingEditionPost,
  post: PendingPostEntity,
) => {
  const proposedAttachments = pendingPost.postContent.attachments;
  return proposedAttachments != null ? proposedAttachments : post.attachments;
};

const getAfterPoll = (
  pendingPost: PendingEditionPost,
  post: PendingPostEntity,
) => pendingPost.postContent.poll ?? post.poll;

type Props = {
  pendingPost: PendingEditionPost;
  post: PendingPostEntity;
  onApprove: () => void;
  onReject: () => void;
};

export const EditionComparisonCard: FC<Props> = ({
  pendingPost,
  post,
  onApprove,
  onReject,
}) => {
  const { t } = useLokaliseTranslation();
  const isFeedPost = 'post' in pendingPost;
  const feedPost = isFeedPost ? (post as FeedPendingPost['post']) : undefined;
  const groupPost = !isFeedPost
    ? (post as GroupPendingPost['groupPost'])
    : undefined;
  const beforeContent = getEditionBeforeContent(pendingPost);
  const afterContent = getEditionAfterContent(pendingPost);
  const beforeAttachments = post.attachments;
  const afterAttachments = getAfterAttachments(pendingPost, post);
  const beforeFeatures = usePostAttachments(beforeAttachments);
  const afterFeatures = usePostAttachments(afterAttachments);
  const beforePoll = post.poll;
  const afterPoll = getAfterPoll(pendingPost, post);
  const beforeLinkPreviews = post.linkPreviews;
  const afterLinkPreviews =
    pendingPost.postContent.linkPreviews ?? post.linkPreviews;
  const hasBeforeExtras =
    Boolean(beforePoll) ||
    beforeAttachments.length > 0 ||
    (beforeLinkPreviews && Object.keys(beforeLinkPreviews).length > 0);
  const hasAfterExtras =
    Boolean(afterPoll) ||
    afterAttachments.length > 0 ||
    (afterLinkPreviews && Object.keys(afterLinkPreviews).length > 0);
  const pendingPostContainerId = `pending-post-request-${pendingPost.id}`;
  const isPendingApproval = true;
  const postAction = feedPost ? (
    <PostAction
      variant="feed"
      id={feedPost.id}
      user={feedPost.user}
      isKeyUpdate={feedPost.isKeyUpdate}
      isPendingApproval={isPendingApproval}
      isSegmented={feedPost.hasBeenSegmented}
      commentsEnabled={feedPost.commentsEnabled}
      poll={feedPost.poll}
      actionLinks={feedPost._links}
      isGroupPost={{
        value: !!feedPost.group,
        groupId: feedPost.group ? Number(feedPost.group.id) : 0,
      }}
    />
  ) : groupPost ? (
    <PostAction
      variant="group"
      id={groupPost.id}
      user={groupPost.user}
      groupId={groupPost.groupId}
      isKeyUpdate={groupPost.isKeyUpdate}
      isPendingApproval={isPendingApproval}
      isSegmented={groupPost.hasBeenSegmented}
      commentsEnabled={groupPost.commentsEnabled}
      poll={groupPost.poll}
      actionLinks={groupPost._links}
    />
  ) : null;
  const headerAction = (
    <Stack
      sx={{
        flexDirection: 'row',
        alignItems: 'center',
        gap: 1,
      }}
    >
      <Pills
        label={t('post:edited')}
        type="info"
        size="small"
        hasIcon={false}
        sx={{ width: 'fit-content', alignSelf: 'center' }}
      />
      {postAction}
    </Stack>
  );

  return (
    <HuCardContainer
      id={pendingPostContainerId}
      fullWidth
      padding={0}
    >
      <PostCardHeader
        user={post.user}
        publicationDatetime={post.publicationDatetime}
        updatedAt={post.updatedAt}
        createdAt={post.createdAt}
        approvalStatus={post.approvalStatus}
        isKeyUpdate={post.isKeyUpdate}
        isExternal={post.isExternal}
        openProfileInNewTab
        stream={post.stream ?? undefined}
        isGroupPost={!!feedPost?.group}
        action={headerAction}
      />
      <Stack sx={{ pb: 2 }}>
        <Stack sx={{ px: 2, gap: 2 }}>
          <Stack
            sx={{
              borderRadius: theme => theme.shape.borderRadiusL,
              p: 2,
              gap: 1,
              backgroundColor: theme =>
                theme.palette.new.background.layout.default,
            }}
          >
            <Pills
              label={t('general:before', { defaultValue: 'Antes' })}
              type="neutral"
              size="small"
              hasIcon={false}
              sx={{ width: 'fit-content', alignSelf: 'flex-start' }}
            />
            <PostBody
              bodyHtml={beforeContent.bodyHtml}
              body={beforeContent.body}
              maxCharacters={MAX_CHARACTERS_LIMIT}
              maxNewLines={MAX_NEW_LINES_LIMIT}
            />
            {hasBeforeExtras && (
              <Box id={`${pendingPostContainerId}-before`}>
                <PostCardFeatures
                  id={post.id}
                  poll={beforePoll}
                  gif={beforeFeatures.gif}
                  mediaList={beforeFeatures.mediaList}
                  fileList={beforeFeatures.fileList}
                  audioList={beforeFeatures.audioList}
                  linkPreviews={beforeLinkPreviews}
                  approvalStatus={pendingPost.approvalStatus}
                  userCanVote={false}
                  parentElementId={`${pendingPostContainerId}-before`}
                />
              </Box>
            )}
          </Stack>
          <Divider />
          <Stack sx={{ gap: 1, px: 2 }}>
            <Pills
              label={t('general:after', { defaultValue: 'Despues' })}
              type="success"
              size="small"
              hasIcon={false}
              sx={{ width: 'fit-content', alignSelf: 'flex-start' }}
            />
            <PostBody
              bodyHtml={afterContent.bodyHtml}
              body={afterContent.body}
              maxCharacters={MAX_CHARACTERS_LIMIT}
              maxNewLines={MAX_NEW_LINES_LIMIT}
            />
            {hasAfterExtras && (
              <Box id={`${pendingPostContainerId}-after`}>
                <PostCardFeatures
                  id={post.id}
                  poll={afterPoll}
                  gif={afterFeatures.gif}
                  mediaList={afterFeatures.mediaList}
                  fileList={afterFeatures.fileList}
                  audioList={afterFeatures.audioList}
                  linkPreviews={afterLinkPreviews}
                  approvalStatus={pendingPost.approvalStatus}
                  userCanVote={false}
                  parentElementId={`${pendingPostContainerId}-after`}
                />
              </Box>
            )}
          </Stack>
        </Stack>
        <PostCardApprovalControls
          postApprovalControls={{
            handleApprove: onApprove,
            handleReject: onReject,
          }}
        />
      </Stack>
    </HuCardContainer>
  );
};
