<template>
  <div class="searchMap">
    <div class="grid-input">
      <img src="./img/back-icon.png" alt="" class="back-icon" v-if="name && show" @click="show=false">
      <img src="./img/search-icon.png" alt="" class="search-icon" v-else>
      <input type="text" class="input" placeholder="请输入姓名、房屋信息" v-model="name" maxlength="10" confirm-type="search"
             @confirm="search"/>
      <div class="clear-btn">
        <img src="./img/del-icon.png" alt="" class="del-icon" v-if="name" @click="clear">
      </div>
      <span class="search-btn" @click="search">搜索</span>
    </div>
    <div class="search-list" v-if="show">
      <div class="title border">
        <img src="./img/search-icon.png" alt="" class="search-icon">{{ name }}
      </div>
      <div class="item border" v-for="(item, index) in buildList" :key="index" @click="getBuildingInfo(item)">
        <img src="./img/user-icon.png" alt="" class="search-icon user-icon">
        <div class="item-content">
          <h3>{{ item.residentName }}</h3>
          <p>{{ item.areaName || '' }}{{ item.createAddress }}</p>
        </div>
      </div>
    </div>
    <div class="build-btn" @click="toList()">
      <img src="./img/build-icon.png" alt=""> 楼栋<br/>列表
    </div>
    <div class="map-content">
      <AiTMap :map.sync="map" :lib.sync="lib" :ops="ops" :libraries="['service', 'tools']"/>
    </div>
    <u-popup v-model="showPop" mode="bottom" border-radius="14">
      <div class="popup">
        <div class="bg"></div>
        <div class="title">{{ detailInfo.house.createAddress || '' }}</div>
        <p class="address">{{ detailInfo.community.address || '' }}</p>
        <div class="info-flex">
          <span class="label">所属社区</span>
          <span class="value">{{ detailInfo.build.areaName }}</span>
        </div>
        <div class="info-flex">
          <span class="label">所属小区</span>
          <span class="value">{{ detailInfo.build.communityName }}</span>
        </div>
        <div class="info-flex">
          <span class="label">房屋类型</span>
          <span class="value">{{ $dict.getLabel('communityBuildingType', detailInfo.house.buildingType) }}</span>
        </div>
        <div class="info-flex">
          <span class="label">所属网格</span>
          <span class="value">{{ detailInfo.gird.girdName || '' }}</span>
        </div>
        <div class="info-flex">
          <span class="label">网格管理员</span>
          <span class="value">{{ detailInfo.gird.girdMemberNames || '' }}</span>
        </div>
        <div class="info-flex">
          <span class="label">楼栋长</span>
          <span
              class="value">{{ detailInfo.build.managerName || '' }}&nbsp;&nbsp;{{
              detailInfo.build.managerPhone || ''
            }}
            <img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(detailInfo.build.managerPhone)"
                 class="phone-icon" v-if="detailInfo.build.managerPhone">
          </span>
        </div>
      </div>
      <div class="popup-btn" @click="toDetail(detailInfo.build.id)">查看楼栋模型</div>
    </u-popup>
    <u-popup v-model="buildPopup" mode="bottom" border-radius="14">
      <div class="popup">
        <div class="bg"/>
        <div class="title">{{ building.createAddress || '' }}</div>
        <div class="info-flex">
          <span class="label">所属社区</span>
          <span class="value">{{ building.areaName }}</span>
        </div>
        <div class="info-flex">
          <span class="label">所属小区</span>
          <span class="value">{{ building.communityName }}</span>
        </div>
        <div class="info-flex">
          <span class="label">房屋类型</span>
          <span class="value">{{ $dict.getLabel('communityBuildingType', building.buildingType) }}</span>
        </div>
        <div class="info-flex">
          <span class="label">所属网格</span>
          <span class="value" v-text="building.girdName||''"/>
        </div>
        <div class="info-flex">
          <span class="label">网格管理员</span>
          <span class="value" v-text="building.girdMemberNames||''"/>
        </div>
        <div class="info-flex">
          <span class="label">楼栋长</span>
          <span
              class="value">{{ building.managerName || '' }}&nbsp;&nbsp;{{ building.managerPhone || '' }}
            <img :src="$cdn + 'common/phone.png'" alt="" @click="callPhone(detailInfo.build.managerPhone)"
                 class="phone-icon" v-if="detailInfo.build.managerPhone">
          </span>
        </div>
      </div>
      <div class="popup-btn" @click="toDetail(building.id)">查看楼栋模型</div>
    </u-popup>
  </div>
</template>

<script>
import {mapState} from 'vuex'

