import { type FC, Fragment, useMemo, useState } from 'react';
import { useInfiniteQuery } from 'react-query';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import { IconInfoCircle } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import ButtonBase from '@material-hu/mui/ButtonBase';
import Divider from '@material-hu/mui/Divider';
import Radio from '@material-hu/mui/Radio';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuSelectionCard from '@material-hu/components/composed-components/SelectionCard';
import HuAvatar from '@material-hu/components/design-system/Avatar';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import InputSearch from '@material-hu/components/design-system/Inputs/Search';

import { useAuth } from 'src/contexts/JWTContext';
import usePermissions from 'src/hooks/usePermissions';
import { groupsKeys } from 'src/pages/dashboard/groups/queries';
import { getPostableGroups } from 'src/services/groups';
import { type Group } from 'src/types/groups';
import { IconTypes } from 'src/types/icons';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { UserPermissions } from 'src/utils/permissions';

import InfiniteList from 'src/components/list/InfiniteList';
import ProfilePicture from 'src/components/user/ProfilePicture';

import { type ShareDestination } from './types';

type ShareDestinationSelectorProps = {
  selected: ShareDestination | null;
  authorName: string;
  onSelect: (destination: ShareDestination) => void;
};

export const ShareDestinationSelector: FC<ShareDestinationSelectorProps> = ({
  selected,
  authorName,
  onSelect,
}) => {
  const { t } = useTranslation(['post', 'group', 'general']);
  const { user } = useAuth();
  const { hasAll: canCreateFeedPosts } = usePermissions([
    UserPermissions.CREATE_POSTS,
  ]);

  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query);

  const { data, isLoading, hasNextPage, fetchNextPage, isFetchingNextPage } =
    useInfiniteQuery(
      [...groupsKeys.allList(), 'postable', debouncedQuery],
      ({ pageParam = 1 }) =>
        getPostableGroups({
          page: pageParam,
          limit: 10,
          q: debouncedQuery || undefined,
        }),
      {
        getNextPageParam: (_lastPage, pages) => {
          const last = pages.at(-1)?.data;
          if (!last) return undefined;
          return last.page < last.totalPages ? pages.length + 1 : undefined;
        },
      },
    );

  const groups = useMemo<Group[]>(
    () => (data?.pages ?? []).flatMap(page => page.data.items),
    [data],
  );

  const isFeedSelected = selected?.type === 'feed';

  const handleSelectFeed = () => {
    onSelect({ type: 'feed' });
  };

  const handleSelectGroup = (group: Group) => {
    onSelect({ type: 'group', groupId: group.id, groupTitle: group.title });
  };

  return (
    <Stack sx={{ gap: 2 }}>
      <Typography
        variant="globalM"
        fontWeight="fontWeightSemiBold"
      >
        {t('post:share_destination_subtitle', { name: authorName })}
      </Typography>

      {canCreateFeedPosts && (
        <HuSelectionCard
          checked={isFeedSelected}
          onClick={handleSelectFeed}
          fullWidth
        >
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 1,
              p: 1,
            }}
          >
            <Radio
              checked={isFeedSelected}
              onChange={handleSelectFeed}
              size="small"
            />
            {user && (
              <ProfilePicture
                id={user.id}
                user={user}
                sx={{ width: '32px', height: '32px' }}
                withLink={false}
              />
            )}
            <Typography variant="globalS">
              {t('post:share_destination_feed_wall')}
            </Typography>
          </Stack>
        </HuSelectionCard>
      )}

      <CardContainer
        fullWidth
        noHover
      >
        <Box>
          <InputSearch
            fullWidth
            placeholder={t('post:share_destination_search_group')}
            value={query}
            onChange={setQuery}
          />
        </Box>

        <InfiniteList
          isSuccess={!isLoading}
          isLoading={isLoading}
          isEmpty={!isLoading && groups.length === 0}
          noResultsLabel={
            <Stack sx={{ alignItems: 'center', gap: 1.5, py: 3, px: 2 }}>
              <HuAvatar
                Icon={IconInfoCircle}
                size="large"
                sx={{
                  backgroundColor: theme =>
                    theme.palette.new.background.layout.default,
                }}
              />
              <Typography
                variant="globalS"
                textAlign="center"
                sx={{ color: theme => theme.palette.new.text.neutral.lighter }}
              >
                {t('post:share_destination_no_results')}
              </Typography>
            </Stack>
          }
          hasNextPage={!!hasNextPage}
          fetchNextPage={fetchNextPage}
          isFetchingNextPage={isFetchingNextPage}
        >
          {groups.map((group, index) => {
            const isGroupSelected =
              selected?.type === 'group' && selected.groupId === group.id;

            return (
              <Fragment key={group.id}>
                {index > 0 && <Divider />}
                <ButtonBase
                  onClick={() => handleSelectGroup(group)}
                  sx={{
                    display: 'flex',
                    flexDirection: 'row',
                    alignItems: 'center',
                    justifyContent: 'flex-start',
                    gap: 1,
                    px: 1,
                    py: 2.5,
                    width: '100%',
                    textAlign: 'left',
                  }}
                >
                  <Radio
                    checked={isGroupSelected}
                    onChange={() => handleSelectGroup(group)}
                    size="small"
                  />
                  <HuAvatar
                    src={
                      group.icon?.type === IconTypes.IMAGE
                        ? group.icon.value
                        : undefined
                    }
                    text={
                      group.icon?.type === IconTypes.EMOJI
                        ? group.icon.value
                        : undefined
                    }
                    alt={group.title}
                    variant="square"
                    sx={{ width: 40, height: 40 }}
                  />
                  <Stack>
                    <Typography
                      variant="globalS"
                      fontWeight="bold"
                    >
                      {group.title}
                    </Typography>
                    <Typography
                      variant="globalXS"
                      sx={{
                        color: theme => theme.palette.new.text.neutral.lighter,
                      }}
                    >
                      {`${t(`group:groups_group_title_${group.privacyPolicy.toLowerCase()}`)} • ${t('group:member', { count: group.membersCount })}`}
                    </Typography>
                  </Stack>
                </ButtonBase>
              </Fragment>
            );
          })}
        </InfiniteList>
      </CardContainer>
    </Stack>
  );
};

export default ShareDestinationSelector;
