import { getComponentName } from '../../../helpers/componentHelpers';
import { createBaseButtonSelectionGroupInternalClass } from '../createBaseButtonSelectionGroupInternalClass';

export const componentName = getComponentName('button-multi-selection-group-internal');

export class ButtonMultiSelectionGroupInternalClass extends createBaseButtonSelectionGroupInternalClass(
  componentName
) {
  #getSelectedNodes() {
    return this.items.filter((item) => item.hasAttribute('selected'));
  }

  onClick(e) {
    if (e.target !== e.currentTarget) {
      if (this.#getSelectedNodes().includes(e.target)) {
        e.target.removeAttribute('selected');
      } else {
        e.target.setAttribute('selected', 'true');
      }
      this.dispatchChange();
    }
  }

  get value() {
    return this.#getSelectedNodes().map((node) => node.value);
  }

  set value(values) {
    this.items.forEach((item) => {
      if (values.includes(item.value)) {
        item.setAttribute('selected', 'true');
      } else {
        item.removeAttribute('selected');
      }
    });
  }

  get minItemsSelection() {
    return parseInt(this.getAttribute('min-items-selection'), 10) || 0;
  }

  get maxItemsSelection() {
    return parseInt(this.getAttribute('max-items-selection'), 10) || 0;
  }

  #isValidDataType(data) {
    const isValid = Array.isArray(data);
    if (!isValid) {
      // eslint-disable-next-line no-console
      console.error('default-values must be an array, received:', data);
    }

    return isValid;
  }

  get defaultValues() {
    const defaultValuesAttr = this.getAttribute('default-values');
    if (defaultValuesAttr) {
      try {
        const defaultValues = JSON.parse(defaultValuesAttr);
        if (this.#isValidDataType(defaultValues)) {
          return defaultValues;
        }
      } catch (e) {
        // eslint-disable-next-line no-console
        console.error('could not parse data string from attribute "default-values" -', e.message);
      }
    }
    return [];
  }

  setDefaultValues() {
    // we want to defer this action until all attributes are synced
    setTimeout(() => {
      if (this.defaultValues) {
        this.value = this.defaultValues;
        this.setCustomValidity();
      }
    });
  }

  getValidity() {
    if (this.isRequired && !this.value.length) {
      return { valueMissing: true };
    }
    // If the field is not required, no minimum selection can be set
    if (this.isRequired && this.minItemsSelection && this.value.length < this.minItemsSelection) {
      return {
        rangeUnderflow: true,
      };
    }
    if (this.maxItemsSelection && this.value.length > this.maxItemsSelection) {
      return {
        rangeOverflow: true,
      };
    }
    return {};
  }

  init() {
    super.init();

    this.setDefaultValues();

    this.querySelector('slot').addEventListener('click', this.onClick.bind(this));
  }
}
