import { type FC, useLayoutEffect, useRef, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { useInfiniteQuery, useMutation } from 'react-query';

import {
  IconEye,
  IconMessage,
  IconMessages,
  IconThumbUp,
} from '@material-hu/icons/tabler';
import Avatar from '@material-hu/mui/Avatar';
import Grid from '@material-hu/mui/Grid';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';
import useMediaQuery from '@material-hu/mui/useMediaQuery';

import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuChip from '@material-hu/components/design-system/Chip';
import HuCircularProgress from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import { queryClient } from 'src/config/react-query';
import { isDev } from 'src/constants/env';
import { useAuth } from 'src/contexts/JWTContext';
import useCommunityFeature from 'src/hooks/useCommunityFeature';
import useGeneralError from 'src/hooks/useGeneralError';
import CommentUsers from 'src/pages/dashboard/liveStream/components/CommentUsers';
import { type PostCommentPayload } from 'src/types/comments';
import { CommunityFeature } from 'src/types/communityFeatures';
import {
  Configuration,
  HostInteractionTab,
  StreamStatus,
} from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import AddComment from '../../components/AddComment';
import { useGetStatistics } from '../../hooks/useGetStatistics';
import { useStreamDestination } from '../../hooks/useStreamDestination';
import { optimistCommentUpdate } from '../../utils';

import StreamMetrics from './metrics';
import PollsContainer from './polls/Container';

const { GENERAL } = Configuration;

type HostInterationsUsersProps = {
  activeStep: Configuration;
  postId: number;
  streamId: string;
  streamStatus: StreamStatus;
};

const LIMIT = 100;
const SCROLL_THRESHOLD = 50;
const INTERACTION_TABS = [
  {
    id: HostInteractionTab.COMMENTS,
    labelKey: 'COMMENTS',
  },
];

const HostInterationsUsers: FC<HostInterationsUsersProps> = props => {
  const { postId, activeStep, streamId, streamStatus } = props;

  const [selectedTab, setSelectedTab] = useState<HostInteractionTab>(
    HostInteractionTab.COMMENTS,
  );
  const [isAtBottom, setIsAtBottom] = useState(true);
  const commentsContainerRef = useRef<HTMLDivElement | null>(null);
  const { t } = useLokaliseTranslation('livestream');
  const { watch } = useFormContext();
  const { commentsEnabled } = watch();
  const theme = useTheme();
  const { user: currentUser } = useAuth();
  const canViewStreamMetrics = useCommunityFeature(
    CommunityFeature.VIEW_STREAM_METRICS,
  );
  const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
  const { actions: destinationActions, keys: destinationKeys } =
    useStreamDestination();
  const { reactionsCount, commentCount, participantCount } = useGetStatistics({
    postId,
  });
  const showGeneralError = useGeneralError();

  const { data, isLoading } = useInfiniteQuery(
    destinationKeys.commentsDetail(postId),
    ({ pageParam }) =>
      destinationActions.getPostComments(postId, LIMIT, pageParam),
    {
      getNextPageParam: (lastPage, pages) => {
        if (!lastPage?.data) {
          return undefined;
        }
        return destinationActions.getNextPage(lastPage, pages, LIMIT);
      },
      select: response => ({
        ...response,
        pages: response.pages.filter(page => page?.data),
      }),
      enabled: commentCount > 0,
      onError: error => {
        showGeneralError(error, t('ERROR_LOADING_COMMENTS'));
      },
    },
  );

  const comments = destinationActions.transformPostComments(data?.pages) || [];

  useLayoutEffect(() => {
    const element = commentsContainerRef.current;

    if (element && isAtBottom) {
      element?.scrollTo(0, element.scrollHeight);
    }
  }, [comments.length]);

  const postMutation = useMutation(
    (body: PostCommentPayload) => destinationActions.commentPost(postId, body),
    {
      onMutate: async newComment => {
        const previousComments = await optimistCommentUpdate(
          currentUser,
          newComment,
          destinationKeys.commentsDetail(postId),
        );

        return previousComments;
      },
      onSuccess: response =>
        destinationActions.unshiftComment(postId, response?.data),
      onError: (error, _, context) => {
        if (context?.previousComments) {
          queryClient.setQueryData(
            destinationKeys.commentsDetail(postId),
            context.previousComments,
          );
        }
        showGeneralError(error, t('ERROR_ADD_COMMENT'));
      },
      onSettled: () => {
        const element = commentsContainerRef.current;
        if (element) {
          element?.scrollTo(0, element.scrollHeight);
        }
      },
    },
  );

  const statisticsIcons = [
    {
      StatisticsIcons: IconEye,
      label: 'SPECTATORS',
      count: participantCount || 0,
      colorAvatar: theme.palette.new.background.feedback.highlight,
      colorIcon: theme.palette.new.text.feedback.highlight,
    },
    {
      StatisticsIcons: IconMessage,
      label: 'COMMENTS',
      count: commentCount || 0,
      colorAvatar: theme.palette.new.background.feedback.warning,
      colorIcon: theme.palette.new.text.feedback.warning,
    },
    {
      StatisticsIcons: IconThumbUp,
      label: 'REACTIONS',
      count: reactionsCount || 0,
      colorAvatar: theme.palette.new.background.layout.brand,
      colorIcon: theme.palette.new.text.neutral.brand,
    },
  ];

  const handleScroll = () => {
    if (!commentsContainerRef.current) return;

    const { scrollTop, scrollHeight, clientHeight } =
      commentsContainerRef.current;

    setIsAtBottom(scrollHeight - scrollTop - clientHeight <= SCROLL_THRESHOLD);
  };

  return (
    <>
      {activeStep === GENERAL && (
        <Stack
          sx={{
            flexDirection: 'row',
            width: '80%',
            gap: 2,
            flexWrap: isSmallScreen ? 'wrap' : 'nowrap',
          }}
        >
          <Stack
            sx={{
              width: '100%',
              height: 'fit-content',
              gap: 2,
              minWidth: !isSmallScreen ? '220px' : 'auto',
            }}
          >
            <HuCardContainer
              sx={{
                py: theme.spacing(1),
                width: '100%',
                height: 'fit-content',
              }}
            >
              <Typography
                variant="globalM"
                fontWeight="fontWeightSemiBold"
              >
                {t('STATISTICS')}
              </Typography>
              <Grid
                container
                rowSpacing={2}
                columnSpacing={{ xs: 1, sm: 2, md: 3 }}
                sx={{ mt: 0 }}
              >
                {statisticsIcons.map(
                  ({
                    StatisticsIcons,
                    label,
                    count,
                    colorAvatar,
                    colorIcon,
                  }) => (
                    <Grid
                      key={label}
                      item
                      md={12}
                      lg={6}
                    >
                      <Stack sx={{ flexDirection: 'row', gap: 1 }}>
                        <Avatar sx={{ bgcolor: colorAvatar }}>
                          <StatisticsIcons color={colorIcon} />
                        </Avatar>
                        <Stack>
                          <Typography
                            variant="globalXS"
                            fontWeight="fontWeightSemiBold"
                          >
                            {count}
                          </Typography>
                          <Typography
                            variant="globalXXS"
                            color="new.text.neutral.lighter"
                          >
                            {t(label)}
                          </Typography>
                        </Stack>
                      </Stack>
                    </Grid>
                  ),
                )}
              </Grid>
            </HuCardContainer>
            {(isDev || import.meta.env.DEV || canViewStreamMetrics) &&
              streamStatus !== StreamStatus.Finished && (
                <StreamMetrics isStreaming />
              )}
          </Stack>
          <HuCardContainer
            sx={{
              py: theme.spacing(1),
              width: '100%',
              maxHeight: '670px',
            }}
          >
            {INTERACTION_TABS.length > 1 && (
              <Stack
                sx={{
                  flexDirection: 'row',
                  alignItems: 'center',
                  gap: 1,
                  mb: theme.spacing(2),
                }}
              >
                {INTERACTION_TABS.map(tab => (
                  <HuChip
                    key={tab.id}
                    label={t(tab.labelKey)}
                    onClick={() => setSelectedTab(tab.id)}
                    isSelected={selectedTab === tab.id}
                  />
                ))}
              </Stack>
            )}

            {selectedTab === HostInteractionTab.COMMENTS && (
              <>
                <Typography
                  variant="globalM"
                  fontWeight="fontWeightSemiBold"
                >
                  {t('COMMENTS')}
                </Typography>
                <Stack
                  sx={{
                    flexDirection: 'row',
                    alignItems: 'center',
                    gap: 1,
                    mb: theme.spacing(2),
                  }}
                >
                  <Typography
                    variant="globalXS"
                    color="new.text.neutral.lighter"
                  >
                    {commentCount} {t('COMMENTS')}
                  </Typography>
                </Stack>
                <Stack
                  ref={commentsContainerRef}
                  onScroll={handleScroll}
                  sx={{
                    overflow: 'auto',
                    height: '400px',
                    gap: 2,
                  }}
                >
                  {!commentCount && (
                    <Stack
                      sx={{
                        alignItems: 'center',
                        justifyContent: 'center',
                        backgroundColor:
                          theme.palette.new.background.layout.default,
                        py: 2,
                        alignSelf: 'flex-start',
                        width: '100%',
                        borderRadius: 2,
                      }}
                    >
                      <IconMessages
                        style={{ marginBottom: theme.spacing(1) }}
                      />
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                      >
                        {t('NO_COMMENT_TITLE')}
                      </Typography>
                      <Typography
                        variant="globalXS"
                        color="new.text.neutral.lighter"
                      >
                        {t('NO_COMMENT_DESCRIPTION')}
                      </Typography>
                    </Stack>
                  )}
                  {isLoading && (
                    <Stack sx={{ textAlign: 'center' }}>
                      <HuCircularProgress />
                    </Stack>
                  )}
                  {!isLoading &&
                    !!comments?.length &&
                    comments.map(elem => (
                      <CommentUsers
                        key={elem.id}
                        comment={elem}
                      />
                    ))}
                </Stack>
                {commentsEnabled && <AddComment postMutation={postMutation} />}
                {!commentsEnabled && (
                  <Stack>
                    <Typography
                      variant="globalS"
                      color="new.text.neutral.lighter"
                    >
                      {t('post:comments_disabled')}
                    </Typography>
                  </Stack>
                )}
              </>
            )}

            {selectedTab === HostInteractionTab.POLLS && (
              <>
                <Typography
                  variant="globalM"
                  fontWeight="fontWeightSemiBold"
                >
                  {t('polls.title')}
                </Typography>
                <PollsContainer
                  streamId={streamId}
                  streamStatus={streamStatus}
                />
              </>
            )}
          </HuCardContainer>
        </Stack>
      )}
    </>
  );
};

export default HostInterationsUsers;
