import {
  CollectionState,
  FiltersMap,
  KeyedItem,
  QueryState,
  syncWithSharedQuery,
  TaskState,
} from '@wix/bex-core';
import { NestedTableLevelDescriptor } from './NestedTableLevelDescriptor';
import { createNestedOptimisticActions } from './createNestedOptimisticActions';
import { NestedTableFlatModeState } from './NestedTableFlatModeState';

export interface NestedTableFlatDataItem<
  C extends string,
  T,
  F extends FiltersMap,
> {
  state: NestedTableFlatModeSectionState<C, T, F>;
  originalKeyedItem: KeyedItem<T>;
}

export type NestedTableFlatKeyedItem<
  C extends string,
  T,
  F extends FiltersMap,
> = KeyedItem<NestedTableFlatDataItem<C, T, F>>;

export interface NestedTableFlatModeSectionStateParams<
  C extends string,
  T,
  F extends FiltersMap,
> {
  readonly levelDescriptor: NestedTableLevelDescriptor<C, T, F>;
  readonly query: QueryState<{}>;
  readonly flatModeState: NestedTableFlatModeState<C>;
}

export interface NestedTableSectionStatePublicAPI<T, F extends FiltersMap> {
  /**
   * The collection of the section
   * @overrideType [CollectionState](./?path=/story/common-state--collectionstate)
   */
  readonly collection: CollectionState<T, F>;
}

export class NestedTableFlatModeSectionState<
  C extends string,
  T,
  F extends FiltersMap,
> implements NestedTableSectionStatePublicAPI<T, F>
{
  collection;
  readonly levelDescriptor;
  readonly levelDescriptors = [] as NestedTableLevelDescriptor<C, T, F>[];

  readonly initTask = new TaskState();

  constructor(params: NestedTableFlatModeSectionStateParams<C, T, F>) {
    const { levelDescriptor } = params;
    this.levelDescriptor = levelDescriptor;

    const nestedOptimisticActionsState = {
      levelDescriptor: this.levelDescriptor,
    };

    const { collection, parentFilter } = levelDescriptor.createCollection(
      nestedOptimisticActionsState,
    );

    createNestedOptimisticActions(
      params.flatModeState.wrapper.container,
      collection,
      {
        ...nestedOptimisticActionsState,
        parentFilter,
      },
    );

    this.collection = collection;

    const { query: sharedQuery } = params;

    const { query } = collection;

    syncWithSharedQuery(query, sharedQuery);
  }

  get query() {
    return this.collection.query;
  }

  get columns() {
    return this.levelDescriptor.columns;
  }

  get renderMainColumn() {
    return this.levelDescriptor.renderMainColumn;
  }

  get breadcrumbs() {
    return this.levelDescriptor.breadcrumbs;
  }

  get expandable() {
    return this.levelDescriptor.expandable;
  }

  init() {
    const { collection } = this;
    const disposers = [collection._optimisticActions?.init()];

    return () => {
      disposers.forEach((d) => d?.());
    };
  }
}
