import { ReactElement, useEffect, useState } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { runInAction } from 'mobx';
import { GridBaseState, gridSizePresets, LayoutType } from '../../state';
import { AddItemProps } from '@wix/design-system';
import { useScrollableContentContext } from '../../providers';
import { GridDragAndDrop } from '../GridDragAndDropDndKit/GridDragAndDrop';
import { usePageContext } from '@wix/bex-core/react';
import { DragAndDropCancel } from '../DragAndDrop';
import type { Preset } from './Grid.types';

export interface UseGridBaseSyncPropsParams<T, F extends FiltersMap> {
  state: GridBaseState<T, F>;
  preset?: Preset;
  range?: { start: number; length: number };
  renderAddItem?: () => ReactElement<AddItemProps>;
  dragAndDrop?: typeof GridDragAndDrop;
  imagePlacement?: 'side' | 'top';
  layoutType?: LayoutType;
  dragAndDropCancel?: DragAndDropCancel<T, F>;
}

export function useGridBaseSyncProps<T, F extends FiltersMap>(
  props: UseGridBaseSyncPropsParams<T, F>,
) {
  const {
    state,
    renderAddItem,
    preset,
    dragAndDrop,
    range,
    layoutType,
    imagePlacement,
  } = props;
  const { scrollableContentRef } = useScrollableContentContext();
  const { modalsContainerRef } = usePageContext();

  useState(() => {
    props.dragAndDrop?.setStateObject({
      state,
      modalsContainerRef,
    });
  });

  const collectionDragAndDropState = state.collectionDragAndDropState;
  if (collectionDragAndDropState) {
    collectionDragAndDropState.dragAndDropCancel = props.dragAndDropCancel;
  }

  useEffect(() => {
    const { collection } = state;

    const scrollableContent = scrollableContentRef?.current;

    if (scrollableContent) {
      collection.scrollableContent = scrollableContent;
    }

    return () => {
      collection.scrollableContent = null;
    };
  }, []);

  useEffect(() => {
    runInAction(() => {
      state.trailingItemsCount = [renderAddItem].filter(Boolean).length;
    });
  }, [renderAddItem]);

  useEffect(() => {
    runInAction(() => {
      state._localLimit = range?.length;
      state._localStart = range?.start ?? 0;
    });
  }, [range]);

  useEffect(() => {
    runInAction(() => {
      state.preset = preset ?? 'title';
    });
  }, [preset]);

  useEffect(() => {
    runInAction(() => {
      state._draggable = dragAndDrop ? 'draggable' : 'none';
    });
  }, [dragAndDrop]);

  useEffect(() => {
    runInAction(() => {
      state.layoutType = layoutType ?? 'grid';
    });
  }, [layoutType]);

  useEffect(() => {
    runInAction(() => {
      const sizePreset = imagePlacement
        ? gridSizePresets[imagePlacement]
        : undefined;

      if (!sizePreset) {
        return;
      }

      state._sizePreset = sizePreset;
    });
  }, [imagePlacement]);
}
