import { Utility } from '../../core/utility';

const INTERACTIVE_FIELDSET_UTIL_TARGET_SELECTOR = '.interactive-fieldset__target';

const INTERACTIVE_FIELDSET_INITIALIZED_CLASS = 'interactive-fieldset--initialized';
const INTERACTIVE_FIELDSET_CHILD_SELECTOR = 'input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled])';

@Utility({
  selector: '[uw-interactive-fieldset]',
})
export class InteractiveFieldset {

  _element;

  conditionalInput;
  conditionalValue;
  target;
  childInputs;

  constructor(element) {
    if (!element) {
      throw new Error('Interactive Fieldset utility cannot be setup without an element!');
    }

    this._element = element;

    if (this._element.classList.contains(INTERACTIVE_FIELDSET_INITIALIZED_CLASS)) {
      return false;
    }

    // param conditionalInput
    if (!this._element.dataset.conditionalInput) {
      throw new Error('Interactive Fieldset needs a selector for a conditional input!');
    }
    this.conditionalInput = document.querySelector('#' + this._element.dataset.conditionalInput);
    if (!this.conditionalInput) {
      // abort if form has no required inputs
      throw new Error('Couldn\'t find the conditional input. Aborting setup for interactive fieldset.');
    }

    // param conditionalValue
    if (!this._element.dataset.conditionalValue && !this._isCheckbox()) {
      throw new Error('Interactive Fieldset needs a conditional value!');
    }
    this.conditionalValue = this._element.dataset.conditionalValue;

    this.target = this._element.closest(INTERACTIVE_FIELDSET_UTIL_TARGET_SELECTOR);
    if (!this.target || this._element.matches(INTERACTIVE_FIELDSET_UTIL_TARGET_SELECTOR)) {
      this.target = this._element;
    }

    this.childInputs = Array.from(this._element.querySelectorAll(INTERACTIVE_FIELDSET_CHILD_SELECTOR));

    // add event listener
    const observer = new MutationObserver(() => this._updateVisibility());
    observer.observe(this.conditionalInput, { attributes: true, attributeFilter: ['disabled'] });
    this.conditionalInput.addEventListener('input', () => this._updateVisibility());

    // initial visibility update
    this._updateVisibility();

    // mark as initialized
    this._element.classList.add(INTERACTIVE_FIELDSET_INITIALIZED_CLASS);

  }

  destroy() {
    // TODO
  }

  _updateVisibility() {
    const active = this._matchesConditionalValue() && !this.conditionalInput.disabled;

    this.target.classList.toggle('hidden', !active);

    this.childInputs.forEach((el) => {
      el.disabled = !active;

      // disable input for flatpickrs added input as well if exists
      if (el._flatpickr) {
        el._flatpickr.altInput.disabled = !active;
      }
    });
  }

  _matchesConditionalValue() {
    if (this._isCheckbox()) {
      return this.conditionalInput.checked === true;
    }

    return this.conditionalInput.value === this.conditionalValue;
  }

  _isCheckbox() {
    return this.conditionalInput.getAttribute('type') === 'checkbox';
  }
}
