import { useCallback, useEffect, useRef, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { useInfiniteQuery, useMutation } from 'react-query';
import { useLocation, useNavigate } from 'react-router-dom';

import { StreamVideo } from '@stream-io/video-react-sdk';
import CheckIcon from '@material-hu/icons/material/Check';
import { IconSpeakerphone, IconX } from '@material-hu/icons/tabler';
import Avatar from '@material-hu/mui/Avatar';
import Box from '@material-hu/mui/Box';
import Card from '@material-hu/mui/Card';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import Chip from '@material-hu/components/design-system/Chip';

import { queryClient } from 'src/config/react-query';
import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useGetStreamVideoClient from 'src/pages/dashboard/liveStream/hooks/useGetStreamVideoClient';
import { getKeyUpdates, markKeyUpdateAsRead } from 'src/services/posts';
import { FeedSource } from 'src/types/feed';
import { UserTypeStream } from 'src/types/stream';
import { formatDateDifference } from 'src/utils/date';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { flatPages, getNextCursor } from 'src/utils/pagination';
import { getFullName } from 'src/utils/userUtils';

import { InfiniteList } from 'src/components/list';
import PostCard from 'src/components/post/PostCard';

import useAttachCommonGroupListeners from '../groups/hooks/useAttachCommonGroupListeners';
import { groupsKeys } from '../groups/queries';

import KeyUpdateListItemSkeleton from './components/KeyUpdateListItemSkeleton';
import KeyUpdatePostSkeleton from './components/KeyUpdatePostSkeleton';
import {
  addKeyUpdatesListDataReaction,
  feedKeys,
  removeKeyUpdatesListDataReaction,
} from './queries';
import { feedRoutes } from './routes';

const KeyUpdatesPage = () => {
  const { t } = useTranslation(['post', 'key_updates', 'general']);
  const navigate = useNavigate();
  const location = useLocation();
  const HuGoThemeProvider = useHuGoTheme();
  const theme = useTheme();
  const client = useGetStreamVideoClient(UserTypeStream.VIEWER);

  const [selectedPostId, setSelectedPostId] = useState<number | null>(null);
  const showGeneralError = useGeneralError();
  const postIdRef = useRef<number | null>(null);
  const timerRef = useRef<NodeJS.Timeout | null>(null);
  const [showAll, setShowAll] = useState(false);

  // Extract groupId from URL search params
  const searchParams = new URLSearchParams(location.search);
  const sourceId = searchParams.get('sourceId')
    ? Number(searchParams.get('sourceId'))
    : null;

  useAttachCommonGroupListeners({
    source: FeedSource.KEY_UPDATES,
  });

  const {
    data,
    isLoading: isLoadingInitial,
    isFetching,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery(
    feedKeys.keyUpdates.postList(!showAll),
    ({ pageParam = '' }) => getKeyUpdates(pageParam, !showAll),
    {
      getNextPageParam: getNextCursor,
      onError: err => {
        showGeneralError(err, t('post:error_loading_key_updates'));
      },
    },
  );

  const isLoading = isLoadingInitial || isFetching;

  const { mutate: markAsRead } = useMutation(
    () => markKeyUpdateAsRead(selectedPostId ?? undefined),
    {
      onError: err => {
        showGeneralError(err, t('post:error_marking_key_update_as_read'));
      },
    },
  );

  useEffect(() => {
    if (selectedPostId === null) return;

    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }

    postIdRef.current = selectedPostId;

    timerRef.current = setTimeout(() => {
      if (selectedPostId === postIdRef.current) {
        markAsRead();
      }
    }, 3000);

    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
      }
    };
  }, [selectedPostId, markAsRead]);

  const keyUpdates = flatPages(data);

  // Set first post as selected by default when posts load
  useEffect(() => {
    if (keyUpdates.length > 0 && !selectedPostId) {
      setSelectedPostId(keyUpdates[0].id);
    }
  }, [keyUpdates, selectedPostId]);

  const handleClose = useCallback(() => {
    // If we came from a group, return to that group
    if (sourceId) {
      queryClient.invalidateQueries(groupsKeys.all());
      navigate(`/groups/${sourceId}`);
    } else {
      queryClient.invalidateQueries(feedKeys.list());
      navigate(feedRoutes.feed());
    }
  }, [navigate, sourceId]);

  const handleSelectPost = useCallback((postId: number) => {
    setSelectedPostId(postId);
  }, []);

  const selectedPost = keyUpdates.find(post => post.id === selectedPostId);

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(t('post:key_updates'))}</title>
      </Helmet>
      <StreamVideo client={client}>
        <Box
          sx={{
            backgroundColor: 'background.default',
            height: '100%',
            display: 'flex',
            flexDirection: 'column',
            overflow: 'hidden',
          }}
        >
          <Stack
            sx={{
              flexDirection: 'row',
              justifyContent: 'space-between',
              alignItems: 'center',
              px: 3,
              py: 2,
              backgroundColor: 'background.paper',
              borderBottom: 1,
              borderColor: 'divider',
            }}
          >
            <Typography
              variant="globalM"
              fontWeight="fontWeightSemiBold"
            >
              {t('post:key_updates')}
            </Typography>
            <IconButton onClick={handleClose}>
              <IconX />
            </IconButton>
          </Stack>

          <Stack
            sx={{
              flexDirection: 'row',
              flexGrow: 1,
              overflow: 'hidden',
            }}
          >
            <Stack
              sx={{
                width: 280,
                borderRight: 1,
                borderColor: 'divider',
                overflow: 'auto',
                backgroundColor: 'background.paper',
              }}
            >
              <Stack
                direction="row"
                spacing={1}
                p={3}
              >
                <Chip
                  label={t('post:key_update_filter_title_all')}
                  isSelected={showAll}
                  onClick={() => setShowAll(true)}
                />
                <Chip
                  label={t('post:key_update_filter_title_unread')}
                  isSelected={!showAll}
                  onClick={() => setShowAll(false)}
                />
              </Stack>
              {isLoading &&
                Array.from({ length: 4 }).map((_, i) => (
                  <KeyUpdateListItemSkeleton key={i} />
                ))}
              {!isLoading && keyUpdates.length === 0 && (
                <Stack
                  sx={{
                    alignItems: 'center',
                    flexDirection: 'row',
                    bgcolor: _theme =>
                      _theme.palette.new.background.elements.grey,
                    borderRadius: theme.spacing(2),
                    mx: 2,
                    p: 2,
                    gap: theme.spacing(1),
                    color: theme => theme.palette.new.text.neutral.default,
                  }}
                >
                  <Stack sx={{ px: 1 }}>
                    <IconSpeakerphone fontSize="small" />
                  </Stack>
                  <Typography
                    variant="globalS"
                    fontWeight="fontWeightSemiBold"
                    color={theme => theme.palette.new.text.neutral.brand}
                  >
                    {t('post:no_unread_key_updates')}
                  </Typography>
                </Stack>
              )}
              {!isLoading && keyUpdates.length > 0 && (
                <InfiniteList
                  isSuccess={!isLoading && !!keyUpdates.length}
                  isEmpty={keyUpdates.length === 0}
                  fetchNextPage={fetchNextPage}
                  hasNextPage={hasNextPage}
                  isFetchingNextPage={isFetchingNextPage}
                  withEnd
                >
                  {keyUpdates.map(post => (
                    <Card
                      key={post.id}
                      sx={{
                        mx: 2,
                        mb: 1,
                        cursor: 'pointer',
                        boxShadow: 'none',
                        borderRadius: 2,
                        backgroundColor:
                          selectedPostId === post.id
                            ? _theme =>
                                _theme.palette.new.background.elements.grey
                            : 'background.paper',
                        border: 0,
                        '&:hover': {
                          backgroundColor: _theme =>
                            _theme.palette.new.background.elements.grey,
                        },
                      }}
                      onClick={() => handleSelectPost(post.id)}
                    >
                      <Stack
                        sx={{ p: 2 }}
                        direction="row"
                        spacing={2}
                      >
                        <Stack sx={{ justifyContent: 'center' }}>
                          {post.user ? (
                            <Avatar
                              src={post.user.profilePicture ?? undefined}
                              alt={`${post.user.firstName} ${post.user.lastName}`}
                              sx={{
                                width: 40,
                                height: 40,
                                bgcolor: _theme =>
                                  post.user.profilePicture
                                    ? 'transparent'
                                    : _theme.palette.primary.light,
                              }}
                            />
                          ) : (
                            <Avatar sx={{ width: 40, height: 40 }} />
                          )}
                        </Stack>
                        <Stack sx={{ flex: 1 }}>
                          <Typography
                            variant="globalM"
                            fontWeight="fontWeightSemiBold"
                            color={
                              selectedPostId === post.id
                                ? (theme: any) =>
                                    theme.palette.new.text.neutral.brand
                                : undefined
                            }
                          >
                            {getFullName(post.user)}{' '}
                            {t('key_updates:published_in')}{' '}
                            {post.group?.title ?? t('post:feed')}
                          </Typography>
                          <Typography
                            variant="globalXS"
                            color={
                              selectedPostId === post.id
                                ? (theme: any) =>
                                    theme.palette.new.text.neutral.brand
                                : (theme: any) =>
                                    theme.palette.new.text.neutral.lighter
                            }
                          >
                            {formatDateDifference(post.createdAt, t)}
                          </Typography>
                        </Stack>
                      </Stack>
                    </Card>
                  ))}
                </InfiniteList>
              )}
            </Stack>

            <Box
              sx={{
                flexGrow: 1,
                overflow: 'auto',
                p: 2,
                backgroundColor: _theme =>
                  _theme.palette.new.background.layout.default,
              }}
            >
              {isLoading && <KeyUpdatePostSkeleton />}
              {!isLoading && selectedPost && (
                <Stack sx={{ alignItems: 'center' }}>
                  <Stack sx={{ width: 576 }}>
                    <PostCard
                      key={selectedPost.id}
                      post={selectedPost}
                      hidePinIcon
                      onAddReaction={addKeyUpdatesListDataReaction}
                      onRemoveReaction={removeKeyUpdatesListDataReaction}
                    />
                  </Stack>
                </Stack>
              )}
              {!isLoading && !selectedPost && (
                <Stack
                  sx={{
                    justifyContent: 'center',
                    alignItems: 'center',
                    height: '100%',
                  }}
                >
                  {keyUpdates.length === 0 ? (
                    <Stack alignItems="center">
                      <Avatar
                        sx={{
                          bgcolor: _theme =>
                            _theme.palette.new.background.feedback.success,
                          width: 64,
                          height: 64,
                        }}
                      >
                        <CheckIcon
                          fontSize="large"
                          sx={{ color: 'success.main' }}
                        />
                      </Avatar>
                      <Typography
                        variant="globalS"
                        align="center"
                        sx={{ mt: 2 }}
                      >
                        {t('post:up_to_date')}
                      </Typography>
                      <Button
                        variant="outlined"
                        onClick={handleClose}
                        sx={{
                          mt: 1,
                          minWidth: '256px',
                        }}
                      >
                        <Typography
                          variant="globalS"
                          fontWeight="fontWeightSemiBold"
                          color={theme => theme.palette.new.text.neutral.brand}
                        >
                          {t('post:return_to_feed')}
                        </Typography>
                      </Button>
                    </Stack>
                  ) : (
                    <Typography color="textSecondary">
                      {t('post:select_a_post')}
                    </Typography>
                  )}
                </Stack>
              )}
            </Box>
          </Stack>
        </Box>
      </StreamVideo>
    </HuGoThemeProvider>
  );
};

export default KeyUpdatesPage;
