import { useState } from 'react';
import { useInfiniteQuery, useMutation } from 'react-query';

import { AxiosError } from 'axios';
import { IconInfoCircle, IconEdit, IconTrash } from '@material-hu/icons/tabler';
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 HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuSkeleton from '@material-hu/components/design-system/Skeleton';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { useDebounce } from 'src/hooks/useDebounce';
import useGeneralError from 'src/hooks/useGeneralError';
import { deleteShiftTemplate, getShiftsRepository } from 'src/services/shifts';
import { ResponseError } from 'src/types/services';
import { Shift } from 'src/types/shifts';
import { useLokaliseTranslation } from 'src/utils/i18n';

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

import { invalidateShiftsRepository, shiftsKeys } from '../../queries';

import TemplateCard from './TemplateCard';

type Props = {
  onCreateShift?: () => void;
  onCustomShiftPrefill?: (name: string) => void;
  onTemplateEdit?: (shift: Shift) => void;
};

const TemplateList = ({
  onCreateShift,
  onCustomShiftPrefill,
  onTemplateEdit,
}: Props) => {
  const [search, setSearch] = useState('');
  const { debouncedValue: debouncedSearch } = useDebounce(search, 300);
  const { t } = useLokaliseTranslation(['shifts', 'work_schedules']);
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();

  const {
    data: infiniteRegisters,
    isLoading: isLoadingShiftsRepository,
    isFetchingNextPage,
    hasNextPage,
    fetchNextPage,
  } = useInfiniteQuery(
    shiftsKeys.shiftsRepository({ search: debouncedSearch }),
    ({ pageParam = 1 }) =>
      getShiftsRepository({ page: pageParam, search: debouncedSearch }),
    {
      getNextPageParam: (_, pages) => {
        const { page, totalPages } = pages[pages.length - 1]?.data || {};
        return page < totalPages ? pages.length + 1 : undefined;
      },
      onError: () => {
        showGeneralError(t('error_load_shifts_repository'));
      },
      staleTime: 1000 * 60 * 2,
    },
  );

  const {
    mutate: deleteShiftTemplateMutation,
    isLoading: isDeletingShiftTemplate,
  } = useMutation(deleteShiftTemplate, {
    onSuccess: async () => {
      await invalidateShiftsRepository(false);
      enqueueSnackbar({
        title: t('actions.delete_template.success'),
        description: t('actions.delete_template.success_description'),
        variant: 'success',
      });
    },
    onError: (error: AxiosError<ResponseError>) => {
      showGeneralError(error, t('actions.delete_template.error'));
    },
  });

  const shiftMenuOptions = (shift: Shift) => [
    {
      Icon: IconEdit,
      title: t('edit_shift'),
      onClick: () => {
        onTemplateEdit?.(shift);
      },
    },
    {
      Icon: IconTrash,
      title: t('delete_shift'),
      onClick: () => {
        deleteShiftTemplateMutation(shift.id);
      },
    },
  ];

  const registers =
    infiniteRegisters?.pages?.flatMap(page => page.data.items) || [];
  const resultsFetched = !!registers?.length;

  return (
    <Stack sx={{ gap: 1 }}>
      <HuSearch
        value={search}
        onChange={inputValue => {
          setSearch(inputValue);
        }}
      />
      <Typography
        variant="globalS"
        sx={{
          color: ({ palette }) => palette.new.text.neutral.lighter,
          fontWeight: 'fontWeightSemiBold',
          mt: 2,
        }}
      >
        {t('work_schedules:shifts')}
      </Typography>

      <HuCardContainer
        sx={{
          backgroundColor: ({ palette }) =>
            palette.new.background.layout.default,
          border: 'unset',
          overflowY: 'scroll',
          ...(!isLoadingShiftsRepository &&
            !onCustomShiftPrefill && {
              '& > .MuiCardContent-root': {
                pb: 0,
              },
            }),
        }}
        fullWidth
      >
        {!resultsFetched && !isLoadingShiftsRepository && (
          <HuEmptyState
            titleProps={{
              title: t('no_shifts_saved_yet'),
              description: t('no_shifts_saved_yet_description'),
            }}
            avatarProps={{
              Icon: IconInfoCircle,
              color: 'highlight',
            }}
            buttonProps={
              onCreateShift
                ? {
                    text: t('create_shift'),
                    onClick: () => {
                      onCreateShift();
                    },
                  }
                : undefined
            }
            sx={{ backgroundColor: 'transparent' }}
          />
        )}
        {(resultsFetched || isLoadingShiftsRepository) && (
          <>
            <InfiniteList
              isSuccess={resultsFetched}
              isLoading={isLoadingShiftsRepository}
              isFetchingNextPage={isFetchingNextPage}
              hasNextPage={hasNextPage}
              fetchNextPage={fetchNextPage}
              renderSkeleton={
                <Stack sx={{ gap: 1 }}>
                  <HuSkeleton height={58} />
                  <HuSkeleton height={58} />
                  <HuSkeleton height={58} />
                  <HuSkeleton height={58} />
                </Stack>
              }
              sx={{
                display: 'flex',
                flexDirection: 'column',
                gap: 2,
              }}
              loadingSkeleton
            >
              {registers?.map(register => (
                <TemplateCard
                  key={register.id}
                  shift={register}
                  onCustomShiftPrefill={onCustomShiftPrefill}
                  isDeletingShiftTemplate={isDeletingShiftTemplate}
                  getCardOptions={shiftMenuOptions}
                />
              ))}
            </InfiniteList>
            {!isLoadingShiftsRepository && !onCustomShiftPrefill && (
              <Stack
                sx={{
                  position: 'sticky',
                  bottom: 0,
                  backgroundColor: ({ palette }) =>
                    palette.new.background.layout.default,
                  py: 2,
                }}
              >
                <Button
                  variant="secondary"
                  size="large"
                  onClick={() => {
                    onCreateShift?.();
                  }}
                  fullWidth
                  loading={isDeletingShiftTemplate}
                  disabled={isDeletingShiftTemplate}
                >
                  {t('create_shift')}
                </Button>
              </Stack>
            )}
          </>
        )}
      </HuCardContainer>
    </Stack>
  );
};

export default TemplateList;
