<!-- @desc:地图组件  @auth:周兴  @time:2022/11/15 13:12 -->
<template>
  <div style="width: 100%;">
    <div style="display: flex;">
      <div style="width: 25%;position: relative;">
        <SelectPop :options="cityOptions" :multiple="false" v-model="city" labelKey="key" valueKey="value" :show-clear-flag="false"
                   :show-toolbar="false"
                   :clearable="false" @on-change="handleSelectChange" :disabled="readonly"></SelectPop>
      </div>
      <div style="width: 75%;position: relative;">
        <Input ref="input-outer" @on-focus="onFocus('outer')" @on-blur="onBlur('outer')" size="small"
               style="width: 100%;" v-model="searchTextOuter"
               :clearable="false"
               :class="readonly ? 'readonly-input' : null"
               :placeholder="readonly?'':inputPlaceholder" :readonly="readonly"
               @keydown.native="handleKeyDown($event,'outer')"
               @on-change="inputChange('outer')"></Input>
        <!--        <div class="close-class" v-if="searchTextOuter && !readonly">-->
        <!--          <Icon slot="prefix" type="ios-close-circle" @click.stop="handleClear('outer')"/>-->
        <!--        </div>-->
        <div class="search-class">
          <Icon slot="prefix" type="md-search" @click.stop="openMap"/>
        </div>
        <div v-if="focusFlagOuter" class="map-select-outer-class">
          <div tabindex="0" @click="chooseAddress(item,'outer')" @keydown="handleItemKeyDown($event,'outer',index)"
               class="search-result-item"
               @blur="onBlur('outer')"
               v-for="(item,index) in searchTextListOuter" :style="{borderTop:index===0?'':'1px solid #b6b6b6'}"
               style="cursor:pointer;width: 100%;padding: 3px;" :ref="'outer_' + index" :key="index">
            <div style="display: flex;align-items: center;">
              <div
                style="width:16px;height:16px;border-radius: 50%;background: red;display: flex;justify-content: center;align-items: center;color: #fff;">
                {{ index + 1 }}
              </div>
              <div style="margin-left: 5px;font-size: 12px;font-weight: bold;">{{ item.title }}</div>
            </div>
            <div style="margin-top: 14px;font-size: 12px;color:#898989;">{{ item.address }}</div>
          </div>
        </div>
      </div>
      <div v-if="searchTextOuter && !readonly" style="cursor: pointer;display: flex;align-items: center">
        <Icon slot="prefix" type="iconfont iconfont icon-clear" @click.stop="handleClear('outer')"/>
      </div>
      <div v-else style="width: 16px;height: 16px">
      </div>
    </div>
    <DkModal width="1200"
             @modalOk="modalClick"
             @on-visible-change="onVisibleChange" v-model="mapShowFlag"
             title="请选择地图定位">
      <div style="display: flex;">
        <div style="display: flex;align-items: center;width: 60%;">
          <span>详细地址</span>
          <div style="width: 85%;position: relative;padding-left:10px">
            <Input ref="input-inner" @on-focus="onFocus('inner')" @on-blur="onBlur('inner')" style="width: 100%;"
                   v-model="searchTextInner" size="small" :placeholder="inputPlaceholder"
                   @on-change="inputChange('inner')" clearable
                   @keydown.native="handleKeyDown($event,'inner')"
                   :clearable="false"></Input>
            <div v-if="focusFlagInner"
                 class="map-select-class">
              <div @click.stop="chooseAddress(item,'inner')" class="search-result-item"
                   tabindex="0" @keydown.stop="handleItemKeyDown($event,'inner',index)"
                   @blur="onBlur('inner')" :ref="'inner_' + index"
                   v-for="(item,index) in searchTextListInner" :style="{borderTop:index===0?'':'1px solid #b6b6b6'}"
                   style="cursor:pointer;width: 100%;padding: 3px;" :key="index">
                <div style="display: flex;align-items: center;">
                  <div
                    style="width:16px;height:16px;border-radius: 50%;background: red;display: flex;justify-content: center;align-items: center;color: #fff;">
                    {{ index + 1 }}
                  </div>
                  <div style="margin-left: 5px;font-size: 12px;font-weight: bold;">{{ item.title }}</div>
                </div>
                <div style="margin-top: 5px;font-size: 12px;color:#898989;">{{ item.address }}</div>
              </div>
            </div>
          </div>
          <div v-if="searchTextInner && !readonly" style="cursor: pointer">
            <Icon slot="prefix" type="iconfont iconfont icon-clear" @click.stop="handleClear('inner')"/>
          </div>
          <div v-else style="width: 16px;height: 16px">
          </div>
        </div>
        <div style="display: flex;align-items: center;width: 35%;">
          <span>坐标</span>
          <Input style="width: 85%;padding-left:10px" :value="getLatlngStr()" size="small" disabled></Input>
        </div>
      </div>
      <div :id="'container-'+$route.name" style="width: 100%;height: 600px;margin-top: 10px;" v-if="mapShowFlag"></div>
    </DkModal>
    <!--    弹窗外的地图-->
    <div :id="'hidden-container-'+$route.name" style="display: none"></div>
  </div>
