<template>
  <l-label :class="className" :style="style" :arrow="!disabled" :required="required" :title="title">
    <picker
      @change="change"
      :mode="multiple ? 'multiSelector' : 'selector'"
      :range="innerRange"
      :value="index"
      :disabled="disabled"
    >
      <view class="picker">{{ display }}</view>
    </picker>
  </l-label>
</template>

<script>
export default {
  name: 'l-select',

  props: {
    title: {},
    disabled: {},
    range: {},
    placeholder: {},
    multiple: {},
    value: {},
    emptyText: { default: '(未选择)' },
    splitText: { default: ' ' },
    required: {},
    textField: { default: 'text' },
    valueField: { default: 'value' }
  },

  data() {
    return {
      index: -1
    }
  },

  model: {
    prop: 'value',
    event: 'input'
  },

  mounted() {
    this.calcIndex()
  },

  methods: {
    change(e) {
      this.index = e.detail.value
      this.$emit('input', this.currentModel)
      this.$emit('change', this.currentModel)
    },

    calcIndex() {
      if (this.multiple) {
        if (this.objectMode) {
          this.index = this.range.map((group, idx) =>
            group.findIndex(t => this.arrayCompare(t[this.valueField], this.value[idx]))
          )
        } else {
          this.index = this.range.map((group, idx) => group.findIndex(t => this.arrayCompare(t, this.value[idx])))
        }
      } else {
        if (this.objectMode) {
          this.index = this.range.findIndex(t => t[this.valueField] === this.value)
        } else {
          this.index = this.range.indexOf(this.value)
        }
      }
    },

    arrayCompare(a, b) {
      if (!a || !b || a.length !== b.length) {
        return false
      }

      let isOk = true
      a.forEach((t, i) => {
        if (b[i] !== t) {
          isOk = false
        }
      })

      return isOk
    }
  },

  computed: {
    objectMode() {
      return typeof (this.multiple ? this.range[0][0] : this.range[0]) === 'object'
    },

    innerRange() {
      if (!this.objectMode) {
        return this.range
      }

      if (this.multiple) {
        return this.range.map(item => item.map(t => t[this.textField]))
      }

      return this.range.map(t => t[this.textField])
    },

    currentModel() {
      const { multiple, range, index, objectMode } = this
      if (!multiple) {
        return index === -1 ? undefined : objectMode ? range[index][this.valueField] : range[index]
      }

      if (!objectMode) {
        return range.map((group, idx) => group[index[idx]])
      }

      range.map((group, idx) => (index[idx] === -1 ? undefined : group[index[idx]][this.valueField]))
    },

    display() {
      const { multiple, range, value, index, objectMode, emptyText, displayPlaceholder, splitText } = this
      if (!multiple) {
        return index === -1 ? displayPlaceholder : objectMode ? range[index][this.textField] : range[index]
      }

      if (!Array.isArray(index) || index.every(t => t === -1)) {
        return displayPlaceholder
      }

      if (!objectMode) {
        return range.map((group, idx) => group[index[idx]] || emptyText).join(splitText)
      }

      return range
        .map((group, idx) => (index[idx] === -1 ? emptyText : group[index[idx]][this.textField]))
        .join(splitText)
    },

    displayPlaceholder() {
      if (this.disabled) {
        return ''
      }

      if (this.placeholder) {
        return this.placeholder
      }

      return this.title ? `请选择${this.title}` : '请选择…'
    }
  },

  watch: {
    value() {
      this.calcIndex()
    }
  }
}
</script>
