import { queryClient } from 'src/config/react-query';
import {
  getShiftsRepository,
  ShiftCalendarParams,
  ShiftsRepositoryParams,
} from 'src/services/shifts';

export type ShiftCalendarBaseParams = Omit<
  ShiftCalendarParams,
  'page' | 'limit'
>;

export const shiftsKeys = {
  all: () => ['shifts'],
  collaborators: (id: number) => [
    ...shiftsKeys.all(),
    'pre-assign-collaborator',
    id,
  ],
  calendar: (params: ShiftCalendarBaseParams) => [
    ...shiftsKeys.all(),
    'calendar',
    params,
  ],
  regions: (params?: { search?: string }) => [
    ...shiftsKeys.all(),
    'regions',
    params || {},
  ],
  getUsers: (params?: { search?: string; siteId?: number }) => [
    ...shiftsKeys.all(),
    'users',
    params || {},
  ],
  shiftsRepository: (params: Omit<ShiftsRepositoryParams, 'page'>) => [
    ...shiftsKeys.all(),
    'repository',
    params,
  ],
  shiftRotations: (params: { search?: string }) => [
    ...shiftsKeys.all(),
    'rotations',
    params,
  ],
  shiftRotation: (id: string) => [...shiftsKeys.all(), 'rotation', id],
};

// Invalidate infinite queries partially matching the base query key
export const invalidateShiftsCalendar = () =>
  queryClient.invalidateQueries({
    predicate: query => query.queryKey.includes('calendar'),
  });

// Invalidate shift calendar queries that are contained on the target dates range
export const removeCalendarQueryData = (
  targetStartDate: string,
  targetEndDate: string,
) =>
  queryClient.removeQueries({
    predicate: query => {
      // Using unknown since we don't know/don't care about the type of the query key values
      const queryParams = query.queryKey[2] as Record<string, unknown>;
      const hasShiftCalendarParams =
        query.queryKey[0] === 'shifts' && query.queryKey[1] === 'calendar';
      if (
        !hasShiftCalendarParams ||
        !queryParams ||
        !queryParams?.startDate ||
        !queryParams?.endDate
      )
        return false;
      return (
        targetStartDate <= queryParams.endDate &&
        targetEndDate >= queryParams.startDate
      );
    },
  });

export const invalidateShiftsRepository = (removeQuery = true) => {
  queryClient.invalidateQueries({
    predicate: query => query.queryKey.includes('repository'),
  });
  if (removeQuery) {
    queryClient.removeQueries({
      predicate: query => query.queryKey.includes('repository'),
    });
  }
};

export const invalidateShiftRotations = () =>
  queryClient.invalidateQueries(shiftsKeys.shiftRotations({}));

export const removeShiftRotation = (id: string) =>
  queryClient.removeQueries(shiftsKeys.shiftRotation(id));

export const prefetchShiftsRepositoryFirstPage = () =>
  queryClient.prefetchInfiniteQuery(
    shiftsKeys.shiftsRepository({ search: '' }),
    () => getShiftsRepository({ page: 1, search: '' }),
    {
      staleTime: 1000 * 60 * 2,
    },
  );
