import {
  CollectionState,
  FiltersMap,
  WixPatternsContainer,
} from '@wix/bex-core';
import {
  ToolbarCollectionState,
  ToolbarCollectionStateParamsInitParams,
} from './ToolbarCollectionState';
import { GridBaseState } from './GridBaseState';
import { GridSectionsState } from '../components/GridSections/GridSectionsState';
import { ICollectionComponentState } from './ICollectionComponentState';
import { GridSizePreset } from './gridSizePresets';
import { makeObservable, observable } from 'mobx';

export interface GridStateParams<T, F extends FiltersMap> {
  readonly collection: CollectionState<T, F>;
  readonly container: WixPatternsContainer;
  readonly toolbar?: ToolbarCollectionState<T, F>;
}

export interface GridStateInitParams
  extends ToolbarCollectionStateParamsInitParams {}

export interface GridStatePublicAPI<T, F extends FiltersMap> {
  /**
   * Underlying [CollectionState](./?path=/story/common-state--collectionstate) instance
   * @external
   */
  readonly collection: CollectionState<T, F>;
  /**
   * Underlying [ToolbarCollectionState](./?path=/story/common-state--toolbarcollectionstate) instance
   * @external
   */
  readonly toolbar: ToolbarCollectionState<T, F>;

  /**
   * Reset active filters & sorting and adds new items to the collection.
   * @param items - new items to add to the collection
   * @external
   */
  onAddItemActionComplete(items: T[]): void;
}

export class GridState<T, F extends FiltersMap>
  implements GridStatePublicAPI<T, F>, ICollectionComponentState
{
  readonly toolbar;
  readonly container;
  readonly collection;

  readonly _subGrids = [] as GridBaseState<T, F>[];
  _sizePreset = undefined as GridSizePreset | undefined;
  _sections?: GridSectionsState<T, F>;

  constructor(params: GridStateParams<T, F>) {
    this.container = params.container;
    this.collection = params.collection;

    this.toolbar =
      params.toolbar ??
      new ToolbarCollectionState({
        collection: params.collection,
        container: params.container,
        componentType: 'Grid',
      });

    makeObservable(this, {
      _sizePreset: observable.ref,
    });
  }

  init(params: GridStateInitParams) {
    const disposers = [this.toolbar.init(params)];

    return () => {
      for (const disposer of disposers) {
        disposer();
      }
    };
  }

  onAddItemActionComplete = async (items: T[]) => {
    return this.toolbar.onAddItemActionComplete(items);
  };
}
