<template>
  <el-select v-model="selectedValue" :size="size" filterable remote @change="updateValue" :placeholder="placeholder"
    :clearable="clearable" :remote-method="projectListRemotemethod" :loading="newProjectListLoading" :style="`width: ${width}`"
    @visible-change="visibleChangeProjrct" @focus="peojectFocus">
    <div ref="mySelectProject" class="select-project-class">
      <el-option v-for="item in newProjectList" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode"
        :value="item.id">
        <span style="float: left; color: #8492a6; font-size: 13px;">{{ item.projectCode }}</span>
        <span style="float: right;margin-left: 20px">{{ item.projectName }}</span>
      </el-option>
      <div class="itemsLoading" v-if="loadingInProgress">
        加载中...
      </div>
    </div>
  </el-select>
</template>

<script>
export default {
  name: 'selectProject',
  props: {
    value: {
      type: [String, Number],
      required: true
    },
    size: {
      type: [String],
      default: 'mini'
    },
    placeholder: {
      type: [String],
      default: '请选择'
    },
    clearable: {
      type: [Boolean],
      default: false
    },
    width: {
      type: [String],
      default: '200px'
    }
  },
  data() {
    return {
      newProjectListLoading: false,
      newProjectList: [],
      selectedValue: this.value,
      newProjectListPage: 1,
      newProjectListSize: 20,
      newProjectListTotal: 0,
      loadingInProgress: false,
      loadingInProgressHight: 0,
      refRollVal: null,
      scrollListener: null,
      infoString: ''
    }
  },
  watch: {
    value(newValue) {
      this.selectedValue = newValue;
    },
    selectedValue(newValue) {
      this.$emit('input', newValue);
    }
  },
  methods: {
    projectListRemotemethod: _.debounce(function (val) {
      this.newProjectListPage = 1
      this.getNewProjectList(val)
    }, 300),
    peojectFocus() {
      this.newProjectListPage = 1
      this.getNewProjectList()
    },
    getNewProjectList(infoString = '') {
      this.infoString = infoString
      this.newProjectListLoading = true
      this.postData(`/project/getProjectListByPage`, {
        pageIndex: this.newProjectListPage,
        pageSize: this.newProjectListSize,
        id: this.value,
        forReport: 0,
        infoString,
      }).then((res) => {
        this.newProjectList = res.data.data
        this.newProjectListTotal = res.data.total
      }).finally(() => {
        this.newProjectListLoading = false
      })
    },
    addNewProjectList() {
      this.loadingInProgress = true
      this.postData(`/project/getProjectListByPage`, {
        pageIndex: this.newProjectListPage,
        pageSize: this.newProjectListSize,
        id: this.value,
        forReport: 0,
        infoString: this.infoString,
      }).then((res) => {
        this.newProjectList = [...this.newProjectList, ...res.data.data]
      }).finally(() => {
        setTimeout(() => {
          this.loadingInProgress = false
        }, 500)
      })
    },
    handleScroll(event) {
      const container = event.target;
      const { scrollTop, scrollHeight, clientHeight } = container;

      const totalPage = Math.ceil(this.newProjectListTotal / this.newProjectListSize);
      if (scrollTop + clientHeight >= scrollHeight - 20 && this.newProjectListPage < totalPage && !this.loadingInProgress) {
        this.loadMoreData()
      }
    },
    loadMoreData() {
      this.newProjectListPage += 1;
      this.addNewProjectList();
    },
    visibleChangeProjrct(flag) {
      if (flag) {
        this.$nextTick(() => {
          this.addScrollListener();
        });
      } else {
        this.removeScrollListener();
      }
    },
    addScrollListener() {
      const container = this.$refs.mySelectProject;
      const scrollbar = container.closest('.el-scrollbar__wrap');
      if (scrollbar) {
        this.loadingInProgressHight = scrollbar.clientHeight - 40
        this.removeScrollListener();
        const debouncedHandleScroll = _.debounce(this.handleScroll, 200);
        scrollbar.addEventListener('scroll', debouncedHandleScroll);
        this.scrollListener = debouncedHandleScroll;
      }
    },

    removeScrollListener() {
      const container = this.$refs.mySelectProject;
      const scrollbar = container.closest('.el-scrollbar__wrap');
      if (scrollbar && this.scrollListener) {
        scrollbar.removeEventListener('scroll', this.scrollListener);
        this.scrollListener = null;
      }
    },
    async postData(urls, param) {
      return new Promise((resolve, reject) => {
        this.http.post(urls, { ...param },
          res => {
            if (res.code == 'ok') {
              resolve(res)
            } else {
              this.$message({
                message: res.msg,
                type: 'error'
              })
              reject(res)
            }
            resolve(res)
          },
          error => {
            this.$message({
              message: error,
              type: "error"
            });
            reject(error)
          }
        )
      });
    },
    updateValue(value) {
      this.$emit('input', value);
      this.$emit('change', value);
    }
  },
  created() {

  },
  mounted() {
    this.getNewProjectList()
  },
  beforeDestroy() {
    this.removeScrollListener();
  }
}
</script>

<style lang="scss" scoped>
.select-project-class {
  position: relative;

  .itemsLoading {
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 100%;
    text-align: center;
    padding: 10px;
    background: #fff;
    box-shadow: 0px -4px 20px 0px #999;
    font-size: 12px;
    color: #999;
    z-index: 99;
    box-sizing: border-box;
  }
}
</style>