import { type FC, Fragment, useCallback, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { useInfiniteQuery } from 'react-query';
import { useNavigate, useParams } from 'react-router';

import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import { IconFilter } from '@material-hu/icons/tabler';
import Badge from '@material-hu/mui/Badge';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';

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 HuTitle from '@material-hu/components/design-system/Title';

import { useDebounce } from 'src/hooks/useDebounce';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { getUsersAssignedToSchedule } from 'src/services/timeTrackingService';
import {
  type ScheduleFormFilters,
  type WorkScheduleUserAssignment,
} from 'src/types/timeTracking';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { flatPages } from 'src/utils/tableUtils';
import { sToMs } from 'src/utils/timeUtils';

import { appliedFiltersNumber } from 'src/components/AdvancedFilter/utils';
import { InfiniteList } from 'src/components/InfiniteList';

import ListEmptyState from '../../components/ListEmptyState';
import { timeTrackingKeys } from '../../queries';
import { timeTrackingRoutes } from '../../routes';
import SectionHeader from '../../SectionHeader';
import {
  ASSIGNMENT_FILTERS_INITIAL_VALUES,
  FILTERS_INITIAL_VALUES,
} from '../constants';
import { parseCommonScheduleFilters } from '../utils';
import { useFiltersDrawer } from '../List/hooks/useFiltersDrawer';

import CollaboratorCard from './components/CollaboratorCard';

const assignmentsSkeleton = Array(4)
  .fill(0)
  .map((_, index) => (
    <Fragment key={index}>
      <Stack sx={{ flexDirection: 'row', gap: 0.5, p: 2 }}>
        <HuSkeleton
          variant="circular"
          height={40}
          width={40}
        />
        <Stack sx={{ flex: 1, gap: 0.5 }}>
          <HuSkeleton
            variant="rounded"
            height={24}
            width="100%"
          />
          <HuSkeleton
            variant="rounded"
            height={12}
            width="17%"
          />
        </Stack>
      </Stack>
      {index + 1 < 4 && <Divider sx={{ my: 1 }} />}
    </Fragment>
  ));

const PAGE_LIMIT = 20;

const AssignmentsList: FC = () => {
  const [filterValues, setFilterValues] = useState(
    ASSIGNMENT_FILTERS_INITIAL_VALUES,
  );
  const [search, setSearch] = useState('');
  const HuGoThemeProvider = useHuGoTheme();
  const scheduleId = parseInt(useParams().id!);
  const navigate = useNavigate();
  const { t } = useLokaliseTranslation('work_schedules');

  const handleFiltersChange = useCallback(
    ({ departmentIds, itemIds, regionIds, siteIds }: ScheduleFormFilters) => {
      setFilterValues({ departmentIds, itemIds, regionIds, siteIds });
    },
    [],
  );

  const { debouncedValue: debouncedValues, isDebouncing } = useDebounce({
    ...parseCommonScheduleFilters(filterValues),
    search,
  });

  const {
    data: infiniteRegisters,
    isLoading: isLoadingAssignments,
    fetchNextPage,
    isFetchingNextPage,
    hasNextPage,
  } = useInfiniteQuery(
    timeTrackingKeys.scheduleAssignmentsList(scheduleId, debouncedValues),
    ({ pageParam = 1 }) =>
      getUsersAssignedToSchedule(scheduleId, {
        ...debouncedValues,
        page: pageParam,
        limit: PAGE_LIMIT,
      }),
    {
      getNextPageParam: (_, pages) => {
        const { page, totalPages } = pages[pages.length - 1]?.data || {};
        return page < totalPages ? pages.length + 1 : undefined;
      },
      staleTime: sToMs(60),
    },
  );

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

  const goBack = () => {
    navigate(timeTrackingRoutes.workSchedulesList());
  };

  const { showDrawer: showFiltersDrawer, drawer: filtersDrawer } =
    useDrawerV2(useFiltersDrawer);

  const appliedFiltersCount = appliedFiltersNumber(
    filterValues.departmentIds,
    filterValues.siteIds,
    filterValues.itemIds,
  );
  const isFiltering = appliedFiltersCount > 0 || search !== '';

  const isLoadingTable = isDebouncing || isLoadingAssignments;

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(t('SCHEDULE_ASSIGNMENTS.ASSIGNMENTS_LIST'))}</title>
      </Helmet>

      {filtersDrawer}
      <Stack
        sx={{
          alignItems: 'center',
          backgroundColor: ({ palette }) =>
            palette.new.background.layout.default,
          height: 'auto',
          minHeight: '100%',
          gap: 3,
        }}
      >
        <SectionHeader
          title={t('ASSIGNMENTS')}
          goBack={goBack}
        />
        <Stack sx={{ gap: 2 }}>
          <Stack
            sx={{
              alignItems: 'center',
              flexDirection: 'row',
              justifyContent: 'space-between',
              gap: 5,
              width: '100%',
            }}
          >
            <HuTitle
              variant="L"
              title={t('SCHEDULE_ASSIGNMENTS.ASSIGNED_COLLABORATORS')}
              description={t('SCHEDULE_ASSIGNMENTS.LIST_HINT')}
            />
            <Button
              variant="primary"
              onClick={() => {
                navigate(
                  timeTrackingRoutes.editScheduleCollaborators(scheduleId),
                );
              }}
              sx={{ px: 3, py: 1.5 }}
            >
              {t('ASSIGN')}
            </Button>
          </Stack>
          <Stack sx={{ alignItems: 'center', flexDirection: 'row', gap: 2 }}>
            <HuSearch
              placeholder={t('SCHEDULE_ASSIGNMENTS.COLLABORATOR')}
              onChange={setSearch}
              value={search}
            />
            <Button
              variant="secondary"
              startIcon={<IconFilter size={16} />}
              onClick={() => {
                showFiltersDrawer({
                  filterValues: {
                    ...FILTERS_INITIAL_VALUES,
                    ...filterValues,
                  },
                  handleFiltersChange,
                  hiddenFields: ['userIds', 'scheduleCodes'],
                });
              }}
              endIcon={
                <Badge
                  sx={{ mx: appliedFiltersCount && 1.5 }}
                  color="primary"
                  badgeContent={appliedFiltersCount}
                />
              }
            >
              {t('GENERAL:FILTER')}
            </Button>
          </Stack>
          {!isLoadingTable && !assignments?.length && (
            <ListEmptyState
              title={t(
                !isFiltering
                  ? 'SCHEDULE_ASSIGNMENTS.NO_COLLABORATORS_ASSIGNED'
                  : 'SCHEDULE_ASSIGNMENTS.FILTER_NO_RESULTS',
              )}
              description={t(
                !isFiltering
                  ? 'SCHEDULE_ASSIGNMENTS.NO_COLLABORATORS_ASSIGNED_DESCRIPTION'
                  : 'SCHEDULE_ASSIGNMENTS.FILTER_NO_RESULTS_DESCRIPTION',
              )}
              action={
                !isFiltering
                  ? {
                      text: t('ASSIGN'),
                      onClick: () => {
                        navigate(
                          timeTrackingRoutes.editScheduleCollaborators(
                            scheduleId,
                          ),
                        );
                      },
                    }
                  : undefined
              }
            />
          )}
          {(isLoadingTable || assignments?.length > 0) && (
            <HuCardContainer
              elevation={0}
              padding={0}
              fullWidth
            >
              {isLoadingTable && assignmentsSkeleton}
              {!isLoadingTable && assignments?.length > 0 && (
                <InfiniteList
                  isSuccess={!!infiniteRegisters}
                  isLoading={isLoadingTable}
                  fetchNextPage={fetchNextPage}
                  isFetchingNextPage={isFetchingNextPage}
                  hasNextPage={hasNextPage}
                  sx={{ width: '100%', p: 0 }}
                >
                  {assignments.map((assignment, index) => (
                    <Fragment key={assignment.id}>
                      <CollaboratorCard assignment={assignment} />
                      {index + 1 < assignments.length && <Divider />}
                    </Fragment>
                  ))}
                </InfiniteList>
              )}
            </HuCardContainer>
          )}
        </Stack>
      </Stack>
    </HuGoThemeProvider>
  );
};

export default AssignmentsList;
