<template>
  <div class="el-transfer-panel">
    <el-checkbox
      class="el-transfer-panel__header"
      v-model="allChecked"
      @change="handleAllCheckedChange"
      :indeterminate="isIndeterminate">
      <span>
        {{ title }}
      <span class="el-transfer-panel__header-text">{{ showNumber }}个</span>
      </span>
    </el-checkbox>

    <div :class="['el-transfer-panel__body', (pagination || hasFooter) ? 'is-with-footer' : '']">
      <div class="el-transfer-panel__filter_box">
        <el-input
          class="el-transfer-panel__filter"
          v-model="query"
          size="large"
          :placeholder="placeholder"
          @mouseenter.native="inputHover = true"
          @mouseleave.native="inputHover = false"
          clearable
          v-if="filterable">
          <i class="el-input__icon el-icon-search icon" slot="suffix" @click="clearQuery"/>
        </el-input>
      </div>
      <template v-if="type !== 'tree'">
        <el-scrollbar class="scrollbar" :class="{ 'is-filterable': filterable }">
          <template v-for="item in fixedData">
            <div class="el-transfer-panel__item fixed-text" v-if="filterFixedData(item)">{{item[labelProp]}}</div>
          </template>
          <p
          class="hasNoMatch"
          v-show="!(filteredData && filteredData.length) && !query">
            <span>暂无内容</span></p>
            <p
          class="hasNoMatch"
          v-show="hasNoMatch"><span>{{ t('el.transfer.noMatch') }}</span></p>
          <el-checkbox-group
            v-model="checked"
            v-show="!hasNoMatch && sourceData.length > 0"
            :class="{ 'is-filterable': filterable, 'has-padding-top': fixedData.length === 0 }"
            :style="filterable ? 'padding-top: 0':'padding-top: 8px;'"
            class="el-transfer-panel__list">
            <template v-for="item in filteredData">
              <el-checkbox
                v-if="!item.options"
                class="el-transfer-panel__item"
                :label="item[keyProp]"
                :disabled="item[disabledProp]"
                :key="item[keyProp]"
                @change="changeItem($event, item)">
                <option-content :option="item"></option-content>
              </el-checkbox>
              <div v-if="item.options" :key="item[keyProp]" class="el-transfer-panel__list-groupname el-transfer-panel__item">{{item[labelProp]}}</div>
            </template>
          </el-checkbox-group>
        </el-scrollbar>
      </template>

      <template v-else>
        <el-scrollbar class="scrollbar" :class="{ 'is-filterable': filterable }">
          <template>
            <el-tree show-checkbox
              ref="tree"
              :class="{ 'is-filterable': filterable }"
              class="el-transfer-panel__list"
              :style="filterable ? 'padding-top: 0':'padding-top: 8px;'"
              :showLine="showLine"
              :transfer="true"
              v-show="!hasNoMatch && sourceData.length > 0"
              :data="filteredData"
              :props="treeProps"
              :node-key="props.key"
              :default-checked-keys="defaultChecked"
              :isOverflowHidden="isOverflowHidden"
              @check="checkNode">
            </el-tree>
          </template>
        </el-scrollbar>
      </template>
      
    </div>

    <div class="el-transfer-panel__footer" v-if="pagination">
      <div style="position: relative;">
        <el-pagination
          ref="pagination"
          layout="prev, pager, smallPager, next"
          :total="totalNum"
          :page-size="pageSize"
          @prev-click="prevClick"
          @next-click ="nextClick"
        ></el-pagination>
        <div v-show="hasNoMatch" class="pafination-reset">0/0</div>
      </div>
    </div>
    <p class="el-transfer-panel__footer" v-if="hasFooter">
      <slot></slot>
    </p>
  </div>
</template>