export default {
  data() {
    return {
      ops: {},
      lib: null,
      map: null,
      markerArr: [],
      show: false,
      value: '',
      ClusterBubble: null,
      name: '',
      buildList: [],
      detailInfo: {
        house: {},
        build: {},
        community: {},
        gird: {}
      },
      showPop: false,
      retryMapCount: 0,
      building: {},
      buildPopup: false
    }
  },
  computed: {...mapState(['user', 'config'])},
  mounted() {
    this.getCommunityList().then(points => {
      this.getMarkerCluster(points)
    })
  },
  onShow() {
    document.title = "以房找人"
  },
  created() {
    this.$dict.load("communityBuildingType")
  },
  methods: {
    getCommunityList() {
      return this.$http.post('/app/appcommunitybuildinginfo/listByBuilding', null, {
        params: {
          current: 1,
          size: 1000000,
          areaId: this.user.areaId
        }
      }).then(res => {
        if (res?.data) {
          this.buildList = res.data
          return res.data.map(item => {
            return {
              ...item,
              lnglat: [item.lng, item.lat],
              buildingNumber: item.name || item.buildingNumber,
              communityName: item.name || item.communityName,
            }
          })
        }
      })
    },
    getMarkerCluster(points, count = 0) {
      let {lib: TMap, map} = this
      if (map) {
        map.setCenter(this.config.latlng)
        let MarkerCluster = new TMap.MarkerCluster({
          map, gridSize: 60,
          enableDefaultStyle: false, // 关闭默认样式
          geometries: points?.map(e => ({
            position: new TMap.LatLng(e.lat, e.lng),
            content: `${e.createAddress} | ${e.houseNum}户`,
            properties: {...e}
          })) || [],
          zoomOnClick: true
        })
        let geometries = [], marker, markers = []
        MarkerCluster.on('cluster_changed', () => {
          if (markers.length) {
            markers.forEach(function (item) {
              item.destroy();
            })
            markers = [];
          }
          geometries = []
          let clusters = MarkerCluster.getClusters()
          clusters.forEach((item) => {
            if (item.geometries?.length > 1) {
              //聚合样式
              geometries.push({
                styleId: 'cluster',
                position: item.center,
                properties: {...item},
                content: item.geometries.length?.toString() || "0"
              })
            } else {
              //点标记样式
              // 创建气泡DOM元素
              class ClusterBubble extends TMap.DOMOverlay {
                constructor(options) {
                  super(options);
                }

                onInit(options) {
                  this.content = options.content;
                  this.position = options.position;
                };

                onDestroy() {
                  this.dom.removeEventListener('click', this.onClick);
                  this.removeAllListeners();
                }

                createDOM() {
                  let dom = document.createElement('div');
                  dom.classList.add('marker');
                  dom.innerText = this.content;

                  // 监听点击事件，实现zoomOnClick
                  this.onClick = this.onClick.bind(this);
                  // pc端注册click事件，移动端注册touchend事件
                  dom.addEventListener('click', this.onClick);
                  dom.addEventListener('touchend', this.onClick);
                  return dom;
                };

                updateDOM() {
                  if (!this.map) {
                    return;
                  }
                  // 经纬度坐标转容器像素坐标
                  let pixel = this.map.projectToContainer(this.position);

                  // 使文本框中心点对齐经纬度坐标点
                  let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
                  let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
                  this.dom.style.transform = `translate(${left}, ${top})`;
                  this.emit('dom_updated');
                };

                onClick() {
                  this.emit('click');
                }
              }

              let {content} = item.geometries?.[0] || {},
                  overlay = new ClusterBubble({map, position: item.center, content})
              overlay.on('click', () => {
                this.buildPopup = true
                this.building = item.geometries?.[0]?.properties || {}
              })
              markers.push(overlay)
            }
          });
          if (marker) {
            marker.setGeometries(geometries)
          } else {
            marker = new TMap.MultiMarker({
              map, enableCollision: true, geometries,
              styles: {
                cluster: new TMap.MarkerStyle({
                  width: 48,
                  height: 48,
                  anchor: {x: 24, y: 24},
                  src: this.$cdn + "/map/cluster.png",
                  color: '#fff',
                  // direction: 'center',
                  size: 18
                })
              },
            })
            marker.on('click', (e) => {
              let {bounds} = e.geometry.properties
              map.fitBounds(bounds)
            })
          }
        })
        return Promise.resolve()
      } else {
        if (count < 5) {
          setTimeout(() => {
            return this.getMarkerCluster(points, ++count)
          }, 1000)
        } else Promise.reject("加载失败")
      }
    },
    clear() {
      this.name = ''
    },
    search() {
      this.buildList = []
      this.$http.post('/app/appcommunityhouseinfo/queryHouseByName', null, {
        params: {
          current: 1,
          size: 20,
          areaId: this.user.areaId,
          name: this.name
        }
      }).then(res => {
        if (res.code == 0 && res.data.length) {
          this.show = true
          this.buildList = res.data
          const points = res.data.map(item => {
            return {
              lnglat: [item.lng, item.lat],
              id: item.id,
              corpId: item.corpId,
              areaName: item.areaName,
              buildingNumber: item.name || item.buildingNumber,
              communityName: item.name || item.communityName,
            }
          })
          this.getMarkerCluster(points)
        } else {
          this.show = false
          this.$u.toast('未搜索到结果，请换个关键字重试！')
        }
      })
    },
    getBuildingInfo(item) {
      this.$http.post(`/app/appcommunityhouseinfo/queryDetailByIdWithBuilding?buildId=${item.buildingId}&houseId=${item.id}`).then(res => {
        if (res?.data) {
          this.show = false
          this.showPop = true
          this.detailInfo = res.data
        }
      })
    },
    toList() {
      uni.navigateTo({url: './list'})
    },
    callPhone(phone) {
      uni.makePhoneCall({phoneNumber: phone})
    },
    toDetail(id) {
      uni.navigateTo({url: `./detail?id=${id}`})
    }
  }
}
</script>

