<template>
  <selector-card
    class="area-selector card"
    @onConfirm="onConfirm"
    @onCancel="onCancel"
  >
    <div slot="header">选择区域</div>
    <div class="selector-content" v-loading="loading">
      <div class="search-container">
        <el-input v-model="searchContent" placeholder="搜索" prefix-icon="el-icon-search"></el-input>
      </div>
      <div class="select-list scrollbar" ref="selectList">
        <div v-for="(item, key) in provinceListMap" :key="key" class="select-group-container">
          <div class="index-anchor" :id="key" :data-index="key" v-if="key !== '#'">{{ key }}</div>
          <el-collapse-transition v-for="(province, ii) in item" :key="ii*2">
            <div class="select-group tab-content global" v-if="province.name == '全国'">
              <button
                class="j-button-item global"
                :class="{
                  active: province.selectedState,
                  [province.id]: true
                }"
                @click="changeCityState(province, '#')"
              >{{ province.name }}</button>
            </div>
            <div class="select-group" v-else>
              <div class="tab" :class="province.id">
                <div class="tab-name-container" @click="clickCheckbox(province)">
                  <div class="j-checkbox" :class="province.selectedState"></div>
                  <span class="tab-name">{{ province.name }}</span>
                </div>
                <span style="flex: 1; height: 100%;" @click="changeExpandState($event, province)"></span>
                <span
                  v-if="province.canExpanded"
                  @click="changeExpandState($event, province)">
                  <i
                    class="el-icon-arrow-down"
                    :class="{
                      rotate180: province.expanded
                    }"></i>
                </span>
              </div>
              <el-collapse-transition>
                <div v-show="province.expanded" class="tab-content">
                  <div class="content-list">
                    <button v-for="(city, iii) in province.children" :key="iii*3"
                      class="j-button-item"
                      :class="{
                        active: city.selected,
                        [city.id]: true
                      }"
                      :disabled="!city.canSelected"
                      @click="changeCityState(province, city)"
                      >{{ city.city }}</button>
                  </div>
                </div>
              </el-collapse-transition>
            </div>
          </el-collapse-transition>
        </div>
      </div>
    </div>
  </selector-card>
</template>

