/* eslint-disable no-magic-numbers */
import React, { useState } from 'react';
import { useAppSelector } from '@/redux/hooks/useAppSelector';

import { mapEditToolsLayerImageObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
import { LayerImageObjectForm } from '@/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectForm.component';
import { currentModelIdSelector } from '@/redux/models/models.selectors';
import { layersActiveLayerSelector } from '@/redux/layers/layers.selectors';
import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { updateLayerImageObject } from '@/redux/layers/layers.thunks';
import { layerUpdateImage } from '@/redux/layers/layers.slice';
import { showToast } from '@/utils/showToast';
import { closeModal } from '@/redux/modal/modal.slice';
import { SerializedError } from '@reduxjs/toolkit';
import { useMapInstance } from '@/utils/context/mapInstanceContext';
import updateGlyph from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/Glyph/updateGlyph';
import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';

export const LayerImageObjectEditFactoryModal: React.FC = () => {
  const layerImageObject = useAppSelector(mapEditToolsLayerImageObjectSelector);
  const { mapInstance } = useMapInstance();

  const currentModelId = useAppSelector(currentModelIdSelector);
  const activeLayer = useAppSelector(layersActiveLayerSelector);
  const dispatch = useAppDispatch();

  const [selectedGlyph, setSelectedGlyph] = useState<number | null>(
    layerImageObject?.glyph || null,
  );
  const [file, setFile] = useState<File | null>(null);
  const [isSending, setIsSending] = useState<boolean>(false);

  const handleSubmit = async (): Promise<void> => {
    if (!layerImageObject || !activeLayer) {
      return;
    }
    setIsSending(true);

    try {
      let glyphId = selectedGlyph;
      if (file) {
        const data = await dispatch(addGlyph(file)).unwrap();
        if (!data) {
          return;
        }
        glyphId = data.id;
      }
      const layerImage = await dispatch(
        updateLayerImageObject({
          modelId: currentModelId,
          layerId: activeLayer,
          ...layerImageObject,
          glyph: glyphId,
        }),
      ).unwrap();
      if (layerImage) {
        dispatch(layerUpdateImage({ modelId: currentModelId, layerId: activeLayer, layerImage }));
        dispatch(mapEditToolsSetLayerObject(layerImage));
        updateGlyph(mapInstance, activeLayer, layerImage);
      }
      showToast({
        type: 'success',
        message: 'The layer image object has been successfully updated',
      });
      dispatch(closeModal());
    } catch (error) {
      const typedError = error as SerializedError;
      showToast({
        type: 'error',
        message: typedError.message || 'An error occurred while adding a new image object',
      });
    } finally {
      setIsSending(false);
    }
  };

  return (
    <LayerImageObjectForm
      file={file}
      selectedGlyph={selectedGlyph}
      isSending={isSending}
      onSubmit={handleSubmit}
      setFile={setFile}
      setSelectedGlyph={setSelectedGlyph}
    />
  );
};