import { FC, Fragment } from 'react';
import { useInfiniteQuery } from 'react-query';
import { useParams } from 'react-router';

import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuSkeleton from '@material-hu/components/design-system/Skeleton';
import HuTitle from '@material-hu/components/design-system/Title';

import useGeneralError from 'src/hooks/useGeneralError';
import { getUsersAssignmentHistory } from 'src/services/timeTrackingService';
import { WorkScheduleUserAssignment } from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { flatPages } from 'src/utils/tableUtils';

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

import { timeTrackingKeys } from '../../../queries';

import AssignmentItem from './AssignmentItem';

type Props = {
  userId: number;
  onClose: () => void;
};

const PAGE_LIMIT = 20;

const assignmentSkeleton = Array(3)
  .fill(0)
  .map((_, index) => (
    <Fragment key={index}>
      <HuSkeleton
        variant="rounded"
        height={24}
        width={75}
      />
      <Stack
        sx={{
          alignItems: 'center',
          backgroundColor: ({ palette }) =>
            palette.new.background.layout.default,
          borderRadius: 2,
          flexDirection: 'row',
          gap: 1,
          p: 2,
        }}
      >
        <HuSkeleton
          variant="circular"
          height={40}
          width={40}
        />
        <HuSkeleton
          variant="rounded"
          height={32}
          width={200}
        />
      </Stack>
    </Fragment>
  ));

const AssignmentDrawer: FC<Props> = props => {
  const { onClose, userId } = props;
  const { t } = useLokaliseTranslation('work_schedules');
  const scheduleId = parseInt(useParams().id || '');
  const showGeneralError = useGeneralError();

  const {
    data: infiniteRegisters,
    isLoading: isLoadingHistory,
    fetchNextPage,
    isFetchingNextPage,
    hasNextPage,
  } = useInfiniteQuery(
    timeTrackingKeys.scheduleAssignmentsHistory(scheduleId, userId, undefined),
    ({ pageParam = 1 }) =>
      getUsersAssignmentHistory(scheduleId, userId, {
        page: pageParam,
        limit: PAGE_LIMIT,
      }),
    {
      getNextPageParam: (_, pages) => {
        const { page, totalPages } = pages[pages.length - 1]?.data || {};
        return page < totalPages ? pages.length + 1 : undefined;
      },
      onError: err => {
        showGeneralError(
          err,
          t('SCHEDULE_ASSIGNMENTS.FETCH_ASSIGNMENTS_HISTORY_ERROR'),
        );
      },
    },
  );

  const assignmentsHistory: WorkScheduleUserAssignment[] =
    flatPages(infiniteRegisters);

  const groupAssignmentsByVersion = (
    assigmentList: WorkScheduleUserAssignment[],
  ) => {
    const groupedAssignments = assigmentList.reduce(
      (acc, assignment) => {
        if (!acc[assignment.workScheduleVersion]) {
          acc[assignment.workScheduleVersion] = [];
        }
        acc[assignment.workScheduleVersion].push(assignment);
        return acc;
      },
      {} as Record<string, WorkScheduleUserAssignment[]>,
    );
    return Object.entries(groupedAssignments)
      .map(([version, assignments]) => ({ number: version, assignments }))
      .sort((a, b) => parseInt(b.number) - parseInt(a.number));
  };

  return (
    <Stack sx={{ height: '100%', gap: 2 }}>
      <HuTitle
        variant="M"
        title={t('SCHEDULE_ASSIGNMENTS.ASSIGNMENTS_MADE')}
        description={t('SCHEDULE_ASSIGNMENTS.ASSIGNMENTS_MADE_DESCRIPTION')}
      />
      {isLoadingHistory && assignmentSkeleton}
      {!isLoadingHistory &&
        assignmentsHistory?.length > 0 &&
        groupAssignmentsByVersion(assignmentsHistory)?.map(version => (
          <Stack
            key={version.number}
            sx={{ gap: 2 }}
          >
            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
            >
              {t('SCHEDULE_ASSIGNMENTS.VERSION', { number: version.number })}
            </Typography>
            <InfiniteList
              isSuccess={!!infiniteRegisters}
              isLoading={isLoadingHistory}
              fetchNextPage={fetchNextPage}
              isFetchingNextPage={isFetchingNextPage}
              hasNextPage={hasNextPage}
              sx={{ width: '100%', p: 0 }}
            >
              <Stack sx={{ gap: 2 }}>
                {version.assignments.map(assignment => (
                  <AssignmentItem
                    key={assignment.id}
                    assignment={assignment}
                    assignmentsHistory={assignmentsHistory}
                    onCloseDrawer={onClose}
                    userId={userId}
                  />
                ))}
              </Stack>
            </InfiniteList>
          </Stack>
        ))}
    </Stack>
  );
};

export default AssignmentDrawer;