<script>
import { Input, Icon } from 'element-ui'
import 'element-ui/lib/theme-chalk/base.css'
import CollapseTransition from 'element-ui/lib/transitions/collapse-transition'
import SelectorCard from '@/components/selector/SelectorCard.vue'
import chinaMapJSON from '@/assets/js/china_area.js'
import { provinceListMapExp } from '@/assets/js/selector.js'
import { debounce, getRandomString } from '@/utils/'
export default {
  name: 'area-selector-card',
  components: {
    [Input.name]: Input,
    [Icon.name]: Icon,
    [CollapseTransition.name]: CollapseTransition,
    SelectorCard
  },
  props: {
    // 初始化城市数据
    // 刚进入页面需要被选中的城市数据
    initCityMap: {
      type: Object,
      default () {
        return {
          // '北京': [],
          // '安徽': [],
          // '广东': [
          //     '揭阳市',
          //     '茂名市',
          //     '韶关市'
          // ],
          // '河北': [
          //     '邯郸市',
          //     '秦皇岛市',
          //     '保定市'
          // ],
          // '福建': [
          //     '福州市',
          //     '厦门市',
          //     '宁德市'
          // ],
          // '重庆': []
        }
      }
    }
  },
  data () {
    return {
      searchContent: '',
      loading: false,
      // 省份与字母IndexBar对照表
      provinceListMapExp,
      provinceListMap: {
        // A: [
        //     {
        //         name: '安徽',
        //         expanded: false,
        //         canExpanded: true,
        //         selectedState: '',
        //         children: []
        //     }
        // ]
      },
      // indexBar数据
      indexList: [],
      provinceExp: {
        name: '',
        // 展开状态
        expanded: false,
        // 是否可以展开
        canExpanded: false,
        // 选中状态: half(半选)、checked(全选)、''(未选中)、checkeddisabled(全选不能点击)、nonedisabled(未选不能点击)
        selectedState: '',
        children: [],
        id: ''
      }
    }
  },
  watch: {
    initCityMap (newVal, oldVal) {
      this.setCitySelected(newVal)
    },
    searchContent: debounce(function (newVal, oldVal) {
      const search = newVal
      const { findP } = this.getProvinceWithString(search)
      const id = findP[0] && findP[0].id
      if (id) {
        if (findP[0].canExpanded) {
          findP[0].expanded = true
        }
        this.$nextTick(() => {
          const wrapper = document.querySelector('.area-selector.card')
          this.$refs.selectList.scrollTop = wrapper.querySelector(`.${id}`).offsetTop
          // document.querySelector(`.${id}`).scrollIntoView() // 兼容性有问题
        })
      }
    }, 300)
  },
  created () {
    this.initIndexBarAndAreaMap()
    this.provinceListMap['#'][0].selectedState = 'checked'
    this.setCitySelected(this.initCityMap)
  },
  methods: {
    changeLoadingState (s) {
      this.loading = s
    },
    // 整理城市数据列表(并初始化indexBar数据)
    initIndexBarAndAreaMap () {
      // 整理数据得到indexListMap()，同时获得indexList
      const provinceListMap = {}
      const indexList = []
      for (const key in this.provinceListMapExp) {
        const areaArr = []
        indexList.push(key)
        this.provinceListMapExp[key].forEach(pName => {
          const provinceExp = JSON.parse(JSON.stringify(this.provinceExp))

          provinceExp.name = pName
          provinceExp.id = `ap-${getRandomString(8).toLowerCase()}`

          if (pName !== '全国') {
            const cities = this.getCitiesFromJSONMap(pName)
            // console.log(pName, cities)
            // 筛选掉直辖市和特别行政区(台湾省也不不需要展开)
            if (cities.ProRemark === '省份' || cities.ProRemark === '自治区') {
              if (cities.ProID === 32) {
                provinceExp.children = []
                provinceExp.canExpanded = false
              } else {
                cities.city.forEach(c => {
                  // 将市区重组成一个新的对象
                  return provinceExp.children.push({
                    city: c.name,
                    selected: false,
                    canSelected: true,
                    id: `ac-${getRandomString(8).toLowerCase()}`
                  })
                })
              }
            } else {
              provinceExp.children = []
              provinceExp.canExpanded = false
            }
          }

          provinceExp.canExpanded = provinceExp.children.length !== 0
          areaArr.push(provinceExp)
        })

        provinceListMap[key] = areaArr
      }

      this.provinceListMap = provinceListMap
      this.indexList = indexList

      // 给provinceListMap赋值
      for (const k in provinceListMap) {
        this.$set(this.provinceListMap, k, provinceListMap[k])
      }
    },
    // 循环chinaMapJSON，找到对应省下面对应的市
    getCitiesFromJSONMap (provinceName) {
      return chinaMapJSON.find(item => item.name.indexOf(provinceName) !== -1)
    },
    // 输入字符串，找到其所在省份
    getProvinceWithString (s = '') {
      // 找是否有省份相同的
      const findP = [] // 匹配到的省份数组
      const findC = [] // 匹配到的市数组
      if (s) {
        for (const key in this.provinceListMap) {
          const item = this.provinceListMap[key]
          for (let i = 0; i < item.length; i++) {
            if (item[i].name.includes(s)) {
              findP.push(item[i])
            }
            if (Array.isArray(item[i].children) && item[i].children.length !== 0) {
              item[i].children.forEach(city => {
                if (city.city.includes(s)) {
                  findP.push(item[i])
                  findC.push(city)
                }
              })
            }
          }
        }
      }
      return {
        findP,
        findC
      }
    },
    // 控制城市盒子展开和收起
    changeExpandState (e, province) {
      if (!province.canExpanded) return
      province.expanded = !province.expanded
    },
    // 城市选择按钮点击事件
    // 根据城市的选择情况判断省份的选择情况
    changeCityState (province, city) {
      if (city === '#') {
        return this.setCitySelected()
      }
      // 全国置为空
      this.provinceListMap['#'][0].selectedState = ''
      city.selected = !city.selected

      // 判断省份的选择状态
      let count = 0
      const cityLength = province.children.length
      if (cityLength) {
        province.children.forEach(v => {
          // 前提是可点击的
          if (v.canSelected && v.selected) {
            count++
          }
        })
      } else {
        // 直辖市或自治区
        province.canExpanded = false
        province.expanded = false
      }

      // 选中状态: half(半选)、checked(全选)、''(未选中)、checkeddisabled(全选不能点击)、nonedisabled(未选不能点击)
      if (count === 0) {
        province.selectedState = ''
      } else if (count < cityLength) {
        province.selectedState = 'half'
      } else if (count === cityLength) {
        province.selectedState = 'checked'
      } else {
        province.selectedState = ''
      }

      const pState = this.checkAllProvinceState()
      // 如果所有省份被全选，则取消所有选中，让全国选中
      if (pState.allSelected || pState.noSelected) {
        this.setCitySelected()
      }
    },
    // 省份checkbox点击事件
    clickCheckbox (province) {
      const state = province.selectedState
      if (state === 'checkeddisabled' || state === 'nonedisabled') return

      // 全国置为空
      this.provinceListMap['#'][0].selectedState = ''
      if (state === '' || state === 'half') {
        province.children.forEach(v => (v.selected = true))
        province.selectedState = 'checked'
      } else {
        province.children.forEach(v => (v.selected = false))
        province.selectedState = ''
      }

      const pState = this.checkAllProvinceState()
      // 如果所有省份被全选，则取消所有选中，让全国选中
      if (pState.allSelected || pState.noSelected) {
        this.setCitySelected()
      }
    },
    // 检查是否所有省份按钮被全选中
    // 全部被全选->返回true
    checkAllProvinceState () {
      const stateArr = []
      for (const key in this.provinceListMap) {
        this.provinceListMap[key].forEach(item => {
          if (item.name !== '全国') {
            if (item.selectedState === '') {
              stateArr.push('checked')
            } else if (item.selectedState === 'checked') {
              stateArr.push('unchecked')
            } else {
              stateArr.push('other')
            }
          }
        })
      }
      // 统计不同状态的个数
      const counter = {
        checked: 0,
        unchecked: 0,
        other: 0
      }
      for (let i = 0; i < stateArr.length; i++) {
        const k = stateArr[i]
        if (counter[k]) {
          counter[k] += 1
        } else {
          counter[k] = 1
        }
      }
      // console.log(counter)
      return {
        state: stateArr,
        allSelected: counter.checked === stateArr.length,
        noSelected: counter.unchecked === stateArr.length
      }
    },
    // 初始化选中城市数据
    setCitySelected (data) {
      // 设置全国
      if (!data || Object.keys(data).length === 0) {
        // 其他全部设置不选中，全国设置选中
        for (const key in this.provinceListMap) {
          this.provinceListMap[key].forEach(item => {
            item.selectedState = ''
            item.children.forEach(iitem => {
              iitem.selected = false
            })
            if (item.name === '全国') {
              item.selectedState = 'checked'
            }
          })
        }
      } else {
        // 先将所有城市选择取消
        this.setCitySelected()
        // 设置某几个省份被选中
        for (const key in this.provinceListMap) {
          this.provinceListMap[key].forEach(item => {
            const selectCityArr = data[item.name]
            if (Array.isArray(selectCityArr)) {
              if (selectCityArr.length === 0) {
                // 全省被选中
                item.children.forEach(iitem => {
                  iitem.selected = true
                })
                item.selectedState = 'checked'
              } else {
                // 省份中的某些市被选中
                item.children.forEach(iitem => {
                  if (selectCityArr.indexOf(iitem.city) !== -1) {
                    iitem.selected = true
                  }
                })
                item.selectedState = 'half'
              }
            }

            if (item.name === '全国') {
              item.selectedState = ''
            }
          })
        }
      }
    },
    // 获取当前选中城市数据
    getSelectedCity () {
      const counter = {}
      // 判断是否全国被选中
      if (this.provinceListMap['#'][0].selectedState === 'checked') {
        return counter
      }

      // 全国没有被选中，排除循环全国
      for (const key in this.provinceListMap) {
        if (key === '#') continue
        this.provinceListMap[key].forEach(item => {
          // 当前省份下被选中的城市数量
          const selectedCityArr = []
          const cityTotalCount = item.children.length
          item.children.forEach(iitem => {
            if (iitem.selected && iitem.canSelected) {
              selectedCityArr.push(iitem.city)
            }
          })
          // 计算出当前省份下的城市是否被全选了
          if (cityTotalCount === selectedCityArr.length && item.selectedState === 'checked') {
            // 城市被全选
            counter[item.name] = []
          } else {
            if (selectedCityArr.length !== 0) {
              counter[item.name] = selectedCityArr
            }
          }
        })
      }

      return counter
    },
    // 统计城市分布数量
    getCityCount () {
      const selectedCount = {
        // 全国被选中时，country为1
        country: 1,
        province: 0,
        city: {
          // 一共选了多少个城市
          totalCount: 0,
          // 分布在几个省份
          pCount: 0
        }
      }

      const selected = this.getSelectedCity()
      if (Object.keys(selected).length === 0) {
        // 全国
      } else {
        selectedCount.country = 0
        for (const p in selected) {
          if (selected[p].length === 0) {
            selectedCount.province++
          } else {
            selectedCount.city.pCount++
            selected[p].forEach(() => {
              selectedCount.city.totalCount++
            })
          }
        }
      }

      const tipText = {
        p: selectedCount.province === 0 ? '' : selectedCount.province + '个省',
        c: selectedCount.city.totalCount === 0 ? '' : selectedCount.city.totalCount + '个市',
        s: selectedCount.city.pCount === 1 ? '' : '(分布在' + selectedCount.city.pCount + '个省内)',
        text: ''
      }

      if (selectedCount.province === 1) {
        tipText.text = '全国'
      } else {
        let dot = ''
        if (selectedCount.city.totalCount !== 0 && selectedCount.province !== 0) {
          dot = '、'
        }
        if (selectedCount.city.totalCount === 0 || selectedCount.city.totalCount === 1) {
          tipText.s = ''
        }
        tipText.text = tipText.p + dot + tipText.c + tipText.s
      }

      return {
        data: selectedCount,
        zh: tipText
      }
    },
    onCancel () {
      this.$emit('onCancel')
    },
    onConfirm () {
      const selectedCity = this.getSelectedCity()
      this.$emit('onConfirm', selectedCity)
    }
  }
}
</script>

