import { createBaseInputClass } from '../../../baseClasses/createBaseInputClass';
import { forwardAttrs, getComponentName, syncAttrs } from '../../../helpers/componentHelpers';

export const componentName = getComponentName('boolean-field-internal');

const forwardAttributes = ['disabled', 'invalid', 'readonly'];

const BaseInputClass = createBaseInputClass({ componentName, baseSelector: 'div' });

class BooleanInputInternal extends BaseInputClass {
  static get observedAttributes() {
    return ['readonly', 'label'];
  }

  constructor() {
    super();
    this.innerHTML = `
			<div class="wrapper">
				<vaadin-checkbox>
					<descope-enriched-text link-target-blank="true" class="label-content" slot="label"></descope-enriched-text>
				</vaadin-checkbox>
			</div>
		`;
    this.wrapperEle = this.querySelector('div');
    this.checkbox = this.querySelector('vaadin-checkbox');
    this.labelContent = this.querySelector('.label-content');
  }

  get value() {
    return this.checkbox?.checked;
  }

  set value(val) {
    this.checkbox.checked = val;
  }

  get checked() {
    return this.value;
  }

  set checked(val) {
    this.value = val;
  }

  init() {
    this.addEventListener('focus', (e) => {
      if (e.isTrusted) {
        this.checkbox.focus();
      }
    });
    super.init?.();

    forwardAttrs(this, this.checkbox, { includeAttrs: forwardAttributes });
    syncAttrs(this, this.checkbox, { includeAttrs: ['checked'] });

    // Handle label click to toggle checkbox
    this.labelContent.addEventListener('click', (e) => {
      if (!this.hasAttribute('disabled') && !this.hasAttribute('readonly')) {
        this.checkbox.click();
      }
    });

    // we need it in order to set the focus ring and trigger validation on descope-checkbox
    this.handleFocusEventsDispatching([this.checkbox]);
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    super.attributeChangedCallback?.(attrName, oldValue, newValue);

    if (attrName === 'readonly') {
      this.onReadOnlyChange(newValue !== null);
    }

    if (attrName === 'label') {
      this.onLabelChange();
    }
  }

  onLabelChange() {
    const labelValue = this.getAttribute('label');
    if (labelValue) {
      this.labelContent.textContent = labelValue;
    } else {
      this.labelContent.textContent = '';
    }
  }

  onReadOnlyChange(val) {
    this.baseElement.setAttribute('inert', val);
  }

  getValidity() {
    if (this.isRequired && !this.value) {
      return { valueMissing: true };
    }
    return {};
  }
}

export default BooleanInputInternal;
