import { action, computed, makeObservable, observable } from 'mobx';
import { addResizeObserver, WixPatternsContainer } from '@wix/bex-core';

export interface HorizontalSpaceAvailableStateParams {
  state: {
    container: WixPatternsContainer;
    responsiveDisabled: boolean | undefined;
  };
}

export class HorizontalSpaceAvailableState {
  readonly _syncThrottled;

  readonly container;
  readonly _state;

  _element?: Element | null | undefined;
  _child?: Element | null | undefined;

  _directChildClientWidth = 0;
  _clientWidth = 0;

  constructor(params: HorizontalSpaceAvailableStateParams) {
    const { state } = params;
    this.container = state.container;
    this._state = state;

    makeObservable(this, {
      _sync: action.bound,
      _directChildClientWidth: observable.ref,
      _clientWidth: observable.ref,
      available: computed,
    });

    this._syncThrottled = this.container.lodash.throttle(() => {
      window.requestAnimationFrame(this._sync);
    }, 200);
  }

  _sync() {
    const { _element, _child } = this;

    if (!_element || !_child) {
      return;
    }

    this._clientWidth = _element.clientWidth;
    this._directChildClientWidth = _child.scrollWidth;
  }

  get available() {
    return this._clientWidth - this._directChildClientWidth;
  }

  initLayout() {
    const { _element, _child, _state } = this;

    if (_state.responsiveDisabled) {
      return;
    }

    if (!_element || !_child) {
      return;
    }

    this._sync();
  }

  init() {
    const { _element, _child, _state } = this;

    if (_state.responsiveDisabled) {
      return;
    }

    if (!_element || !_child) {
      return;
    }

    const disposers = [addResizeObserver(_child, this._syncThrottled)];

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