import { compose } from '../../helpers';
import { getComponentName, observeChildren } from '../../helpers/componentHelpers';
import {
  componentNameValidationMixin,
  createProxy,
  createStyleMixin,
  proxyInputMixin,
} from '../../mixins';

export const componentName = getComponentName('radio-button');

const customMixin = (superclass) =>
  class CustomMixin extends superclass {
    constructor() {
      super();

      this.baseElement.checkValidity = () => {};
    }

    init() {
      // we are forwarding vaadin checked-changed event
      this.baseElement.addEventListener('checked-changed', (e) => {
        this.dispatchEvent(
          new CustomEvent(
            'checked-changed',
            { detail: e.detail },
            { bubbles: true, composed: true }
          )
        );
      });

      super.init?.();

      observeChildren(this, this.renderLabel.bind(this));
    }

    renderLabel() {
      this.baseElement.setAttribute('label', this.textContent);
    }

    get value() {
      return this.getAttribute('value');
    }
  };

export const RadioButtonClass = compose(
  createStyleMixin({
    mappings: {
      cursor: [{}, { selector: 'label' }],
      fontSize: [{ selector: 'label' }, {}],
      labelTextColor: { selector: 'label', property: 'color' },
      fontFamily: { selector: 'label' },
      radioSize: [
        { selector: '::part(radio)', property: 'height' },
        { selector: '::part(radio)', property: 'width' },
      ],
      radioBackgroundColor: { selector: '::part(radio)', property: 'background-color' },
      radioMargin: { selector: '::part(radio)', property: 'margin' },
      radioCheckedSize: { selector: '::part(radio)::after', property: 'border-width' },
      radioCheckedColor: { selector: '::part(radio)::after', property: 'border-color' },
      radioBorderColor: { selector: '::part(radio)', property: 'border-color', fallback: 'none' },
      radioBorderWidth: { selector: '::part(radio)', property: 'border-width', fallback: 0 },
      radioBorderStyle: { selector: '::part(radio)', property: 'border-style', fallback: 'solid' },
    },
  }),
  proxyInputMixin({ proxyProps: ['setSelectionRange'] }),
  componentNameValidationMixin,
  customMixin
)(
  createProxy({
    slots: [''],
    wrappedEleName: 'vaadin-radio-button',
    excludeAttrsSync: ['tabindex', 'data', 'style'],
    includeForwardProps: ['checked', 'name', 'disabled'],
    componentName,
  })
);
