Загрузка данных


import { type AuditRouteSearch } from '@/app/router/routes/audit';
import { EquipmentModel } from '@/features/Settings/selects/lib';
import { useGetLocationChildrenQuery } from '@/shared/api/location/client';
import { useAutocompleteDebounce } from '@/shared/hooks';
import { Helpers } from '@/shared/lib';
import { ChangeEvent, useCallback, useEffect, useMemo, useRef } from 'react';

type ModelSelectValue = string | number | boolean | null;
type ModelSelectChangeValue = ModelSelectValue | ModelSelectValue[];

type Params = {
  searchParams: AuditRouteSearch;
  updateParamAndResetPage: (paramName: string, value: unknown) => void;
  updateParamsAndResetPage: (queryObject: Record<string, unknown>) => void;
};

const EQUIPMENT_FILTER_TYPES = [
  'controller_delete',
  'device_delete',
  'network_device_delete',
  'offline_device_delete',
  'padlet_delete',
];

const getEquipmentModelType = (messageType?: string) => {
  switch (messageType) {
    case 'controller_delete':
      return EquipmentModel.controller;
    case 'padlet_delete':
      return EquipmentModel.padlet;
    default:
      return EquipmentModel.device;
  }
};

const normalizeModelSelectValue = (
  value: ModelSelectChangeValue,
): ModelSelectValue[] => {
  if (Array.isArray(value)) {
    return value;
  }

  return value === null ? [] : [value];
};

export const useAdditionalFilters = ({
  searchParams,
  updateParamAndResetPage,
  updateParamsAndResetPage,
}: Params) => {
  const isMacResetting = useRef(false);
  const isIpResetting = useRef(false);
  const isMacDebounceReady = useRef(false);
  const isIpDebounceReady = useRef(false);

  const {
    inputValue: macValue,
    debouncedValue: debouncedMac,
    onInputChange: onMacInputChange,
    resetDebounce: resetMacDebounce,
  } = useAutocompleteDebounce(searchParams.mac || '');

  const {
    inputValue: ipValue,
    debouncedValue: debouncedIp,
    onInputChange: onIpInputChange,
    resetDebounce: resetIpDebounce,
  } = useAutocompleteDebounce(searchParams.ip || '');

  const isEquipmentFiltersAvailable = EQUIPMENT_FILTER_TYPES.includes(
    searchParams.type || '',
  );

  const equipmentModelType = getEquipmentModelType(searchParams.type);

  const { data: roomsData } = useGetLocationChildrenQuery(
    {
      parentId: Helpers.convertStringsToNumbers(searchParams.floorId),
    },
    {
      skip: !searchParams.floorId.length,
      refetchOnMountOrArgChange: true,
    },
  );

  const roomIdByTreeId = useMemo(() => {
    const map = new Map<string, string>();

    roomsData?.forEach((room) => {
      if (room.treeId !== undefined && room.id !== undefined) {
        map.set(String(room.treeId), String(room.id));
      }
    });

    return map;
  }, [roomsData]);

  useEffect(() => {
    if (!isMacDebounceReady.current) {
      isMacDebounceReady.current = true;
      return;
    }

    if (isMacResetting.current) {
      isMacResetting.current = false;
      return;
    }

    updateParamAndResetPage('mac', debouncedMac || undefined);
  }, [debouncedMac, updateParamAndResetPage]);

  useEffect(() => {
    if (!isIpDebounceReady.current) {
      isIpDebounceReady.current = true;
      return;
    }

    if (isIpResetting.current) {
      isIpResetting.current = false;
      return;
    }

    updateParamAndResetPage('ip', debouncedIp || undefined);
  }, [debouncedIp, updateParamAndResetPage]);

  const setRegionId = useCallback(
    (value: string[]) => {
      updateParamsAndResetPage({
        regionId: value,
        cityId: [],
        placeId: [],
        floorId: [],
        roomId: [],
        locationIds: [],
      });
    },
    [updateParamsAndResetPage],
  );

  const setCityId = useCallback(
    (value: string[]) => {
      updateParamsAndResetPage({
        cityId: value,
        placeId: [],
        floorId: [],
        roomId: [],
        locationIds: [],
      });
    },
    [updateParamsAndResetPage],
  );

  const setPlaceId = useCallback(
    (value: string[]) => {
      updateParamsAndResetPage({
        placeId: value,
        floorId: [],
        roomId: [],
        locationIds: [],
      });
    },
    [updateParamsAndResetPage],
  );

  const setFloorId = useCallback(
    (value: string[]) => {
      updateParamsAndResetPage({
        floorId: value,
        roomId: [],
        locationIds: [],
      });
    },
    [updateParamsAndResetPage],
  );

  const setRoomId = useCallback(
    (roomTreeIds: string[]) => {
      const locationIds = roomTreeIds
        .map((treeId) => roomIdByTreeId.get(String(treeId)))
        .filter((id): id is string => Boolean(id));