import { type FC, useEffect, useMemo } from 'react';
import { Helmet } from 'react-helmet-async';
import { useQuery } from 'react-query';
import { useParams } from 'react-router-dom';

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

import { EVENTS_SOCKETS } from 'src/constants/sockets';
import { useAuth } from 'src/contexts/JWTContext';
import { useSocket } from 'src/contexts/SocketContext';
import useCustomServerTranslation from 'src/hooks/useCustomServerTranslation';
import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { getArticleById } from 'src/services/news';
import { CopyTypePath } from 'src/types/deeplinks';
import { EventName } from 'src/types/amplitude';
import { type ArticleCommentReactionSocket } from 'src/types/news';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { addReaction, removeReaction } from 'src/utils/reactions';

import Article from './components/ArticleDetail';
import ArticleDetailSkeleton from './components/ArticleDetailSkeleton';
import { newsKeys, updateReactionCommentDataCommentList } from './queries';
import { newsRoutes } from './routes';

export type ArticleDetailProps = {
  eventNameAmplitude?: EventName;
};

const ArticleDetail: FC<ArticleDetailProps> = props => {
  const { eventNameAmplitude } = props;

  const { id } = useParams();
  const showGeneralError = useGeneralError();
  const { t } = useTranslation(['news', 'general']);
  const title = useCustomServerTranslation({
    module: 'ARTICLES',
    defaultTranslationKey: 'news:articles',
  });
  const socket = useSocket();
  const { user } = useAuth();
  const HuGoThemeProvider = useHuGoTheme();

  const { data, isLoading, isSuccess } = useQuery(
    newsKeys.detail(id!),
    () => getArticleById(id!),
    {
      onError: err => showGeneralError(err, t('news:error_loading_article')),
    },
  );

  useEffect(() => {
    const addArticleCommentReaction = (
      reaction: ArticleCommentReactionSocket,
    ) => {
      const { emoji, userId, articleId, commentId, unified } = reaction;

      updateReactionCommentDataCommentList(articleId, commentId, reactions =>
        addReaction(reactions, emoji, unified, userId === user?.id),
      );
    };

    const removeArticleCommentReaction = (
      reaction: ArticleCommentReactionSocket,
    ) => {
      const { emoji, userId, articleId, commentId } = reaction;

      updateReactionCommentDataCommentList(articleId, commentId, reactions =>
        removeReaction(reactions, emoji, userId === user?.id),
      );
    };

    socket.listenEvent(
      EVENTS_SOCKETS.NEW_ARTICLE_COMMENT_REACTION,
      addArticleCommentReaction,
    );

    socket.listenEvent(
      EVENTS_SOCKETS.REMOVE_ARTICLE_COMMENT_REACTION,
      removeArticleCommentReaction,
    );

    return () => {
      socket.closeEvent(
        EVENTS_SOCKETS.NEW_ARTICLE_COMMENT_REACTION,
        addArticleCommentReaction,
      );

      socket.closeEvent(
        EVENTS_SOCKETS.REMOVE_ARTICLE_COMMENT_REACTION,
        removeArticleCommentReaction,
      );
    };
  }, [socket, user?.id]);

  const article = data?.data;

  const eventProperties = useMemo(
    () => ({
      newsId: id,
      name: article?.title,
    }),
    [id, article?.title],
  );

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(title)}</title>
      </Helmet>
      <Box
        sx={theme => ({
          backgroundColor: theme.palette.new.background.layout.default,
          minHeight: '100%',
          pt: 5,
          pb: 3,
          px: 2,
          display: 'flex',
          justifyContent: 'center',
        })}
      >
        <Box sx={{ maxWidth: '688px !important', width: '100%' }}>
          {isLoading && <ArticleDetailSkeleton />}
          {isSuccess && !!article && (
            <Box sx={{ mt: 3, mb: 3 }}>
              <Article
                eventNameAmplitude={eventNameAmplitude}
                eventPropertiesAmplitude={eventProperties}
                {...article}
                copyType={CopyTypePath.ARTICLE}
                copyRoute={newsRoutes.article.detail(Number(id!))}
              />
            </Box>
          )}
        </Box>
      </Box>
    </HuGoThemeProvider>
  );
};

export default ArticleDetail;
