<template>
  <el-select
    :loading="loading"
    :placeholder="placeholderProxy"
    :clearable="clearableProxy"
    popper-class="o-select-option"
    v-bind="$attrs"
    @visible-change="onVisibleChange"
    @change="onChange"
  >
    <el-option
      v-for="option in options"
      :key="option.value"
      :label="option.label"
      :value="option.value"
    />
  </el-select>
</template>

<script>
// const schema = {
//   option?: { value: String, label: String },
//   options?: [{ value: String, label: String }],
//   remote?: Function,
//   pagination?: false,
//   value?: String,
//   label?: String
// }

export default {
  name: 'SchemaSelect',
  props: {
    schema: {
      type: Object,
      required: true
    },
    placeholder: {
      type: String,
      default: void 0
    },
    clearable: {
      type: [Boolean, String],
      default: false
    }
  },
  data () {
    return {
      loaded: false,
      loading: false,
      optionData: null
    }
  },
  computed: {
    placeholderProxy () {
      return this.schema.placeholder || this.placeholder
    },
    clearableProxy () {
      return !!this.schema.placeholder
    },
    options () {
      if (this.loaded) {
        return this.optionData || []
      }
      const { option } = this.schema
      return this.$attrs.value && option ? [option] : []
    }
  },
  created () {
    const { options, remote } = this.schema
    this.optionData = options
    this.loaded = !remote
  },
  methods: {
    onVisibleChange (visible) {
      if (visible && !this.loaded && !this.loading) {
        this.loading = true
        this.loadSelectOptions(this.schema).then(
          ({ data }) => {
            const { value = 'value', label = 'label' } = this.schema
            this.optionData = data.map(item => {
              return { value: item[value], label: item[label] }
            })
            this.loading = false
            this.loaded = true
          },
          () => {
            this.loading = false
          }
        )
      }
    },
    mergeCondition (condition) {
      const { options, remote } = this.schema
      if (remote) {
        this.schema.condition = { ...this.schema, ...condition }
        this.optionData = options
        this.loaded = false
      }
    },
    loadSelectOptions () {
      const { pagination, remote, condition } = this.schema
      return pagination
        ? remote({
          ...condition,
          pageSize: 10,
          pageNum: 1
        }).then(({ data, totalCount }) => {
          if (totalCount <= 10) {
            return { data }
          }
          return remote({
            ...condition,
            pageSize: totalCount,
            pageNum: 1
          })
        })
        : remote(this.schema)
    },
    onChange (value) {
      this.$emit('input', value)
      this.$emit('change', value)
    }
  }
}
</script>
