<template>
  <el-select
    v-model="selectedValue"
    placeholder="请选择"
    filterable
    :multiple="multiple"
    :loading="loading"
    @change="handleChange"
    @visible-change="handleVisibleChange"
    remote
    :remote-method="remoteMethod"
    :clearable="clearable"
    :size="size"
  >
    <div class="select-header">
      <div>
        共{{ total }}条数据
      </div>
      <el-button v-if="multiple && !isEmpty(options)" style="margin-left: 10px;" size="mini" type="text" @click.stop="handleSelectAll">
        {{ isAllSelected ? '取消全选' : '全选' }}
      </el-button>
    </div>
    <slot name="option" :options="options">
      <el-option
        v-for="item in options"
        :key="item[prop]"
        :value="item[prop]"
        :label="item[showProp]"
      />
    </slot>
    <el-option v-if="isEmpty(options)" :label="emptyText" disabled :value="emptyValue"></el-option>
  </el-select>
</template>

<script>
import { isEmpty } from '@/utils';
import { $remoteSelect } from '@/components/BaseRemoteSelect/mixins';

export default {
  name: 'BaseRemoteSelect',
  mixins: [$remoteSelect],
  data() {
    return {
      options: [],
      total: 0,
      loading: false,
      queryParams: {
        pageNum: 1,
        pageSize: 999
      },
    }
  },
  computed: {
    selectedValue: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('input', value)
      }
    },
    // 是否全选
    isAllSelected() {
      return this.multiple && this.options.length > 0 && Array.isArray(this.value) && this.value.length === this.options.length;
    }
  },
  watch: {
    value: {
      handler(nv, ov) {
        if (isEmpty(ov) && !isEmpty(nv) && this.loadApi) {
          this.loadData(nv);
        } 
      },
      deep: true,
      immediate: true
    }
  },
  created() {
    this.queryParams[this.keywordProp] = null;
  },
  methods: {
    isEmpty,
    // 加载数据
    loadData(value) {
      this.loading = true;
      let values = value;
      if (!this.multiple) {
        values = [values];
      }
      this.loadApi(values).then(res => {
        this.options = res.data;
        this.total = this.options?.length;
      }).finally(() => {
        this.loading = false;
      });
    },
    // 远程搜索
    remoteMethod(val) {
      this.queryParams.keyword = val;
      this.getOptions();
    },
    // 下拉框可见性变化
    handleVisibleChange(visible) {
      if (visible) {
        this.getOptions();
      }
    },
    // 全选
    handleSelectAll() {
      if (this.isAllSelected) {
        this.handleChange([]);
      } else {
        const all = this.options.map(item => item[this.prop]);
        this.handleChange(all);
      }
    },
    // 选中值变化，触发change事件
    handleChange(value) {
      if (this.multiple) {
        let list = this.options.filter(item => value.includes(item[this.prop]));
        this.$emit('change', list);
      } else {
        let item = this.options.find(item => value.includes(item[this.prop]));
        this.$emit('change', item);
      }
    },
    // 获取选项
    getOptions() {
      if (!this.beforeGetOptions()) {
        return;
      }
      this.loading = true;
      Object.assign(this.queryParams, this.query);
      this.listApi(this.queryParams).then(res => {
        this.options = res.rows;
        this.total = res.total;
      }).finally(() => {
        this.loading = false;
      });
    }
  }
}
</script>

<style lang="scss" scoped>
.select-header {
  padding: 2px 12px;
  border-bottom: 1px solid #EBEEF5;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  line-height: 1em;
  text-align: center;
  color: #8492a6;
  font-size: 13px;
}
</style>
