import Swiper from 'swiper'

let timer, swiper

export default {
  props: {
    loadData: {
      type: Function,
      require: true,
    },

    defaultExpandedKeys: {
      default: false,
      type: Boolean
    },

    replaceFields: {
      default() {
        return {
          value: 'id',
          title: 'title',
          children: 'children'
        }
      },
      type: Object
    }
  },

  data() {
    return {
      loading: false,

      data: [],
      list: [],

      searchValue: '',

      selectedKeys: [],
      expandedKeys: [],
      autoExpandParent: true
    }
  },

  created() {
    this.onLoadData()
  },

  mounted() {
    const container = this.$refs.swiper,
      scrollBar = container.querySelector('.swiper-scrollbar')

    const swiperOptions = {
      direction: 'vertical',
      slidesPerView: 'auto',
      freeMode: true,
      scrollbar: {
        el: scrollBar,
      },
      mousewheel: true,
    }

    swiper = new Swiper(container, swiperOptions)

    window.addEventListener('resize', () => {
      this.onUpdateSwiper()
    })

  },

  methods: {

    renderBreadcrumbItem() {

      const path = ['顶级']

      const findPath = (data, level) => {
        level = level || 1
        for (let i = 0; i < data.length; i++) {
          const item = data[i]

          path[level] = item[this.replaceFields.title]

          if (item[this.replaceFields.value] === this.selectedKeys[0]) {
            path.length = level + 1
            return true
          }

          if (item[this.replaceFields.children] && item[this.replaceFields.children].length) {
            const found = findPath(item[this.replaceFields.children], level + 1)
            if (found) {
              return true
            }
          }
        }
      }

      if (this.selectedKeys.length) {
        findPath(this.data)
      }

      return path.map(p => (
        <a-breadcrumb-item>{p}</a-breadcrumb-item>
      ))
    },

    onLoadData() {
      this.loading = true

      this.loadData().then((res) => {
        const data = this.generateKey(res)
        this.list = []
        this.generateList(data)
        if (this.defaultExpandedKeys) {
          this.expandedKeys = this.list.map(p => p.key)
        }
        this.data = data

        this.$nextTick(() => {
          this.onUpdateSwiper()
        })
      }).finally(() => {
        this.loading = false
      })
    },

    onReloadData() {
      this.onLoadData()
    },

    onExpand(expandedKeys) {
      this.expandedKeys = expandedKeys
      this.autoExpandParent = false
      this.onUpdateSwiper()
    },

    onUnexpandAll() {
      this.expandedKeys = []
    },

    onSearch(value) {
      const expandedKeys = this.list
        .map(p => {
          if (p[this.replaceFields.title].indexOf(value) > -1) {
            return this.getParentKey(p.key, this.data)
          }
          return null
        })
        .filter((p, i, self) => p && self.indexOf(p) === i)

      this.searchValue = value
      this.expandedKeys = expandedKeys
      this.autoExpandParent = true

      this.$nextTick(() => {
        this.onUpdateSwiper()
      })

    },

    onSelect(selectedKeys) {
      const selectedIds = []
      selectedKeys.forEach(p => {
        const data = this.list.find(m => m.key === p)
        selectedIds.push(data[this.replaceFields.value])
      })
      this.selectedKeys = selectedIds
      this.$emit('select', selectedIds)
    },

    onUpdateSwiper() {
      clearTimeout(timer)
      timer = setTimeout(() => {
        swiper.update()
        swiper.update()
      }, 300)
    },

    generateKey(data, level) {
      const n = level || [0]
      n.push(0)
      data.forEach((p, i) => {
        n[n.length - 1] = i
        p.key = n.join('-')
        p.scopedSlots = { title: 'title' }
        if (p[this.replaceFields.children]) {
          this.generateKey(p[this.replaceFields.children], Object.assign([], n))
        }
      })
      return data
    },

    generateList(data) {
      // 这里获取不到Key
      for (let i = 0; i < data.length; i++) {
        const { key } = data[i]
        this.list.push({
          key,
          [this.replaceFields.value]: data[i][this.replaceFields.value],
          [this.replaceFields.title]: data[i][this.replaceFields.title]
        })
        if (data[i][this.replaceFields.children]) {
          this.generateList(data[i][this.replaceFields.children])
        }
      }
    },

    getParentKey(key, tree) {
      let parentKey;
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        if (node[this.replaceFields.children]) {
          if (node[this.replaceFields.children].some(item => item.key === key)) {
            parentKey = node.key
          } else if (this.getParentKey(key, node[this.replaceFields.children])) {
            parentKey = this.getParentKey(key, node[this.replaceFields.children])
          }
        }
      }
      return parentKey;
    },
  },

  render() {

    const props = {
      treeData: this.data,
      expandedKeys: this.expandedKeys,
      autoExpandParent: this.autoExpandParent,
    }

    const on = {
      expand: this.onExpand,
      select: this.onSelect
    }

    const scopedSlots = {
      title: (props) => {
        const title = props[this.replaceFields.title]
        return (
          <div>
            {
              title.indexOf(this.searchValue) > -1 ?
                <span>
                  {title.substr(0, title.indexOf(this.searchValue))}
                  <span style="color: #f50">{this.searchValue}</span>
                  {title.substr(title.indexOf(this.searchValue) + this.searchValue.length)}
                </span>
                :
                <span>{title}</span>
            }
          </div>

        );
      }
    }

    return (
      <a-layout class="yo-tree-layout">
        <a-layout-sider width="240px">
          <a-layout-header>
            <div class="header-actions">
              <a-input-search allowClear={true} placeholder="请输入检索关键字" onSearch={this.onSearch} />
            </div>
          </a-layout-header>
          <div class="yo-tree-layout--bar">
            <a-tooltip placement="bottom" title="折叠全部">
              <a-icon type="switcher" onClick={this.onUnexpandAll} />
            </a-tooltip>
          </div>
          <div class="swiper-container" ref="swiper">
            <div class="swiper-wrapper">
              <div class="swiper-slide">
                <a-spin style={{ height: '100%' }} spinning={this.loading}>
                  <a-icon slot="indicator" type="loading" spin />
                  {
                    !this.loading && !this.list.length ?
                      <a-empty description={false} class="ant-list-empty-text">
                        <template slot="image">
                          <a-icon class="h3 mt-xl mb-md" type="smile" />
                          <p>暂无数据</p>
                        </template>
                      </a-empty>
                      :
                      <a-tree {...{ props, on, scopedSlots }} />
                  }
                </a-spin>
              </div>
            </div>
            <div class="swiper-scrollbar" />
          </div>
        </a-layout-sider>
        <a-layout-content>
          <container>
            <a-breadcrumb class="mt-md mb-md">
              {this.renderBreadcrumbItem()}
            </a-breadcrumb>
          </container>
          {this.$scopedSlots.default ? this.$scopedSlots.default() : null}
        </a-layout-content>
      </a-layout>
    )
  }
}