import { addEventListener } from '@wix/bex-core/util';
import { TypedEmitter } from '@wix/bex-core/events';
import {
  CollectionState,
  Filter,
  FilterEventOptions,
  FiltersMap,
  withoutDefaults,
} from '@wix/bex-core';
import { cairoFilterToggled } from '@wix/bex-core/bi';
import { EventEmitter } from 'events';
import { action } from 'mobx';
import { CollectionToolbarFiltersState } from '../CollectionToolbarFilters/CollectionToolbarFiltersState';

export interface CollectionFilterStateParams<T, F extends FiltersMap, V> {
  readonly filter: Filter<V>;
  readonly toolbarFiltersState: CollectionToolbarFiltersState<T, F>;
  readonly location?: 'toolbar' | 'panel' | 'modal';
}

export class CollectionFilterState<T, F extends FiltersMap, V> {
  readonly filter;
  readonly toolbarFiltersState;
  readonly location;

  readonly events = new EventEmitter() as TypedEmitter<{
    fetch: () => () => unknown;
  }>;

  constructor(params: CollectionFilterStateParams<T, F, V>) {
    this.filter = params.filter;
    this.toolbarFiltersState = params.toolbarFiltersState;
    this.location = params.location;
  }

  _reportFilterToggleBiOnNextResult(
    collection: CollectionState<unknown, {}>,
    params: FilterEventOptions | undefined,
  ) {
    const { filter, toolbarFiltersState, location, events } = this;
    const { toolbar } = toolbarFiltersState;

    const onFetch = () => {
      events.off('fetch', onFetch);
      // const currentFilters = ??? remember filters before query result?
      return action(() => {
        const { actionType, clickedValueKey } = params ?? {};
        toolbar.reportBi(
          withoutDefaults(cairoFilterToggled)({
            ...toolbar._commonDynamicBiParams(),
            ...collection._commonDynamicBiParams(),
            origin: location,
            filterValue: clickedValueKey,
            filterName: filter.name,
            actionType,
            numFiltersActive: toolbar.collection.query.activeFiltersCount,
            filteredListSize: toolbar.collection.result.total,
            isCustomField: !!filter.isCustomField,
          }),
        );
      });
    };

    events.on('fetch', onFetch);
  }

  init() {
    const { filter, toolbarFiltersState } = this;
    const { toolbar } = toolbarFiltersState;
    const {
      multi: { collections },
    } = toolbar;

    const disposers = [
      ...collections
        .filter(({ query: { filtersArray } }) =>
          filtersArray.includes(filter as Filter<unknown>),
        )
        .flatMap((collection) => [
          addEventListener(filter.events, 'beforeRefresh', (params) => {
            this._reportFilterToggleBiOnNextResult(collection, params);
          }),

          addEventListener(collection.emitter, 'fetch', () => {
            const ls = this.events.listeners('fetch').map((l) => l());
            return () => {
              ls.forEach((l) => l());
            };
          }),
        ]),
    ];

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