import { type AxiosResponse } from 'axios';

import { queryClient } from 'src/config/react-query';
import {
  type CategorizedHoursParams,
  getPendingRequestsAmount,
} from 'src/services/timeTracking';
import {
  type ControlRegisterParams,
  type UserControlParams,
  type UserSite,
} from 'src/types/timeTracking';

import { type CategorizedHoursListFilters } from './services';

export const timeTrackingKeys = {
  all: () => ['time-tracking'],
  controlRegisters: (params: ControlRegisterParams | undefined) => [
    ...timeTrackingKeys.all(),
    'control-registers',
    params,
  ],
  userControlRegisters: (params: UserControlParams) => [
    ...timeTrackingKeys.all(),
    'user-registers',
    params,
  ],
  userSites: (userId: number) => [
    ...timeTrackingKeys.all(),
    userId,
    'userSites',
  ],
  registersReport: () => [...timeTrackingKeys.all(), 'report'],
  regions: () => [...timeTrackingKeys.all(), 'regions'],
  getUsers: (search?: string) => [
    ...timeTrackingKeys.all(),
    'users',
    search || '',
  ],
  daySummary: () => [...timeTrackingKeys.all(), 'day-summary'],
  policies: () => [...timeTrackingKeys.all(), 'policies'],
  userPolicies: (userId: number) => [
    ...timeTrackingKeys.all(),
    'user-policies',
    userId,
  ],
  hourCategories: () => [...timeTrackingKeys.all(), 'hour-categories'],
  categorizedHours: {
    all: () => [...timeTrackingKeys.all(), 'categorized-hours'],
    detail: (id: string) => [
      ...timeTrackingKeys.all(),
      'categorized-hours',
      'detail',
      id,
    ],
    categoryCounts: (filters: CategorizedHoursListFilters) => [
      ...timeTrackingKeys.all(),
      'categorized-hours',
      'category-counts',
      filters,
    ],
  },
  dayDetail: (userId: number, date: string) => [
    ...timeTrackingKeys.all(),
    'day-detail',
    userId,
    date,
  ],
  categorizedHoursPending: () => [
    ...timeTrackingKeys.categorizedHours.all(),
    'pending-requests',
  ],
  categorizedHoursRequests: (params: CategorizedHoursParams) => [
    ...timeTrackingKeys.categorizedHours.all(),
    'categorized-hours-requests',
    params,
  ],
};

export const refetchDaySummaries = () => {
  queryClient.invalidateQueries(timeTrackingKeys.all());
};

export const getQueriedUserSites = (
  userId: number,
): AxiosResponse<UserSite[]> | undefined =>
  queryClient.getQueryData(timeTrackingKeys.userSites(userId));

// Invalidate control registers and user control registers by partially matching the query key
export const invalidateControlRegistersQueries = () => {
  queryClient.invalidateQueries({
    predicate: query =>
      query.queryKey.includes('control-registers') ||
      query.queryKey.includes('user-registers'),
  });
};

export const prefetchPendingRequestsAmount = () => {
  queryClient.prefetchQuery(timeTrackingKeys.categorizedHoursPending(), {
    queryFn: getPendingRequestsAmount,
  });
};

export const refetchCategorizedHoursPending = () => {
  queryClient.invalidateQueries(timeTrackingKeys.categorizedHoursPending());
};

export const invalidateCategorizedHoursApprovalQueries = () => {
  queryClient.invalidateQueries(timeTrackingKeys.categorizedHours.all());
  queryClient.invalidateQueries(timeTrackingKeys.categorizedHoursPending());
  queryClient.invalidateQueries({
    predicate: query => query.queryKey.includes('categorized-hours-requests'),
  });
};
