import { type FC, Fragment, useEffect, useMemo } from 'react';
import { useInfiniteQuery } from 'react-query';
import { useNavigate } from 'react-router-dom';

import { isToday, parseISO } from 'date-fns';
import Container from '@material-hu/mui/Container';
import Divider from '@material-hu/mui/Divider';
import ListItem from '@material-hu/mui/ListItem';
import ListItemAvatar from '@material-hu/mui/ListItemAvatar';
import ListItemText from '@material-hu/mui/ListItemText';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

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

import { logEvent } from 'src/config/logging';
import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import usePermissions from 'src/hooks/usePermissions';
import { useOpenConversation } from 'src/pages/dashboard/Conversations/hooks/useConversationsQueries';
import { createChat } from 'src/services/chats';
import { getCelebrationsByDate } from 'src/services/upcomingCelebrations';
import { EventName } from 'src/types/amplitude';
import {
  CelebrationType,
  type CelebrationUser,
} from 'src/types/upcomingCelebrations';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { getListItemsLength, getNextPage } from 'src/utils/pagination';
import { UserPermissions } from 'src/utils/permissions';
import { getRandomMessage, getResults } from 'src/utils/upcomingCelebrations';

import { chatRoutes } from 'src/components/dashboard/chat/routes';
import CelebrationTranslation from 'src/components/dashboard/upcomingCelebrations/CelebrationTranslation';
import NoFoundMessage from 'src/components/dashboard/upcomingCelebrations/NoFoundMessage';
import { upcomingCelebrationsKeys } from 'src/components/dashboard/upcomingCelebrations/queries';
import InfiniteList from 'src/components/list/InfiniteList';
import ProfilePicture from 'src/components/user/ProfilePicture';

const { VIEW_REGULAR_CHATS, VIEW_CHATS_V2 } = UserPermissions;

export type UpcomingCelebrationsListProps = {
  celebrationDate: string;
  filter?: CelebrationType;
  height?: string;
};

const LIMIT = 10;

export const UpcomingCelebrationsList: FC<
  UpcomingCelebrationsListProps
> = props => {
  const {
    celebrationDate,
    filter = CelebrationType.ALL,
    height = '350px',
  } = props;

  const { t } = useTranslation('celebrations');
  const showGeneralError = useGeneralError();
  const navigate = useNavigate();
  const { user: myUser, instance } = useAuth();
  const openConversationMutation = useOpenConversation();

  const { hasAll: canViewConversations } = usePermissions([VIEW_CHATS_V2]);
  const { hasAny: canSeeIconChat } = usePermissions([
    VIEW_REGULAR_CHATS,
    VIEW_CHATS_V2,
  ]);

  const { data, hasNextPage, refetch, isError, isSuccess, ...others } =
    useInfiniteQuery(
      upcomingCelebrationsKeys.date(celebrationDate, false, false, filter),
      ({ pageParam = 1 }) =>
        getCelebrationsByDate(celebrationDate, filter, pageParam, LIMIT),
      {
        getNextPageParam: (_, pages) =>
          getNextPage(getListItemsLength(pages), LIMIT, pages),
        onError: err => showGeneralError(err, t('error_loading_users')),
      },
    );

  useEffect(() => {
    logEvent(EventName.BIRTHDAYS_VIEW_NEXT, { next: celebrationDate });
  }, []);

  const handleSelect = async (user: CelebrationUser) => {
    const { isUserAnniversary, isUserBirthday } = user;
    const celebrateMessage = t(
      getRandomMessage(isUserAnniversary, isUserBirthday),
    );

    if (canViewConversations) {
      openConversationMutation.mutateAsync({
        users: [user.id.toString()],
        me: celebrateMessage,
      });
    } else {
      try {
        const { data: thread } = await createChat(user.id);

        const chatId = thread.chat.id;
        const state = {
          thread,
          isCelebrationChat: true,
          message: celebrateMessage,
        };

        navigate(chatRoutes.thread.detail(chatId), { state });
      } catch (err) {
        showGeneralError(err, t('CHAT:ERROR_CREATING_CHAT'));
      }
    }
  };

  const canCongratulate =
    isToday(parseISO(celebrationDate)) && instance?.allowCreateChats;

  const results = useMemo(() => getResults(data, filter), [data, filter]);

  return (
    <>
      {isError && (
        <Stack
          justifyContent="center"
          alignItems="center"
        >
          <Typography
            color="textSecondary"
            variant="subtitle2"
            sx={{
              textAlign: 'center',
              mt: 5,
              px: 2,
            }}
          >
            {t('ERROR_BOUNDARY:INFO')}
          </Typography>
          <Button
            onClick={() => refetch()}
            size="medium"
            variant="text"
            sx={{
              width: 'fit-content',
            }}
          >
            {t('retry')}
          </Button>
        </Stack>
      )}
      {!isError && (
        <InfiniteList
          isSuccess={isSuccess}
          isEmpty={!results?.length}
          noResultsLabel={<NoFoundMessage />}
          hasNextPage={hasNextPage}
          sx={{
            py: 1,
            position: 'relative',
            zIndex: 0,
            height: height,
            overflowY: 'auto',
          }}
          {...others}
        >
          {results?.map(user => (
            <Fragment
              key={`${user.id}${user.isUserAnniversary}${user.isUserBirthday}`}
            >
              <ListItem
                sx={{
                  borderBottom: theme =>
                    `solid 1px ${theme.palette.new.border.neutral.divider}`,
                  minHeight: '80px',
                }}
              >
                <ListItemAvatar sx={{ minWidth: '36px' }}>
                  <ProfilePicture
                    id={user.id}
                    user={user}
                    size="medium"
                    withLink
                  />
                </ListItemAvatar>
                <Container
                  sx={{
                    padding: '0 0 0 8px !important',
                    rowGap: '5px',
                    display: 'flex',
                    alignItems: 'center',
                  }}
                >
                  <ListItemText
                    sx={{
                      overflowWrap: 'break-word',
                      '@media screen and (max-width: 899px)': {
                        maxWidth: '80vw',
                      },
                      '& span': {
                        fontSize: '14px',
                        lineHeight: '17px',
                      },
                    }}
                    primary={
                      myUser && (
                        <CelebrationTranslation
                          canCongratulate={canCongratulate ?? false}
                          currentUserId={myUser.id}
                          user={user}
                          celebrationDate={celebrationDate}
                        />
                      )
                    }
                  />
                  {canSeeIconChat &&
                    myUser?.id !== user.id &&
                    canCongratulate && (
                      <Button
                        onClick={() => handleSelect(user)}
                        variant="secondary"
                        size="small"
                        sx={{ ml: 1 }}
                      >
                        {t('congratulate')}
                      </Button>
                    )}
                </Container>
              </ListItem>
              <Divider
                variant="inset"
                sx={{ ':last-of-type': { display: 'none' } }}
              />
            </Fragment>
          ))}
        </InfiniteList>
      )}
    </>
  );
};

export default UpcomingCelebrationsList;
