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


import { auditRoute } from '@/app/router/routes/audit';
import { AppConsts } from '@/shared';
import { useGetApiV1MessageQuery } from '@/shared/api/audit/client';
import { useGetLocationChildrenQuery } from '@/shared/api/location/client';
import { RouterConsts } from '@/shared/consts/RouterConsts';
import { Helpers } from '@/shared/lib';
import { ChangeEvent, useCallback, useMemo, useState } from 'react';
import { useAuditLocationFilters } from './useAuditLocationFilters';
import { useAuditOptions } from './useAuditOptions';
import { useAuditSearchUpdater } from './useAuditSearchUpdater';
import { useSmartRoomIdFilter } from './useAuditSmartRoomIdFilter';

type ModelSelectValue = string | number | boolean | null;

export const useAuditSideFilter = () => {
  const searchParams = auditRoute.useSearch();

  const messageSearchParams = useMemo(() => {
    const {
      regionId,
      cityId,
      placeId,
      floorId,
      roomId,
      treeId,
      typeCall,
      ...params
    } = searchParams;

    return searchParams.locationIds.length
      ? params
      : { ...params, locationIds: undefined };
  }, [searchParams]);

  const { refetch } = useGetApiV1MessageQuery(messageSearchParams);

  const { updateSearchParams, updateParamAndResetPage } =
    useAuditSearchUpdater();

  const [isLocationFiltersOpen, setIsLocationFiltersOpen] = useState(false);

  const auditOptions = useAuditOptions(searchParams);

  const smartRoomFilter = useSmartRoomIdFilter({
    initialValue: searchParams.smartroomId,
    updateParamAndResetPage,
  });

  const locationFilters = useAuditLocationFilters({
    searchParams,
    updateParamAndResetPage,
  });

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

  const roomIdByTreeId = useMemo(() => {
    const rooms = roomsData || [];

    return new Map(
      rooms
        .filter((room) => room.id && room.treeId)
        .map((room) => [String(room.treeId), String(room.id)]),
    );
  }, [roomsData]);

  const clearLocationIds = useCallback(() => {
    updateParamAndResetPage('locationIds', []);
  }, [updateParamAndResetPage]);

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

      updateParamAndResetPage('locationIds', locationIds);
    },
    [roomIdByTreeId, updateParamAndResetPage],
  );

  const setRegionId = useCallback(
    (value: string[]) => {
      locationFilters.setRegionId(value);
      clearLocationIds();
    },
    [clearLocationIds, locationFilters],
  );

  const setCityId = useCallback(
    (value: string[]) => {
      locationFilters.setCityId(value);
      clearLocationIds();
    },
    [clearLocationIds, locationFilters],
  );

  const setPlaceId = useCallback(
    (value: string[]) => {
      locationFilters.setPlaceId(value);
      clearLocationIds();
    },
    [clearLocationIds, locationFilters],
  );

  const setFloorId = useCallback(
    (value: string[]) => {
      locationFilters.setFloorId(value);
      clearLocationIds();
    },
    [clearLocationIds, locationFilters],
  );

  const setRoomId = useCallback(
    (value: string[]) => {
      locationFilters.setRoomId(value);
      updateRoomLocationIds(value);
    },
    [locationFilters, updateRoomLocationIds],
  );

  const handleChange =
    (paramName: string) =>
    (event: ChangeEvent<{ name?: string | undefined; value: unknown }>) => {
      updateParamAndResetPage(paramName, event.target.value);
    };

  const handleChangeUser = useCallback(
    (value: string) => {
      updateParamAndResetPage('userId', value);
    },
    [updateParamAndResetPage],
  );

  const handleChangeTimeFrom = useCallback(
    (time: Date) => {
      updateParamAndResetPage(
        'tmMin',
        new Date(time).getTime() / AppConsts.THOUSAND,
      );
    },
    [updateParamAndResetPage],
  );

  const handleChangeTimeMax = useCallback(
    (time: Date) => {
      updateParamAndResetPage(
        'tmMax',
        new Date(time).getTime() / AppConsts.THOUSAND,
      );
    },
    [updateParamAndResetPage],
  );

  const handleMacChange = useCallback(
    (event: ChangeEvent<HTMLInputElement>) => {
      updateParamAndResetPage('mac', event.target.value || undefined);
    },
    [updateParamAndResetPage],
  );

  const handleIpChange = useCallback(
    (event: ChangeEvent<HTMLInputElement>) => {
      updateParamAndResetPage('ip', event.target.value || undefined);
    },
    [updateParamAndResetPage],
  );

  const handleChangeModels = useCallback(
    (value: ModelSelectValue[]) => {
      updateParamAndResetPage('modelIds', value.map(String));
    },
    [updateParamAndResetPage],
  );

  const handleLocationFiltersToggle = useCallback(() => {
    setIsLocationFiltersOpen((prev) => !prev);
  }, []);

  const resetFilters = useCallback(() => {
    updateSearchParams({
      queryObject: { ...RouterConsts.AUDIT_DEFAULT_QUERY },
    });
    smartRoomFilter.resetSmartRoomId();
  }, [smartRoomFilter, updateSearchParams]);

  const refetchQuery = useCallback(() => {
    refetch();
  }, [refetch]);

  return {
    searchParams,
    isLocationFiltersOpen,

    ...auditOptions,
    ...smartRoomFilter,
    ...locationFilters,

    setRegionId,
    setCityId,
    setPlaceId,
    setFloorId,
    setRoomId,

    modelIds: searchParams.modelIds,

    refetchQuery,
    resetFilters,
    handleChange,
    handleChangeUser,
    handleChangeTimeFrom,
    handleChangeTimeMax,
    handleMacChange,
    handleIpChange,
    handleLocationFiltersToggle,
    handleChangeModels,
  };
};