<style lang="scss" scoped>
.searchMap {
  height: 100vh;

  .grid-input {
    width: calc(100% - 64px);
    height: 88px;
    background: #FFF;
    box-shadow: 0 4px 8px 0 rgba(192, 185, 185, 0.5);
    border-radius: 16px;
    position: fixed;
    top: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 99999;
    padding: 16px 20px;
    box-sizing: border-box;

    .search-icon {
      width: 48px;
      height: 48px;
      margin-right: 16px;
    }

    .input {
      display: inline-block;
      padding: 8px 0;
      height: 32px;
      line-height: 32px;
      width: calc(100% - 220px);
      font-size: 28px;
      font-family: MicrosoftYaHei;
      color: #666;
    }

    .back-icon {
      width: 16px;
      height: 32px;
      margin-right: 24px;
      vertical-align: super;
    }

    .clear-btn {
      display: inline-block;
      width: 32px;
      height: 32px;
      margin-right: 30px;
    }

    .del-icon {
      width: 32px;
      height: 32px;
      vertical-align: super;
    }

    .search-btn {
      display: inline-block;
      width: 80px;
      height: 32px;
      line-height: 32px;
      text-align: right;
      font-size: 28px;
      font-family: MicrosoftYaHei;
      color: #1365DD;
      border-left: 1px solid #DEDFE0;
      vertical-align: top;
      margin-top: 12px;
    }
  }

  .search-list {
    position: fixed;
    width: 100%;
    height: calc(100% - 130px);
    overflow-y: scroll;
    top: 128px;
    left: 0;
    box-sizing: border-box;
    z-index: 99999;

    .search-icon {
      width: 36px;
      height: 36px;
      margin-right: 16px;
      vertical-align: sub;
    }

    .title {
      height: 82px;
      line-height: 82px;
      font-size: 26px;
      font-family: MicrosoftYaHeiSemibold;
      color: #1365DD;
      padding-left: 44px;
      background-color: #fff;
    }

    .item {
      padding: 22px 44px 24px 44px;
      background-color: #fff;
    }

    .item-content {
      display: inline-block;
      width: 610px;
      color: #333;

      h3 {
        font-size: 28px;
        font-family: MicrosoftYaHeiSemibold;
        line-height: 32px;
        margin-bottom: 8px;
      }

      p {
        width: 100%;
        font-size: 24px;
        font-family: MicrosoftYaHei;
        line-height: 32px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
    }

    .user-icon {
      vertical-align: top;
    }

    .border {
      border-bottom: 1px solid #DEDFE1;
    }
  }

  .build-btn {
    width: 80px;
    height: 160px;
    background: #FFF;
    box-shadow: 0 4px 8px 0 rgba(138, 138, 138, 0.5);
    border-radius: 8px;
    position: fixed;
    bottom: 136px;
    right: 24px;
    z-index: 99999;
    padding: 16px 16px 0;
    box-sizing: border-box;
    font-size: 24px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #666;
    line-height: 30px;

    img {
      width: 48px;
      height: 48px;
      margin-bottom: 8px;
    }
  }

  .map-content {
    width: 100%;
    height: 100%;
  }

  .popup {
    padding: 0 32px 16px;

    .bg {
      width: 64px;
      height: 10px;
      background: #CCC;
      border-radius: 6px;
      margin: 32px 0 32px 344px;
    }

    .title {
      font-size: 36px;
      font-family: PingFang-SC-Heavy, PingFang-SC;
      font-weight: 800;
      color: #333;
      line-height: 50px;
      margin-bottom: 24px;
    }

    .info-flex {
      padding: 26px 0 30px 0;
      width: 100%;
      border-bottom: 1px solid #D8DDE6;
      line-height: 40px;
      font-size: 28px;

      .label {
        display: inline-block;
        width: 160px;
        font-weight: 800;
        color: #333;
      }

      .value {
        color: #666;
        font-size: 26px;

        .phone-icon {
          width: 40px;
          height: 40px;
          vertical-align: sub;
          margin-left: 16px;
        }
      }
    }
  }

  .popup-btn {
    width: 100%;
    font-size: 32px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    height: 112px;
    line-height: 112px;
    text-align: center;
    background: #1365DD;
    color: #FFF;
  }

  ::v-deep.marker {
    color: #fff;
    background: #5088FF;
    padding: 0 32px;
    width: fit-content;
    height: 56px;
    border-radius: 52px;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;

    &:before {
      content: " ";
      display: block;
      position: absolute;
      bottom: 0;
      left: 50%;
      width: 0;
      height: 0;
      transform: translate(-50%, 100%);
      border: 12px solid transparent;
      border-top-color: #5088FF;
    }
  }
}
</style>
