import { useWixPatternsContainer } from '@wix/bex-core/react';
import { NestedTableStateBaseParams, NestedTableState } from '../state';
import { useOptionalCachedState } from './useOptionalCachedState';
import { ICollectionComponentState } from '../state/ICollectionComponentState';
import { CollectionState, FiltersMap, OptionalFiltersMap } from '@wix/bex-core';
import { WixPatternsRouterState } from '../state/WixPatternsRouterState';

export function useNestedTable<
  C extends string,
  F extends FiltersMap = OptionalFiltersMap,
>(params: NestedTableStateBaseParams<C, F>) {
  const container = useWixPatternsContainer();

  const getNestedCollection = (
    nestedTableState: NestedTableState,
    entity: any,
  ) => {
    // if the entity has parent (in the code we check hardcoded parentId, we need to support other props)
    if (typeof entity.parentId === 'string') {
      const parentKeyedItem = nestedTableState.nested.getKeyedItem(
        entity.parentId,
      );
      if (!parentKeyedItem) {
        return null;
      }

      const parentNodeState =
        parentKeyedItem.item.state.parentKeyToChildrenMap.get(entity.parentId);

      if (!parentNodeState) {
        return null;
      }

      return parentNodeState.collection;
    } else {
      return nestedTableState.nested.getKeyedItem(entity.id)?.item.state
        .collection;
    }
  };

  const getCollectionsToUpdate = (
    cachedState: ICollectionComponentState,
    entity: any,
  ) => {
    const nestedTableState = cachedState as NestedTableState;

    const nestedModeCollection = getNestedCollection(nestedTableState, entity);
    const flatModeCollection = nestedTableState.flat.keyedItems.find(
      // We need to get the keyItem, for now we use hardcoded id prop
      (item) => item.key === entity.id,
    )?.item.state.collection;

    return [nestedModeCollection, flatModeCollection].filter(
      Boolean,
    ) as CollectionState<any, any>[];
  };

  const shouldResetCache = ({
    router,
    uniqueId,
  }: {
    router: WixPatternsRouterState | null;
    uniqueId: string;
  }) => {
    const entity = router?.currentState?._updatedEntity;
    if (!entity) {
      return false;
    }
    const nestedTableState = router?.stateRefs.get(
      uniqueId,
    ) as NestedTableState;

    const newParentId = entity.parentId;
    const oldParentId = nestedTableState?.nested.getKeyedItem(entity.id)?.item
      .originalKeyedItem?.item.parentId;

    return newParentId !== oldParentId;
  };

  const state = useOptionalCachedState(
    () =>
      new NestedTableState<C, F>({
        ...params,
        container,
      }),
    {
      getCollectionsToUpdate,
      shouldResetCache,
    },
  );

  return state;
}