</template>
<script>

import BaiduMap from '@/libs/base/baidu-map'

export default {
  name: 'RegionsChoose',
  props: {
    value: {},
    //默认值
    defaultValue: {
      type: String,
      default: null
    },
    //组件选项
    options: {
      type: Array,
      default: () => []
    },
    //是否只读
    readonly: {
      type: Boolean,
      default: false
    },
  },
  watch: {
    defaultValue(n, o) {
      this.searchTextOuter = n;
    },
    searchTextOuter(n,o){
      if(n){
        setTimeout(()=>{
          // 清除提示信息
          this.clearErrMessage();
        },300)
      }
    }
  },
  model: {
    prop: 'value',
    event: 'on-choose'
  },
  data() {
    return {
      inputPlaceholder: '',      // 提示信息
      city: '',                  // 默认城市
      cityOptions: [],           // 城市的
      focusFlagOuter: false,
      focusFlagInner: false,
      searchTextListInner: [],
      searchTextListOuter: [],
      latlng: {lat: 39.930779, lng: 116.362353},
      searchTextInner: null,
      searchTextOuter: null,
      mapShowFlag: false,
      BMap: null,
      map: null,
      openItem: null,
      data: []
    }
  },
  mounted() {
    BaiduMap.init().then((BMap) => {
      this.BMap = BMap
      let map = new BMap.Map('hidden-container-' + this.$route.name, {enableMapClick: false}); // 创建Map实例
      // map.centerAndZoom(new this.BMap.Point(this.latlng.lng, this.latlng.lat), 15); // 初始化地图,设置中心点坐标和地图级别
      map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
      map.centerAndZoom(this.city ? this.city : '全国', 13)
      map.addEventListener('click', ((e) => {
        this.mapClick(e)
      }));
      this.map = map
    })
  },
  methods: {
    /**
     * @desc   : 打开地图
     * @author : 周兴
     * @date   : 2022/6/15 16:36
     */
    openMap() {
      if (!this.readonly) {
        this.mapShowFlag = true;
        this.$nextTick(() => {
          BaiduMap.init().then((BMap) => {
            this.BMap = BMap
            let map = new BMap.Map('container-' + this.$route.name, {enableMapClick: false}); // 创建Map实例
            // map.centerAndZoom(new this.BMap.Point(this.latlng.lng, this.latlng.lat), 15); // 初始化地图,设置中心点坐标和地图级别
            map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
            map.centerAndZoom(this.city ? this.city : '全国', 13)
            map.addEventListener('click', ((e) => {
              this.mapClick(e)
            }));
            this.map = map
          })
        })
      }
    },
    /**
     * @desc   : 点击切换到选择数据中
     * @author : 周兴
     * @date   : 2022/6/11 14:35
     */
    handleKeyDown(e, type) {
      if (this.readonly) {
        return;
      }
      switch (e.code) {
        case 'Tab':
          //收缩选择框，跳转到下一个控件
          if (type === 'outer') {
            setTimeout(() => {
              this.chooseAddress(this.openItem, type);
              this.focusFlagOuter = false;
            }, 300)
          } else {
            this.focusFlagInner = false;
          }
          break
        case 'ArrowDown':
          //向下进入选择数据里
          if (this.$refs[type + '_0']
            && this.$refs[type + '_0'].length > 0) {
            setTimeout(() => {
              this.$refs[type + '_0'][0].focus();
            }, 100)
          }
          break
      }
    },
    /**
     * @desc   : 判断是否聚焦
     * @author : 周兴
     * @date   : 2022/6/11 16:09
     */
    checkSearchFocus(type) {
      setTimeout(() => {
        // 如果活动元素不是下拉的，就隐藏
        if (document.activeElement.className !== 'search-result-item') {
          if (type === 'outer') {
            this.focusFlagOuter = false;
          } else {
            this.focusFlagInner = false;
          }
        }
      }, 300)
    },
    /**
     * @desc   : 点击明细进行切换行
     * @author : 周兴
     * @date   : 2022/6/11 14:33
     */
    handleItemKeyDown(e, type, index) {
      switch (e.code) {
        case 'ArrowDown':
          //向下进入选择数据里
          if (this.$refs[type + '_' + (index + 1)]
            && this.$refs[type + '_' + (index + 1)].length > 0) {
            setTimeout(() => {
              this.$refs[type + '_' + (index + 1)][0].focus();
            }, 100)
          }
          break;
        case 'ArrowUp':
          //向上进入选择数据里
          if (this.$refs[type + '_' + (index - 1)]
            && this.$refs[type + '_' + (index - 1)].length > 0) {
            setTimeout(() => {
              this.$refs[type + '_' + (index - 1)][0].focus();
            }, 100)
          }
          break;
        case 'Enter':
        case 'Tab':
          // 选择数据
          if (type === 'outer') {
            if (this.searchTextListOuter[index]) {
              this.openItem = this.searchTextListOuter[index];
              this.searchTextOuter = this.openItem.title;
              this.chooseAddress(this.openItem, type);
              this.focusFlagOuter = false;
            }
          } else {
            if (this.searchTextListInner[index]) {
              this.openItem = this.searchTextListInner[index];
              this.chooseAddress(this.openItem, type);
              this.focusFlagInner = false;
            }
          }
          break;
      }
    },
    /**
     * @desc   : 点确定
     * @author : 周兴
     * @date   : 2022/6/9 16:30
     */
    modalClick() {
      this.searchTextOuter = this.searchTextInner
      this.searchTextListOuter = [...this.searchTextListInner]
      if (this.searchTextListInner[0]) {
        this.openItem = this.searchTextListInner[0];
        this.chooseAddress(this.openItem, 'inner');
        this.focusFlagInner = false;
      }
      this.mapShowFlag = false
      this.focusFlagOuter = false;
    },
    /**
     * @desc   : 格式化经纬度地址
     * @author : 周兴
     * @date   : 2022/6/9 16:29
     */
    getLatlngStr() {
      if (!this.latlng) {
        return ''
      }
      return parseFloat(this.latlng.lat).toFixed(6) + ',' + parseFloat(this.latlng.lng).toFixed(6)
    },
    /**
     * @desc   : 点击地图
     * @author : 周兴
     * @date   : 2022/6/9 15:02
     */
    mapClick(e, flag) {
      this.focusFlagInner = true;
      let geoc = new this.BMap.Geocoder();
      geoc.coord_type = 'gcj02'
      geoc.getLocation(e.point, (rs) => {
        this.latlng = e.point
        this.map.clearOverlays()
        this.map.addOverlay(
          new this.BMap.Marker(new this.BMap.Point(e.point.lng, e.point.lat))
        )
        this.searchTextListInner = rs.surroundingPois
        if (!flag) {
          this.onFocus('inner', true)
          // 光标进入第一个数据
          if (this.$refs['inner_0']
            && this.$refs['inner_0'].length > 0) {
            setTimeout(() => {
              this.$refs['inner_0'][0].focus();
            }, 100)
          }
        } else {
          this.onBlur('inner')
        }
      }, {poiRadius: 300})
    },
    /**
     * @desc   : 选择地址
     * @author : 周兴
     * @date   : 2022/6/9 16:01
     */
    chooseAddress(item, type) {
      if (type === 'inner') {
        this.searchTextInner = item.title
        this.searchTextListInner = []
        this.latlng = item.point
        this.map.centerAndZoom(item.point, 15);
        this.focusFlagInner = false;
      } else {
        this.searchTextOuter = item.title
        this.searchTextListOuter = []
        this.latlng = item.point
        this.focusFlagOuter = false;
      }
      this.openItem = item;
      //选择数据
      this.chooseData();
    },
    /**
     * @desc   : 选择数据
     * @author : 周兴
     * @date   : 2022/6/9 16:19
     */
    chooseData() {
      if (this.openItem) {
        let address = {}
        // 通过经纬度反向解析为了获取 区
        let geoc = new this.BMap.Geocoder();
        geoc.coord_type = 'gcj02'
        geoc.getLocation(this.openItem.point, (rs) => {
          if (rs && rs.addressComponents) {
            this.openItem.district = rs.addressComponents.district
            this.openItem.province = rs.addressComponents.province
            this.openItem.city = rs.addressComponents.city
          }
          let flag = false;
          // 如果区没有就用市来当
          if (!this.openItem.district) {
            this.openItem.district = this.openItem.city;
            flag = true;
          }
          // 如果市为空用区来当
          if (!this.openItem.city) {
            this.openItem.city = this.openItem.district;
            flag = true;
          }
          address.addressArea = {}
          address.addressArea.province = this.openItem.province ? this.openItem.province.replace('市', '') : '';
          address.addressArea.city = this.openItem.city;
          address.addressArea.district = this.openItem.district;
          address.addressName = this.openItem.title;
          address.addressGcj02 = {};
          address.addressGcj02.latitude = this.openItem.point.lat;
          address.addressGcj02.longitude = this.openItem.point.lng;
          if (this.openItem.province === '北京市' || this.openItem.province === '天津市'
            || this.openItem.province === '重庆市' || this.openItem.province === '上海市'
            || flag) {
            address.addressFull = this.openItem.province
              + this.openItem.district + (this.openItem.title.endsWith('市') ? '' : this.openItem.title);
          } else {
            address.addressFull = this.openItem.province + this.openItem.city
              + this.openItem.district + (this.openItem.title.endsWith('市') ? '' : this.openItem.title);
          }
          if (this.openItem.province === '北京市' || this.openItem.province === '天津市'
            || this.openItem.province === '重庆市' || this.openItem.province === '上海市') {
            address.addressFull = this.openItem.province.slice(0, 2) + address.addressFull
          }
          // console.log('open', this.openItem)
          this.$emit('on-choose', address)
        })
      } else {
        this.searchTextOuter = null;
        this.searchTextInner = null;
        this.$emit('on-choose', null)
      }
    },
    /**
     * @desc   : 清空数据
     * @author : 周兴
     * @date   : 2022/8/27 16:24
     */
    clear() {
      this.openItem = null;
      this.searchTextInner = null;
      this.searchTextOuter = null;
    },
    /**
     * @desc   : 清空数据
     * @author : 周兴
     * @date   : 2022/6/9 17:13
     */
    handleClear(type) {
      this.openItem = null;
      this.chooseData();
      if (type === 'inner') {
        this.searchTextInner = null;
      } else {
        this.searchTextOuter = null;
      }
    },
    /**
     * @desc   : desc
     * @author : 周兴
     * @date   : 2022/6/9 16:17
     */
    handleSelectChange(e) {
      //改变城市，需要清空数据
      this.openItem = null;
      this.chooseData();
      this.searchTextOuter = null;
      //切换城市
      this.map.centerAndZoom(this.city ? this.city : '全国', 13)
    },
    /**
     * @desc   : 聚焦
     * @author : 周兴
     * @date   : 2022/6/9 16:01
     */
    onFocus(type, flag) {
      if (this.readonly) {
        return;
      }
      if (!flag) {
        this.inputChange(type === 'inner' ? 'inner' : 'outer')
      }
    },
    /**
     * @desc   : 失去焦点
     * @author : 周兴
     * @date   : 2022/6/9 16:01
     */
    onBlur(type) {
      if (this.readonly) {
        return;
      }
      // setTimeout(() => {
      if (type === 'inner') {
        if (this.openItem) {
          // 如果文本框中跟openItem不一致说明是改过
          if (this.openItem.title !== this.searchTextInner) {
            this.searchTextInner = this.openItem.title;
          }
        } else {
          // 如果openItem为空，选择中有数据，默认取第一个,否则清空
          if (this.searchTextListInner && this.searchTextListInner.length > 0) {
            this.openItem = {...this.searchTextListInner[0]}
            this.searchTextInner = this.openItem.title;
          } else {
            this.searchTextInner = null;
          }
        }
        //判断是否隐藏下拉数据
        this.checkSearchFocus(type);
      } else {
        if (this.openItem) {
          // 如果文本框中跟openItem不一致说明是改过
          if (this.openItem.title !== this.searchTextOuter) {
            this.searchTextOuter = this.openItem.title;
          }
        } else {
          // 如果openItem为空，选择中有数据，默认取第一个,否则清空
          if (this.searchTextListOuter && this.searchTextListOuter.length > 0) {
            this.openItem = {...this.searchTextListOuter[0]}
            this.searchTextOuter = this.openItem.title;
          } else {
            this.searchTextOuter = null;
          }
        }
        //判断是否隐藏下拉数据
        this.checkSearchFocus(type);
      }
      // }, 300)
    },
    /**
     * @desc   : 初始化地图，设置中心点坐标
     * @author : 周兴
     * @date   : 2022/6/9 15:08
     */
    onSearchComplete(result) {
      this.map.centerAndZoom(result.Cr[0].point, 15); // 初始化地图,设置中心点坐标和地图级别
    },
    /**
     * @desc   : 展开地图
     * @author : 周兴
     * @date   : 2022/6/11 16:31
     */
    onVisibleChange(val) {
      if (val) {
        this.searchTextInner = this.searchTextOuter
        if (this.openItem) {
          setTimeout(() => {
            this.mapClick(this.openItem, true)
            this.map.centerAndZoom(this.openItem.point, 15);
          }, 200)
        } else {
          this.latlng = null;
        }
      }
    },
    /**
     * @desc   : 值改变事件
     * @author : 周兴
     * @date   : 2022/6/9 14:58
     */
    inputChange(type) {
      if (type === 'outer') {
        // 如果没有数据就不出现下拉
        if (!this.searchTextOuter) {
          this.focusFlagOuter = false;
          return;
        } else {
          this.focusFlagOuter = true;
        }
        let options = {
          onSearchComplete: ((result) => {
            if (!result) {
              this.searchTextListOuter = []
              return
            }
            let count = result.getCurrentNumPois();
            let arr = []
            for (let i = 0; i < count; i++) {
              arr.push(result.getPoi(i))
            }
            this.searchTextListOuter = arr
          })
        }
        let local = new this.BMap.LocalSearch(this.map, options);
        local.search(this.searchTextOuter);
      } else {
        // 如果没有数据就不出现下拉
        if (!this.searchTextInner) {
          this.focusFlagInner = false;
          return;
        } else {
          this.focusFlagInner = true;
        }
        let options = {
          onSearchComplete: ((result) => {
            if (!result) {
              this.searchTextListInner = []
              return
            }
            let count = result.getCurrentNumPois();
            let arr = []
            for (let i = 0; i < count; i++) {
              arr.push(result.getPoi(i))
            }
            this.searchTextListInner = arr
          })
        }
        let local = new this.BMap.LocalSearch(this.map, options);
        local.search(this.searchTextInner);
      }
    },
    // stopMove(){
    //   console.log('dddd')
    //   let m = function(e){e.preventDefault();};
    //   document.body.style.overflow='hidden';
    //   document.addEventListener("scroll",m,{ passive:false });//禁止页面滑动
    // },
    // //开启页面滚动
    // move(){
    //   let m =function(e){e.preventDefault();};
    //   document.body.style.overflow='';//出现滚动条
    //   document.removeEventListener("scroll",m,{ passive:true });
    // }
  },
  created() {
    // 给城市加载上全国
    this.cityOptions = this.options;
    let filterOpts = this.cityOptions.filter(it => it.key === '全国');
    if (!filterOpts || filterOpts.length === 0) {
      this.cityOptions.push({key: '全国', value: '全国'})
    }
    this.city = this.cityOptions[0].value;
    this.inputPlaceholder = this.$t('inputWords', {'search-name': this.$t('addressFull')})
    this.searchTextOuter = this.defaultValue;
  }
}
</script>
<style scoped>

.search-result-item{
  height: 45px !important;
}

.search-result-item:hover {
  background-color: #a7d6ff;
}

.search-result-item:focus {
  background-color: #a7d6ff;
  /*不然有黑色边框*/
  outline: none;
}

.map-select-outer-class {
  border: 1px solid #b6b6b6;
  height: 300px;
  width: 400px;
  background: #fff;
  position: absolute;
  z-index: 666;
  overflow-y: auto;
}

.map-select-class {
  border: 1px solid #b6b6b6;
  height: 300px;
  width: 100%;
  background: #fff;
  position: absolute;
  z-index: 666;
  overflow-y: auto;
}

.search-class {
  cursor:pointer;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  top:0;
  right: 0;
  align-items: center;
  justify-content: center;
  color: #a0a5ac;
  z-index: 88;
}

xm-select > .xm-label.single-row{
  right: 16px !important;
}

/*只读颜色*/
.readonly-input > /deep/ .ivu-input {
  background-color: #f3f3f3;
}

/deep/.ivu-input{
  padding-right: 23px !important;
}

</style>
