<template>
  <label
    :class="{
      'mm-checkbox-button--checked': selected,
      'mm-checkbox-button--disabled': realDisabled || realReadonly,
    }"
    class="mm-checkbox-button">
    <input
      v-if="value !== undefined"
      ref="input"
      v-model="model"
      v-bind="attrs"
      :value="value"
      type="checkbox"
      @change="handleChange" />

    <input
      v-else
      ref="input"
      v-model="model"
      v-bind="attrs"
      :true-value="trueValue"
      :false-value="falseValue"
      type="checkbox"
      @change="handleChange" />

    <span class="mm-checkbox-faux">
      <span
        :class="indeterminate"
        class="mm-checkbox-input">
      </span>
      <span
        v-if="label || $slots.default"
        class="mm-checkbox-label">
        <slot>{{ label }}</slot>
      </span>
    </span>
  </label>
</template>

<script>
import input from "../../mixins/input"
export default {
  name: "mm-checkbox-button",
  mixins: [input],
  inheritAttrs: false,
  model: {
    prop: "checked",
    event: "input",
  },
  props: {
    label: {
      type: String,
    },
    value: {
      type: null,
    },
    checked: {
      type: null,
      default: false,
    },
    indeterminate: {
      type: Boolean,
      default: false,
    },
    trueValue: {
      type: null,
      default: true,
    },
    falseValue: {
      type: null,
      default: false,
    },
    onChange: Function,
  },
  data() {
    return {
      localChecked: this.checked,
      localIndeterminate: this.indeterminate,
    }
  },
  computed: {
    attrs() {
      return {
        ...this.$attrs,
        name: this.realName,
        disabled: this.realDisabled || this.realReadonly,
      }
    },
    model: {
      get() {
        return this.checked
      },
      set(val) {
        this.localChecked = val
        this.$emit("input", val)
      },
    },
    selected() {
      return Array.isArray(this.checked) && this.checked.includes(this.value)
    },
  },
  watch: {
    checked(value) {
      this.localChecked = value
    },
    indeterminate(value) {
      this.localIndeterminate = value
    },
    localIndeterminate(value) {
      this.$refs.input.indeterminate = value
      this.$emit("update:indeterminate", false)
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.input.indeterminate = this.localIndeterminate
    })
  },
  methods: {
    handleChange(event) {
      this.localIndeterminate = false

      const value = this.getValue(event.target.checked)
      this.$emit("change", event, value)
      this.onChange && this.onChange(event, value)
    },
    getValue(condition) {
      let value

      if (this.value !== undefined) {
        value = this.value
      } else {
        value = condition ? this.trueValue : this.falseValue
      }

      return value
    },
  },
}
</script>
