import { observeAttributes, observeChildren } from '../../helpers/componentHelpers';
import {
  resetInputLabelPosition,
  resetInputCursor,
  resetInputFieldDefaultWidth,
} from '../../helpers/themeHelpers/resetHelpers';

export const buttonSelectionGroupBaseMixin = (superclass) =>
  class ButtonSelectionGroupMixinClass extends superclass {
    #renderItem = ({ value, label }) =>
      `<descope-button-selection-group-item value="${value}">${label}</descope-button-selection-group-item>`;

    #data;

    get renderItem() {
      return this.#renderItem;
    }

    set renderItem(renderFn) {
      this.#renderItem = renderFn;
      this.renderItems();
    }

    get size() {
      return this.inputElement?.size;
    }

    get data() {
      if (this.#data) return this.#data;

      const dataAttr = this.getAttribute('data');

      if (dataAttr) {
        try {
          const data = JSON.parse(dataAttr);
          if (this.isValidDataType(data)) {
            return data;
          }
        } catch (e) {
          // eslint-disable-next-line no-console
          console.error('could not parse data string from attribute "data" - ', e.message);
        }
      }

      return [];
    }

    set data(data) {
      if (this.isValidDataType(data)) {
        this.#data = data;
        this.renderItems();
      }
    }

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

      return isValid;
    }

    getItemsTemplate() {
      return this.data?.reduce?.((acc, item) => acc + (this.renderItem?.(item || {}) || ''), '');
    }

    renderItems() {
      const template = this.getItemsTemplate();
      if (template) this.innerHTML = template;
    }

    init() {
      super.init?.();

      this.renderItems();

      observeAttributes(this, this.renderItems.bind(this), { includeAttrs: ['data'] });

      // we want new items to get the size
      observeChildren(this, ({ addedNodes }) => {
        addedNodes.forEach((node) => {
          node.setAttribute('size', this.size);
        });
      });
    }
  };

const { host, label, requiredIndicator, internalWrapper, errorMessage } = {
  host: { selector: () => ':host' },
  label: { selector: '::part(label)' },
  requiredIndicator: { selector: '[required]::part(required-indicator)::after' },
  internalWrapper: { selector: () => ':host [part="internal-component"] slot' },
  errorMessage: { selector: '::part(error-message)' },
};

export const buttonSelectionGroupMappings = {
  hostWidth: { ...host, property: 'width' },
  hostDirection: { ...host, property: 'direction' },
  fontFamily: host,
  labelTextColor: [
    { ...label, property: 'color' },
    { ...requiredIndicator, property: 'color' },
  ],
  labelRequiredIndicator: { ...requiredIndicator, property: 'content' },
  errorMessageTextColor: { ...errorMessage, property: 'color' },
  errorMessageIcon: { ...errorMessage, property: 'background-image' },
  errorMessageIconSize: { ...errorMessage, property: 'background-size' },
  errorMessageIconPadding: { ...errorMessage, property: 'padding-inline-start' },
  errorMessageIconRepeat: { ...errorMessage, property: 'background-repeat' },
  errorMessageIconPosition: { ...errorMessage, property: 'background-position' },
  errorMessageFontSize: { ...errorMessage, property: 'font-size' },
  itemsSpacing: { ...internalWrapper, property: 'gap' },
};

export const buttonSelectionGroupStyles = `
			:host {
				display: inline-flex;
				max-width: 100%;
			}
			${resetInputFieldDefaultWidth()}
			:host::after {
				background-color: transparent;
			}
			:host::part(input-field)::after {
				background-color: transparent;
			}

      [part="internal-component"] {
				-webkit-mask-image: none;
				padding: 0;
				width: 100%;
				height: 100%;
        display: inline-block;
				min-height: initial;
			}

      [part="internal-component"] slot {
        box-sizing: border-box;
        width: 100%;
        display: flex;
        flex-wrap: wrap;
			}

			vaadin-text-field::part(input-field) {
				background-color: transparent;
				padding: 0;
				overflow: hidden;
				-webkit-mask-image: none;
			}

			vaadin-text-field {
				margin: 0;
				padding: 0;
				width: 100%
			}

			vaadin-text-field::before {
				height: 0;
			}

			vaadin-text-field[readonly] > input:placeholder-shown {
				opacity: 1;
			}

			vaadin-text-field[readonly]::part(input-field)::after {
				border: 0 solid;
			}

			vaadin-text-field::part(input-field) {
				box-shadow: none;
			}

      ${resetInputLabelPosition('vaadin-text-field')}
			${resetInputCursor('vaadin-text-field')}
    `;