<script>
  import ElCheckboxGroup from 'modesign-ui/packages/checkbox-group';
  import ElCheckbox from 'modesign-ui/packages/checkbox';
  import ElTree from 'modesign-ui/packages/tree';
  import ElInput from 'modesign-ui/packages/input';
  import Locale from 'modesign-ui/src/mixins/locale';
  import ElScrollbar from 'modesign-ui/packages/scrollbar';
  import ElPagination from 'modesign-ui/packages/pagination';

  const findLeaf = function(nodeList) {
    const result = [];

    const getLeaf = function(nodes) {
      nodes.forEach(node => {
        if (node.children) {
          getLeaf(node.children);
        } else {
          // TODO 未来可能存在属性名不叫disabled的情况
          if (!node.disabled) {
            result.push(node)
          }
        }
      })
    }

    getLeaf(nodeList);
    return result;
  }

  export default {
    mixins: [Locale],

    name: 'ElTransferPanel',

    componentName: 'ElTransferPanel',

    components: {
      ElCheckboxGroup,
      ElCheckbox,
      ElTree,
      ElInput,
      ElScrollbar,
      ElPagination,
      OptionContent: {
        props: {
          option: Object
        },
        render(h) {
          const getParent = vm => {
            if (vm.$options.componentName === 'ElTransferPanel') {
              return vm;
            } else if (vm.$parent) {
              return getParent(vm.$parent);
            } else {
              return vm;
            }
          };
          const panel = getParent(this);
          const transfer = panel.$parent || panel;
          return panel.renderContent
            ? panel.renderContent(h, this.option)
            : transfer.$scopedSlots.default
              ? transfer.$scopedSlots.default({ option: this.option })
              : <span>{ this.option[panel.labelProp] || this.option[panel.keyProp] }</span>;
        }
      }
    },

    props: {
      sourceData: {
        type: Array,
        default() {
          return [];
        }
      },
      renderContent: Function,
      placeholder: String,
      title: String,
      filterable: Boolean,
      filterMethod: Function,
      defaultChecked: Array,
      props: Object,
      simple: Boolean,
      treeProps: Object,
      showLine: Boolean,
      fixedList: {
        type: Array,
        default: () => []
      },
      type: {
        type: String,
        default: 'checkbox'
      },
      pagination: Boolean,
      pageSize: Number,
      isOverflowHidden: Boolean
    },

    data() {
      return {
        checked: [],
        allChecked: false,
        query: '',
        inputHover: false,
        checkChangeByUser: true,
        leafs: [],
        isdropdown: true, // 表明是下拉菜单里的tree
        filterPaginationData: [], // 分页状态下搜索时维护的数组
        page:1
      };
    },

    watch: {
      checked(val, oldVal) {
        this.updateAllChecked();
        if (this.checkChangeByUser) {
          const movedKeys = val.concat(oldVal)
            .filter(v => val.indexOf(v) === -1 || oldVal.indexOf(v) === -1);
          this.$emit('checked-change', val, movedKeys);
        } else {
          this.$emit('checked-change', val);
          this.checkChangeByUser = true;
        }
      },

      checkableData() {
        this.updateAllChecked();
      },

      defaultChecked: {
        immediate: true,
        handler(val, oldVal) {
          if (oldVal && val.length === oldVal.length &&
            val.every(item => oldVal.indexOf(item) > -1)) return;
          const checked = [];
          const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]);
          val.forEach(item => {
            if (checkableDataKeys.indexOf(item) > -1) {
              checked.push(item);
            }
          });
          this.checkChangeByUser = false;
          this.checked = checked;
        }
      }
    },
    computed: {
      filteredData() {
        if (this.sourceData[0].options) {
          // 分组数据
          const result = []
          function flatArr(arr) {
            arr.forEach(item => {
              if (item.options) {
                result.push(item)
                flatArr(item.options)
              } else {
                result.push(item)
              }
            })
          }
          flatArr(this.sourceData);
          return result.filter(item => {
            // ???? why
            // if (item.options) {
            //   return true;
            // }
            return item[this.labelProp].toLowerCase().indexOf(this.query.toLowerCase()) > -1;
          });
        } else {
          // 不分组数据
          let arr = this.sourceData;
          if (this.simple) {
            // 简单模式，选中项过滤掉
            arr = this.sourceData.filter(item => {
              return !this.checked.includes(item[this.keyProp])
            })
          }
          const result = this.getFilterData(arr);
          if (this.pagination) {
            this.filterPaginationData = result;
            return result.slice(this.pageSize * (this.page - 1), this.pageSize * this.page);
          }
          return result;
        }
      },

      checkableData() {
        if (this.type === 'checkbox') {
          return this.filteredData.filter(item => !item[this.disabledProp]);
        } else {
          this.getTreeLeaf();
          return this.leafs.filter(item => !item[this.disabledProp]);
        }
      },

      isIndeterminate() {
        if (this.simple) {
          return false
        }
        const checkedLength = this.checked.length;
        // const disabledLen = this.filteredData.filter(x => x.disabled).length || 0
        let disabledLen =  0
        this.filteredData.forEach(item => {
          if (item.children && item.children.length) {
            disabledLen += item.children.filter(y => y.disabled).length
          }
        })
        return !this.allChecked && checkedLength > 0 && checkedLength < this.showNumber + disabledLen;
      },

      hasNoMatch() {
        return this.query.length > 0 && this.filteredData.length === 0;
      },

      labelProp() {
        return this.props.label || 'label';
      },

      keyProp() {
        return this.props.key || 'key';
      },

      disabledProp() {
        return this.props.disabled || 'disabled';
      },

      hasFooter() {
        return !!this.$slots.default;
      },

      fixedData() {
        if (this.type === 'checkbox' && this.fixedList.length > 0) {
          return this.sourceData.filter(item => this.fixedList.includes(item[this.keyProp]))
        }
        return []
      },

      showNumber() {
        if (this.type === 'checkbox') {
          if (!this.pagination) {
            return this.filteredData.filter(x => !x.options && !x.disabled).length + this.fixedData.length 
          } else {
            if (!this.query) {
              return this.sourceData.filter(e => !e.disabled).length
            }
            return this.filterPaginationData.filter(e => !e.disabled).length
          }
        }
        return this.leafs.filter(e => !e.disabled).length;
      },

      totalNum() {
        if (!this.query) {
          return this.sourceData.length
        }
        let arr = this.getFilterData(this.sourceData);
        return this.fixedList.length + arr.length
      }
    },

    methods: {
      // 如果有搜索项，那么fixedList也需要进行筛选
      filterFixedData(item) {
        if (this.filterable && this.query) {
          const label = item[this.labelProp]
          return label.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
        }
        return true;
      },

      updateAllChecked() {
        if (this.pagination) {
          // 分页需要把所有项目都选上才行
          const notDisabledList = this.query ? this.filterPaginationData.filter(x => !x.disabled).map(x => x[this.keyProp])
            : this.sourceData.filter(x => !x.disabled).map(x => x[this.keyProp]);
          // 没考虑分页且分组的情况
          this.allChecked = this.checked.length > 0 &&
            notDisabledList.every(item => this.checked.indexOf(item) > -1);
        } else {
          // 过滤掉分组情况的分组名
          const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]).filter(x => x);
          this.allChecked = checkableDataKeys.length > 0 &&
            checkableDataKeys.every(item => this.checked.indexOf(item) > -1);
        }
      },

      getFilterData(arr = []) {
        return arr.filter(item => {
          if (typeof this.filterMethod === 'function') {
            return this.filterMethod(this.query, item);
          } else if (this.fixedList.includes(item[this.keyProp])) {
            return false;
          } else {
            const label = item[this.labelProp] || item[this.keyProp].toString();
            return label.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
          }
        });
      },

      // 点击全选按钮
      handleAllCheckedChange(value) {
        if (this.simple) {
          this.allChecked = true
          // this.checked = this.checkableData.map(item => item[this.keyProp])
          const arr = []
          this.sourceData.forEach(item => {
            if (!item.disabled) {
              arr.push(item[this.keyProp])
            }
          })
          this.checked = arr
        } else if (this.pagination) {
          // 分页
          if (value) {
            this.checked = !this.query ? this.getFilterData(this.sourceData.filter(x => !x.disabled)).map(item => item[this.keyProp])
              : this.getFilterData(this.filterPaginationData.filter(x => !x.disabled)).map(item => item[this.keyProp])
          } else {
            this.checked = []
          }
        } else {
          // 处理checkbox的勾选和不勾选
          if(value){
            this.checked = Array.from(new Set(this.checked.concat(this.checkableData.filter(x => !x.options).map(item => item[this.keyProp]))))
          }else {
            this.checked = []
          }
        }
        // 处理tree的全选和全不选
        if (this.type == "tree") {
          if(value){
            this.$refs.tree.setCheckedKeys(this.checkableData.map(item => item[this.keyProp]))
          }else{
            this.$refs.tree.setCheckedKeys([]);
          }
        }

        if (this.fixedData.length > 0) {
          this.$emit('changeAllItem', [...this.fixedList, ...this.checked]);
        } else {
          this.$emit('changeAllItem', this.checked);
        }
      },

      clearQuery() {
        this.query = '';
      },

      // 切换绑定值选中状态
      changeItem(e, item) {
        this.$emit('changeItem', e, item, 'left');
      },

      // 初始化数据或改变右侧值时，同步checked的值
      changeChecked(checked) {
        this.checkChangeByUser = false;
        if (this.fixedData.length > 0) {
          this.checked = checked.filter(item => !this.fixedList.includes(item))
        } else {
          this.checked = checked;
        }
        if (this.type === 'tree') {
          this.$refs.tree.setCheckedKeys(this.checked);
        }
      },

      checkNode(data, nodes) {
        const keys = nodes.checkedNodes.filter(x => !x.children).map(x => x[this.keyProp])
        this.$emit('changeTreeItem', keys)
      },

      // 获取所有叶子节点
      getTreeLeaf() {
        this.leafs = findLeaf(this.filteredData);
      },

      // 上一页
      prevClick(){
        this.page = this.$refs.pagination.internalCurrentPage
      },

      // 下一页
      nextClick(){
        this.page = this.$refs.pagination.internalCurrentPage
      }
    }
  };
</script>
