import { uniqueId, isBoolean } from 'lodash-es';
import { looseEqual } from '../../../../vendor/bootstrap-vue/src/utils/loose-equal';
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';

var script = {
  name: 'GlFormRadio',
  inject: {
    getGroup: {
      // When we remove BFormRadioGroup from GlFormRadioGroup, we can rename
      // the `getBvRadioGroup` provide to `getRadioGroup`.
      from: 'getBvRadioGroup',
      default: () => () => null
    }
  },
  inheritAttrs: false,
  model: {
    prop: 'checked',
    event: 'input'
  },
  props: {
    /**
     * Used to set the `id` attribute on the rendered content, and used as the base to generate any additional element IDs as needed.
     */
    id: {
      type: String,
      required: false,
      default: undefined
    },
    /**
     * The current value of the radio. When bound to multiple radios, this is the value of the currently selected radio.
     */
    checked: {
      // `checked` prop can be any type
      type: undefined,
      required: false,
      default: null
    },
    /**
     * When set to `true`, disables the component's functionality and places it in a disabled state.
     */
    disabled: {
      type: Boolean,
      required: false,
      default: false
    },
    /**
     * Sets the value of the `name` attribute on the form control.
     */
    name: {
      type: String,
      required: false,
      default: undefined
    },
    /**
     * Adds the `required` attribute to the form control.
     */
    required: {
      type: Boolean,
      required: false,
      default: false
    },
    /**
     * Controls the validation state appearance of the component. `true` for valid, `false` for invalid, or `null` for no validation state.
     */
    state: {
      type: Boolean,
      required: false,
      default: null
    },
    /**
     * Value returned when this radio is selected.
     */
    value: {
      // `value` prop can be any type
      type: undefined,
      required: false,
      default: true
    }
  },
  data() {
    const group = this.getGroup();
    return {
      internalId: this.id ? this.id : uniqueId('gitlab_ui_radio_'),
      localChecked: group ? group.checked : this.checked
    };
  },
  computed: {
    computedLocalChecked: {
      get() {
        return this.isGroup ? this.group.localChecked : this.localChecked;
      },
      set(value) {
        if (this.isGroup) {
          this.group.localChecked = value;
        } else {
          this.localChecked = value;
        }
      }
    },
    group() {
      return this.getGroup();
    },
    isGroup() {
      // Is this radio a child of radio-group?
      return Boolean(this.group);
    },
    computedState() {
      if (this.isGroup) return this.group.computedState;
      return isBoolean(this.state) ? this.state : null;
    },
    stateClass() {
      if (this.computedState === true) return 'is-valid';
      if (this.computedState === false) return 'is-invalid';
      return null;
    },
    computedAriaInvalid() {
      return this.computedState === false ? 'true' : null;
    },
    isChecked() {
      return looseEqual(this.computedLocalChecked, this.value);
    },
    isDisabled() {
      // Child can be disabled while parent isn't, but is always disabled if group is
      return this.isGroup ? this.group.disabled || this.disabled : this.disabled;
    },
    isRequired() {
      // Required only works when a name is provided for the input(s)
      // Child can only be required when parent is
      // Groups will always have a name (either user supplied or auto generated)
      return this.computedName && (this.isGroup ? this.group.required : this.required);
    },
    computedName() {
      // Group name preferred over local name
      return (this.isGroup ? this.group.groupName : this.name) || null;
    },
    computedAttrs() {
      const {
        isDisabled: disabled,
        isRequired: required,
        value,
        isChecked: checked
      } = this;
      return {
        ...this.$attrs,
        id: this.internalId,
        name: this.computedName,
        disabled,
        required,
        value,
        checked,
        'aria-required': required || null,
        'aria-invalid': this.computedAriaInvalid
      };
    }
  },
  watch: {
    checked() {
      this.checkedWatcher(...arguments);
    },
    computedLocalChecked() {
      this.computedLocalCheckedWatcher(...arguments);
    }
  },
  methods: {
    checkedWatcher(newValue) {
      if (!looseEqual(newValue, this.computedLocalChecked)) {
        this.computedLocalChecked = newValue;
      }
    },
    computedLocalCheckedWatcher(newValue, oldValue) {
      if (!looseEqual(newValue, oldValue)) {
        /**
         * Emitted when the selected value is changed
         *
         * @event input
         * @type {boolean} current selected value of radio group
         */
        this.$emit('input', newValue);
      }
    },
    handleChange() {
      const {
        value
      } = this;

      // Update `computedLocalChecked`
      this.computedLocalChecked = value;

      // Fire events in a `$nextTick()` to ensure the `v-model` is updated
      this.$nextTick(() => {
        /**
         * Emitted when the selected value is changed due to user interaction
         *
         * @event change
         * @type {boolean} current selected value of radio group
         */
        this.$emit('change', value);

        // If this is a child of a group, we emit a change event on it as well
        if (this.isGroup) {
          /**
           * Emitted when the selected value is changed due to user interaction
           *
           * @event change
           * @type {boolean} current selected value of radio group
           */
          this.group.$emit('change', value);
        }
      });
    },
    focus() {
      if (!this.disabled) {
        var _this$$refs$input;
        (_this$$refs$input = this.$refs.input) === null || _this$$refs$input === void 0 ? void 0 : _this$$refs$input.focus();
      }
    },
    blur() {
      if (!this.disabled) {
        var _this$$refs$input2;
        (_this$$refs$input2 = this.$refs.input) === null || _this$$refs$input2 === void 0 ? void 0 : _this$$refs$input2.blur();
      }
    }
  }
};

/* script */
const __vue_script__ = script;

/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-form-radio custom-radio custom-control"},[_c('input',_vm._b({key:"input",ref:"input",staticClass:"custom-control-input",class:_vm.stateClass,attrs:{"type":"radio"},on:{"change":_vm.handleChange}},'input',_vm.computedAttrs,false)),_vm._v(" "),_c('label',{staticClass:"custom-control-label",attrs:{"for":_vm.internalId}},[_vm._t("default"),_vm._v(" "),(Boolean(_vm.$scopedSlots.help))?_c('p',{staticClass:"help-text"},[_vm._t("help")],2):_vm._e()],2)])};
var __vue_staticRenderFns__ = [];

  /* style */
  const __vue_inject_styles__ = undefined;
  /* scoped */
  const __vue_scope_id__ = undefined;
  /* module identifier */
  const __vue_module_identifier__ = undefined;
  /* functional template */
  const __vue_is_functional_template__ = false;
  /* style inject */
  
  /* style inject SSR */
  
  /* style inject shadow dom */
  

  
  const __vue_component__ = /*#__PURE__*/__vue_normalize__(
    { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
    __vue_inject_styles__,
    __vue_script__,
    __vue_scope_id__,
    __vue_is_functional_template__,
    __vue_module_identifier__,
    false,
    undefined,
    undefined,
    undefined
  );

export { __vue_component__ as default };
