import { FC } from 'react';
import { Helmet } from 'react-helmet-async';
import { useNavigate } from 'react-router-dom';
import { useMutation, useQuery } from 'react-query';

import { StreamVideo } from '@stream-io/video-react-sdk';
import Skeleton from '@material-hu/mui/Skeleton';
import Stack from '@material-hu/mui/Stack';

import { logEvent } from 'src/config/logging';
import { NavigationAction } from 'src/constants/navigationActions';
import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { isGroupsAccessDeniedError } from 'src/hooks/useGeneralError.helpers';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { useMutationOnMount } from 'src/hooks/useMutationOnMount';
import useNavigationAction from 'src/hooks/useNavigationAction';
import useRequiredParams from 'src/hooks/useRequiredParams';
import useGetStreamVideoClient from 'src/pages/dashboard/liveStream/hooks/useGetStreamVideoClient';
import { clearGroupsNotifications, getGroupDetails } from 'src/services/groups';
import { markNotificationAsRead } from 'src/pages/dashboard/notifications/services';
import { EventName } from 'src/types/amplitude';
import { FeedSource } from 'src/types/feed';
import { UserTypeStream } from 'src/types/stream';
import { userIsOnGroupPage } from 'src/utils/groups';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import KeyUpdatesAlert from 'src/components/key-updates/KeyUpdatesAlert';
import PendingApprovalPostList from 'src/components/pendingApprovals/PendingApprovalPostList';

import FeedPostSkeleton from '../events/components/skeleton/FeedPostSkeleton';
import PostAddSkeleton from '../feed/components/PostAddSkeleton';
import useScheduledPostsDrawer from '../feed/components/schedule/useScheduledPostsDrawer';
import {
  NotificationModuleCodes,
  NotificationTypeCodes,
} from '../notifications/constants';

import { groupsRoutes } from './routes';
import ArchivedGroupAlert from './components/ArchivedGroupAlert';
import GroupHeader from './components/GroupHeader';
import GroupPostAdd from './components/GroupPostAdd';
import GroupPostList from './components/GroupPostList';
import GroupScheduledPostsAlert from './components/GroupScheduledPostsAlert';
import { GroupMemberProvider, useGroupMember } from './GroupMemberContext';
import useAttachCommonGroupListeners from './hooks/useAttachCommonGroupListeners';
import { useGroupDetailSockets } from './hooks/useGroupDetailSockets';
import { groupsKeys, invalidateGroupNotifications } from './queries';
import { GROUP_DETAIL_PAGE_BANNER_DIMENSIONS } from './utils';

const CONTAINER_PADDING = 3;

const Group: FC = () => {
  const { id } = useRequiredParams(['id']);
  useGroupDetailSockets();
  const { t } = useTranslation(['post']);
  const { instance } = useAuth();
  const HuGoThemeProvider = useHuGoTheme();
  const showGeneralError = useGeneralError();
  const navigate = useNavigate();
  const client = useGetStreamVideoClient(UserTypeStream.VIEWER);
  const { userCanSeePosts, userIsMember } = useGroupMember();

  const { drawer, showDrawer } = useScheduledPostsDrawer({
    groupId: id,
    userCanSeePosts,
  });

  // Navigation trigger to open scheduled posts drawer when coming from another route
  useNavigationAction(NavigationAction.OPEN_SCHEDULED_POSTS, () =>
    showDrawer({}),
  );

  const { data, isLoading } = useQuery(
    groupsKeys.detail(id),
    () => getGroupDetails(id),
    {
      onSuccess: response => {
        if (response?.data?.unreadCount) {
          clearGroupsNotifications(id).then(() => {
            // Explicitly invalidate sidebar notifications as fallback
            // in case socket event is not received
            invalidateGroupNotifications();
          });
        }
        logEvent(EventName.GROUPS_GROUP_BUBBLES_CLEARED, {
          groupId: id,
          instance,
          response,
        });
      },
      onError: err => {
        showGeneralError(err, t('error_loading_group'));
        if (isGroupsAccessDeniedError(err as any)) {
          navigate(groupsRoutes.groups());
        }
      },
    },
  );

  const mutation = useMutation(() =>
    markNotificationAsRead(
      NotificationModuleCodes.GROUPS,
      NotificationTypeCodes.NEW_GROUP_POST,
      {
        groupId: id,
      },
    ),
  );

  useMutationOnMount(mutation, id);

  const group = data?.data;

  useAttachCommonGroupListeners({
    enabled: !!userIsOnGroupPage,
    source: FeedSource.GROUP,
  });

  return (
    <StreamVideo client={client}>
      <HuGoThemeProvider>
        <Helmet>
          <title>{formatTitle(t('group:groups'))}</title>
        </Helmet>
        <Stack
          sx={{
            backgroundColor: theme =>
              theme.palette.new.background.layout.default,
            minHeight: '100%',
          }}
        >
          <Stack
            sx={theme => ({
              alignItems: 'center',
              p: CONTAINER_PADDING,
              pb: 8,
              mx: 'auto',
              width: '100%',
              maxWidth: `calc(${GROUP_DETAIL_PAGE_BANNER_DIMENSIONS.WIDTH}px + ${theme.spacing(CONTAINER_PADDING * 2)})`,
              backgroundColor: theme =>
                theme.palette.new.background.layout.default,
            })}
          >
            {isLoading && (
              <Stack sx={{ width: '80%', my: 3, gap: 3 }}>
                <Skeleton
                  variant="rectangular"
                  height={362}
                  width="100%"
                  sx={{ borderRadius: 1 }}
                />
                <PostAddSkeleton />
                <Stack
                  sx={{
                    gap: 2,
                    '.MuiPaper-root': {
                      borderColor: theme =>
                        theme.palette.new.border.neutral.default,
                    },
                  }}
                >
                  {Array.from({ length: 3 }, (_, i) => (
                    <FeedPostSkeleton key={`skeleton-${i}`} />
                  ))}
                </Stack>
              </Stack>
            )}
            {!isLoading && group && (
              <GroupMemberProvider
                members={group.members}
                publicationPolicy={group.publicationPolicy}
                privacyPolicy={group.privacyPolicy}
                approvalPolicy={group.approvalPolicy}
                isArchived={group.isArchived}
              >
                <GroupHeader
                  title={group.title}
                  bannerUrl={group.bannerUrl}
                  description={group.description}
                  membersCount={group.membersCount}
                  privacyPolicy={group.privacyPolicy}
                  groupRequest={group.groupRequest}
                  hasPendingRequests={group.hasPendingRequests}
                  isArchived={group.isArchived}
                  isMultiCompany={group.isMultiCompany}
                />
                <Stack sx={{ width: '100%', my: 2, gap: 2 }}>
                  <ArchivedGroupAlert
                    isArchived={group.isArchived || false}
                    archivedDate={group.archivedMetadata?.archivedAt}
                  />
                  <PendingApprovalPostList groupId={group.id.toString()} />
                  <GroupScheduledPostsAlert
                    onShowScheduledPosts={() => showDrawer({})}
                  />
                  <GroupPostAdd onScheduledPostView={() => showDrawer({})} />
                  {userIsMember && <KeyUpdatesAlert sourceId={group.id} />}
                  <GroupPostList />
                </Stack>
                {drawer}
              </GroupMemberProvider>
            )}
          </Stack>
        </Stack>
      </HuGoThemeProvider>
    </StreamVideo>
  );
};

export default Group;
