import { addResizeObserver } from '@wix/bex-core';
import type { ToolbarResponsiveState } from './ToolbarResponsiveState';
import type { TabsFilterState } from '../../components/TabsFilter/TabsFilterState';
import type { FiltersMap } from '@wix/bex-core';
import { ToolbarMode } from '../../components/CollectionToolbar/toolbarModeUtils';

export interface ToolbarLeftGroupStateParams<T, F extends FiltersMap> {
  readonly responsive: ToolbarResponsiveState;
  readonly mode: ToolbarMode;
  readonly minWidth: number;
  readonly getTabsState?: () => TabsFilterState<T, F> | null | undefined;
}

export class ToolbarLeftGroupState<T, F extends FiltersMap> {
  private readonly _responsive: ToolbarResponsiveState;
  private readonly _getTabsState?: () =>
    | TabsFilterState<T, F>
    | null
    | undefined;

  private _element: HTMLElement | null = null;
  private _tabsWidthTimeout: ReturnType<typeof setTimeout> | null = null;

  readonly mode: ToolbarMode;
  readonly minWidth: number;

  constructor(params: ToolbarLeftGroupStateParams<T, F>) {
    this._responsive = params.responsive;
    this.mode = params.mode;
    this.minWidth = params.minWidth;
    this._getTabsState = params.getTabsState;
  }

  getExcessWidth(): number {
    if (!this._element) {
      return 0;
    }
    return Math.max(0, this._element.clientWidth - this.minWidth);
  }

  init(element: HTMLElement | null | undefined): () => void {
    this._element = null;

    if (!element) {
      return () => {};
    }

    this._element = element;
    const disposer = addResizeObserver(element, this._handleResize);

    return () => {
      disposer?.();
      if (this._tabsWidthTimeout) {
        clearTimeout(this._tabsWidthTimeout);
        this._tabsWidthTimeout = null;
      }
      this._element = null;
    };
  }

  private _handleResize = () => {
    const element = this._element;
    if (!element) {
      return;
    }

    if (this.mode === 'tabs') {
      if (this._tabsWidthTimeout) {
        clearTimeout(this._tabsWidthTimeout);
      }
      this._tabsWidthTimeout = setTimeout(() => {
        this._tabsWidthTimeout = null;
        if (!this._element) return;
        const tabsState = this._getTabsState?.();
        tabsState?.responsive.setAvailableWidth(this._element.clientWidth);
      }, 300);
    }

    this._responsive._scheduleRecompute();
  };
}