<style lang="scss" scoped>
  .j-checkbox {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1px solid #e0e0e0;
    cursor: pointer;
    &.checked {
      border: 0;
      background: url('~@/assets/images/icon/checked.png') no-repeat;
      background-size: 20px;
      &[disabled] {
        background: url('~@/assets/images/icon/checked_disabled.png') no-repeat;
        background-size: 100%;
      }
    }
    &.half {
      border: 0;
      background: url('~@/assets/images/icon/checked-half.png') no-repeat;
      background-size: 20px;
    }
  }

  .j-button-item {
    &.global {
      padding: 6px 8px;
      height: 24px;
      line-height: 24px;
      font-weight: 700;
      color: inherit;
      border-color: rgba(0,0,0,.05);
    }
  }

  [class^=el-icon-] {
    transition: transform 0.2s ease;
  }
  .rotate180 {
    transform: rotate(180deg);
  }

  .j-button-item {
    border-color: transparent;
  }

  .select-group {
    font-size: 14px;
    &.global {
      padding: 0 18px;
    }
    .tab {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 18px;
      height: 40px;
      border-bottom: 1px solid rgba(0,0,0,.05);
      cursor: pointer;
    }
    .tab-name-container {
      display: flex;
      align-items: center;
      .tab-name {
        margin-left: 10px;
        font-weight: bold;
      }
    }
    .tab-content {
      padding: 0 18px;
      // border-bottom: 1px solid rgba(0,0,0,.05);
      .content-list {
        display: flex;
        flex-wrap: wrap;
        padding: 2px 0;
      }
    }
  }
</style>
