import { useState } from 'react';
import { type QueryKey, useInfiniteQuery } from 'react-query';
import { useParams } from 'react-router-dom';

import { type AxiosResponse } from 'axios';
import { useDebounce } from '@material-hu/hooks/useDebounce';
import { useDrawer } from '@material-hu/hooks/useDrawer';
import { IconZoomExclamation } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuStateCard from '@material-hu/components/composed-components/StateCard';
import HuUserAvatar from '@material-hu/components/composed-components/UserAvatar';
import HuAlert from '@material-hu/components/design-system/Alert';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { usersKeys } from 'src/pages/dashboard/Users/queries';
import * as usersService from 'src/services/usersService';
import { type Criteria, CriteriaType } from 'src/types/audience';
import { type User } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { type PaginatedResponse, type Pagination } from 'src/utils/tableUtils';

import { InfiniteList } from 'src/components/InfiniteList';

import { useCriteria } from './criteriaContext';
import {
  type QueryKeys,
  type SegmentationCriteriaService,
} from './hooks/useSegmentationCriteria';

export type SeeCollaboratorsProps = {
  service: (
    pagination: Pagination,
  ) => Promise<AxiosResponse<PaginatedResponse<User>>>;
  queryKey: QueryKey[];
  title: string;
  showCountAlert: boolean;
};

type CollaboratorsDrawerCommonProps = Pick<SeeCollaboratorsProps, 'title'> & {
  goBackDescription: string;
} & Partial<
    Pick<SeeCollaboratorsProps, 'service' | 'queryKey' | 'showCountAlert'>
  >;

const SeeCollaborators = (props: SeeCollaboratorsProps) => {
  const HuGoThemeProvider = useHuGoTheme();
  const { title, service, queryKey } = props;
  const { t } = useLokaliseTranslation('audience');
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search);

  const { data, isLoading, fetchNextPage, isFetchingNextPage, hasNextPage } =
    useInfiniteQuery(
      [queryKey, debouncedSearch],
      ({ pageParam = 0 }) =>
        service({
          page: pageParam,
          search: debouncedSearch || undefined,
          limit: 100,
        }),
      {
        getNextPageParam: lastPage =>
          lastPage.data.page === lastPage.data.totalPages
            ? undefined
            : lastPage.data.page,
      },
    );

  const formsPages = data?.pages || [];

  const results = formsPages.flatMap(page => page.data.items);

  return (
    <HuGoThemeProvider>
      <Stack sx={{ px: 2, height: '100%' }}>
        <Typography
          sx={{ mb: 3 }}
          variant="globalS"
        >
          {title}
        </Typography>
        <Stack sx={{ flex: 1 }}>
          <HuSearch
            value={search}
            onChange={setSearch}
          />
          <InfiniteList
            isSuccess={!!data}
            isLoading={isLoading}
            fetchNextPage={fetchNextPage}
            isFetchingNextPage={isFetchingNextPage}
            hasNextPage={hasNextPage}
            isEmpty={!results.length && !isLoading}
            noResultsLabel={
              <HuStateCard
                sx={{ border: 'none' }}
                slotProps={{
                  title: {
                    title: t('general:empty_search_result'),
                  },
                  avatar: {
                    Icon: IconZoomExclamation,
                  },
                }}
              />
            }
          >
            {results.map(user => (
              <HuUserAvatar
                key={user.id}
                user={user}
                profileProps={{ showEmployeeInternalId: true }}
              />
            ))}
          </InfiniteList>
        </Stack>
      </Stack>
    </HuGoThemeProvider>
  );
};

export default SeeCollaborators;

type Props = {
  customGetIndividualCriteriaUsers?: SegmentationCriteriaService['customGetIndividualCriteriaUsers'];
  customKeyIndividualCriteriaUsers?: QueryKeys['customKeyIndividualCriteriaUsers'];
  criteria?: Partial<Criteria>;
  excludeDeactivatedUsers?: boolean;
};

export const useCriteriaColaborators = (props?: Props) => {
  const { criteria } = props || {};
  const { id } = useParams();
  const { templateId } = useCriteria();
  const { t } = useLokaliseTranslation(['audience']);
  const HuGoThemeProvider = useHuGoTheme();

  const { drawer, showDrawer, closeDrawer } = useDrawer(
    () => {
      let commonProps: CollaboratorsDrawerCommonProps = {
        title: t('selected_collaborators_title', {
          context: criteria?.type,
        }),
        goBackDescription: t('general:back'),
      };

      switch (criteria?.type) {
        case CriteriaType.SEGMENTED_USERS:
          commonProps = {
            ...commonProps,
            service: (pagination: Pagination) =>
              usersService.getAudience({
                segmentationItemIds: criteria.itemIds,
                ...pagination,
                ...(props?.excludeDeactivatedUsers
                  ? { onlyActiveAndUnclaimedAudienceUsers: true }
                  : {}),
              }),
            queryKey: usersKeys.audience({
              itemIds: criteria.itemIds,
              onlyActiveAndUnclaimedAudienceUsers:
                !!props?.excludeDeactivatedUsers,
            }),
          };
          break;
        case CriteriaType.ALL_USERS:
          commonProps = {
            ...commonProps,
            service: props?.excludeDeactivatedUsers
              ? (pagination: Pagination) =>
                  usersService.getPublicUsers({
                    ...pagination,
                    onlyActiveAndUnclaimedPublicUsers: true,
                  })
              : usersService.getPublicUsers,
            queryKey: [
              ...usersKeys.all(),
              'public-collaborators',
              props?.excludeDeactivatedUsers ? 'omit-deactivated' : 'all',
            ],
          };
          break;
        case CriteriaType.INDIVIDUAL_USERS:
          commonProps = {
            ...commonProps,
            service: (pagination: Pagination) =>
              props?.customGetIndividualCriteriaUsers
                ? props?.customGetIndividualCriteriaUsers(
                    {
                      ...pagination,
                    },
                    templateId!,
                  )
                : usersService.getAudience({
                    ...pagination,
                    ids: criteria.userIds,
                    ...(props?.excludeDeactivatedUsers
                      ? { onlyActiveAndUnclaimedAudienceUsers: true }
                      : {}),
                  }),
            queryKey: props?.customKeyIndividualCriteriaUsers
              ? props?.customKeyIndividualCriteriaUsers(Number(id), templateId!)
              : usersKeys.audience({
                  ids: criteria.userIds,
                  onlyActiveAndUnclaimedAudienceUsers:
                    !!props?.excludeDeactivatedUsers,
                }),
          };
          break;
      }

      return <SeeCollaborators {...(commonProps as SeeCollaboratorsProps)} />;
    },
    {
      title: t('selected_collaborators'),
      footer: (
        <HuAlert
          title={t('selected_collaborators_count', {
            count: criteria?.usersCount || 0,
          })}
          severity="info"
        />
      ),
      hasBackButton: true,
    },
  );
  return {
    drawer: <HuGoThemeProvider>{drawer}</HuGoThemeProvider>,
    showDrawer,
    closeDrawer,
  };
};
