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


import { normalizeSipUriForPayload } from '@/domains/equipment/repositories/helpers/normalizeSipUriForPayload';
import { toSecondaryInterfacePostDto } from '@/domains/equipment/repositories/helpers/toSecondaryInterfacePostDto';
import {
  DeviceModel,
  usePostApiV1SecondaryInterfaceValueMutation,
} from '@/shared/api/controller/client';
import { useCloseDrawer } from '@/shared/hooks/drawer/useCloseDrawer';
import { useSelectDrawerType } from '@/shared/hooks/drawer/useSelectDrawerType';
import { Helpers } from '@/shared/lib';
import { DrawerTypes } from '@/shared/model/drawer/drawer.types';
import { useSyncControlPage } from '@/widgets/Monitoring/hooks';
import {
  Ieee8021X,
  ProtocolIp,
  Segment,
} from '@/widgets/Monitoring/model/networkEquipment.model';
import { useEquipmentRepository } from '@/widgets/Monitoring/repositories/networkEquipment.repository';
import { yupResolver } from '@hookform/resolvers/yup';
import { QueryStatus } from '@reduxjs/toolkit/dist/query';
import { useControllerActions } from '@shared/store/сontrollers/controllers.actions';
import { enqueueSnackbar } from 'notistack';
import { useEffect, useState } from 'react';
import { SubmitHandler, UseFormReturn, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import {
  NETWORK_EQUIPMENT_CREATE_FORM_KEY,
  NetworkEquipmentCreateFormData,
} from '../model/networkEquipmentCreateForm.model';
import { networkEquipmentCreateSchema } from '../validation/networkEquipmentCreate.schema';

type NetworkEquipmentCreate = {
  networkEquipmentSaveLabel: string;
  networkEquipmentCreateLabel: string;
  methods: UseFormReturn<NetworkEquipmentCreateFormData, any, undefined>;
  onDrawerClose: () => void;
  submitHandler: SubmitHandler<NetworkEquipmentCreateFormData>;
  isSaveButtonDisabled: boolean;
  setModel: (model: DeviceModel | null) => void;
};

export const useNetworkEquipmentCreateState = (): NetworkEquipmentCreate => {
  const { t } = useTranslation();

  const drawerType = useSelectDrawerType();
  const isVisible = drawerType[DrawerTypes.networkEquipmentCreate];
  const closeDrawer = useCloseDrawer();
  const [model, setModel] = useState<DeviceModel | null>(null);

  const { cleanControllerLocationId } = useControllerActions();

  const networkEquipmentSaveLabel = t('common:buttons.save');
  const networkEquipmentCreateLabel = t(
    'common:drawerTitle.NetworkEquipmentCreate',
  );

  const defaultValues: NetworkEquipmentCreateFormData = {
    locationId: '',
    name: '',
    ip: '',
    mac: '',
    subnetMask: '',
    gateway: '',
    port: 8080,
    timeZone: '+03:00',
    modelId: '',
    typeName: '',
    sipUri: '',
    hasSipUri: null,
    manufacturerName: '',
    segment: Segment.SIGMA,
    protocolIp: ProtocolIp.DHCP,
    ieee8021x: Ieee8021X.MAB,
    description: '',
    controlPage: '',
    telnetPort: '',
    firmware: '',
    serialNumber: '',
    inventoryNumber: '',
    sendNotifications: false,
    netInterface: false,
    netInterfaceInfo: [],
    disableMonitoring: false,
  };

  const methods = useForm({
    mode: 'onBlur',
    reValidateMode: 'onChange',
    resolver: yupResolver(networkEquipmentCreateSchema),
    defaultValues,
  });

  useEffect(() => {
    if (model) {
      methods.setValue('manufacturerName', model.manufacturer?.name || '');
      methods.setValue('typeName', model.type?.name || '');
      methods.setValue('hasSipUri', model.type?.hasSipUri);

      return;
    }

    methods.setValue('modelId', '');
    methods.resetField('manufacturerName');
    methods.resetField('typeName');
    methods.resetField('hasSipUri');
  }, [model]);

  useEffect(() => {
    if (isVisible) {
      cleanControllerLocationId();
      methods.reset(defaultValues);
    }
  }, [isVisible]);

  const netInterface = methods.watch('netInterface');

  useEffect(() => {
    if (!netInterface) {
      methods.setValue(NETWORK_EQUIPMENT_CREATE_FORM_KEY.netInterfaceInfo, []);
    }
  }, [netInterface]);

  useSyncControlPage(defaultValues.ip, methods);

  const { createNetworkEquipment, createNetworkEquipmentQueryStatus } =
    useEquipmentRepository();

  const [saveSecondaryInterface] =
    usePostApiV1SecondaryInterfaceValueMutation();

  const onDrawerClose = (): void => {
    methods.reset(defaultValues);
  };

  const submitHandler: SubmitHandler<NetworkEquipmentCreateFormData> = (
    values,
  ) => {
    saveNetWorkDevice(values);
  };

  const saveNetWorkDevice = async (values: NetworkEquipmentCreateFormData) => {
    const payload = normalizeSipUriForPayload(values);

    const networkDevice = await createNetworkEquipment(payload);

    const id = networkDevice?.id;

    if (id) {
      const secondaryInterfaceDto = toSecondaryInterfacePostDto(
        values.netInterfaceInfo,
        id,
        'network-device',
      );

      if (secondaryInterfaceDto) {
        await Promise.all(
          secondaryInterfaceDto.map(async (dto) => {
            return await saveSecondaryInterface(dto)
              .unwrap()
              .catch((e) => {
                enqueueSnackbar(e ?? '', { variant: 'error' });
              });
          }),
        );
      }
    }
  };

  useEffect(() => {
    if (createNetworkEquipmentQueryStatus === QueryStatus.fulfilled) {
      closeDrawer(DrawerTypes.networkEquipmentCreate);
      methods.reset(defaultValues);
    }
  }, [createNetworkEquipmentQueryStatus]);

  const { isValid, dirtyFields } = methods.formState;
  const isDirtyLocationId =
    methods.getValues().locationId !== defaultValues.locationId;
  const isDirtyFields = !Helpers.isEmpty(dirtyFields) || isDirtyLocationId;
  const isSaveButtonDisabled = !isDirtyFields || !isValid;

  return {
    networkEquipmentCreateLabel,
    networkEquipmentSaveLabel,
    methods,
    onDrawerClose,
    submitHandler,
    isSaveButtonDisabled,

    setModel,
  };
};