import { injectStyle } from '@descope-ui/common/components-helpers';
import { createBaseClass } from '../../baseClasses/createBaseClass';
import { compose } from '../../helpers';
import { getComponentName } from '../../helpers/componentHelpers';
import { componentNameValidationMixin, createStyleMixin, draggableMixin } from '../../mixins';
import { createDynamicDataMixin } from '../../mixins/createDynamicDataMixin';
import { CheckboxClass } from '../boolean-fields/descope-checkbox/CheckboxClass';
import { SwitchToggleClass } from '../boolean-fields/descope-switch-toggle/SwitchToggleClass';

export const componentName = getComponentName('scopes-list');
const variants = ['checkbox', 'switch'];

const itemRenderer = ({ id, desc, required = false }, _, ref) => {
  const ComponentClass = ref.variant === 'checkbox' ? CheckboxClass : SwitchToggleClass;

  return `
    <${ComponentClass.componentName}
      bordered="true"
      size=${ref.size}
      label="${desc}"
      data-id="${id}"
      readonly="${required || ref.isReadOnly}"
      required="${required}"
      checked="true"
    ></${ComponentClass.componentName}>
`;
};

class RawScopesList extends createBaseClass({ componentName, baseSelector: 'div' }) {
  constructor() {
    super();

    this.attachShadow({ mode: 'open' }).innerHTML = `
    <div></div>
		`;

    injectStyle(
      `
      :host {
        display: inline-flex;
      }

      div {
        display: flex;
        flex-direction: column;
      }
        `,
      this
    );
  }

  get isReadOnly() {
    return this.getAttribute('readonly') === 'true';
  }

  get size() {
    return this.getAttribute('size') || 'sm';
  }

  #getChildNodes() {
    return Array.from(this.shadowRoot.querySelector('div').children);
  }

  reportValidity() {
    this.checkValidity();
  }

  checkValidity() {
    return this.data.every((item) => !item.required || this.value.includes(item.id));
  }

  get value() {
    return this.#getChildNodes()
      .filter((node) => node.checked)
      .map((node) => node.getAttribute('data-id'));
  }

  set value(val = []) {
    this.#getChildNodes().forEach((node) => {
      node.checked = val.includes(node.getAttribute('data-id'));
    });
  }

  get variant() {
    const variant = this.getAttribute('variant');

    return variants.includes(variant) ? variant : variants[0];
  }
}

export const ScopesListClass = compose(
  createStyleMixin({
    mappings: {
      hostWidth: { selector: () => ':host', property: 'width' },
      hostDirection: [
        { selector: () => ':host', property: 'direction' },
        {
          selector: () => CheckboxClass.componentName,
          property: CheckboxClass.cssVarList.hostDirection,
        },
        {
          selector: () => SwitchToggleClass.componentName,
          property: SwitchToggleClass.cssVarList.hostDirection,
        },
      ],
      gap: { selector: () => 'div', property: 'gap' },
      requiredInputBorderColor: [
        {
          selector: `${CheckboxClass.componentName}[required="true"]`,
          property: CheckboxClass.cssVarList.inputBorderColor,
        },
        {
          selector: `${SwitchToggleClass.componentName}[required="true"]`,
          property: SwitchToggleClass.cssVarList.inputBorderColor,
        },
      ],
      requiredInputValueTextColor: [
        {
          selector: `${CheckboxClass.componentName}[required="true"]`,
          property: CheckboxClass.cssVarList.inputValueTextColor,
        },
        {
          selector: `${SwitchToggleClass.componentName}[required="true"]`,
          property: SwitchToggleClass.cssVarList.knobColor,
        },
      ],
    },
  }),
  createDynamicDataMixin({ itemRenderer, rerenderAttrsList: ['size', 'variant'] }),
  draggableMixin,
  componentNameValidationMixin
)(RawScopesList);
