<template>
  <div class="nutui-demo-page" style="height: 100vh; display: flex; flex-direction: column">
    <!-- 顶部搜索框 -->
    <nut-searchbar v-model="searchText" placeholder="请输入地址" @focus="onFocus" @change="onInput" @clear="onClear" @blur="onBlur" style="margin: 0">
      <template #leftout>
        <div class="flex items-center">
          <span class="text-[32rpx] font-400">{{ userStore.deviceLocation.province }}</span>
          <ChevronDown @click="toAdministrativePage"/>
        </div>
      </template>
      <template #leftin>
        <Search class="text-[#929297]" />
      </template>
    </nut-searchbar>
    <!-- 地图容器 -->
    <div id="mapDiv" style="flex: 1; width: 100%"></div>
    <!-- 底部弹出层Popup -->
    <nut-popup
      position="bottom"
      :visible="showPopup"
      :close-on-click-overlay="false"
      :overlay="false"
      pop-class="rounded-[32rpx_32rpx_0_0] min-h-[600rpx] max-h-[60vh]! overflow-y-auto"
      @click-overlay="() => {}">
      <div v-if="promptList.length" class="px-[32rpx] py-[24rpx]">
        <div
          v-for="(item, index) in promptList"
          :key="index"
          @click="searchByPrompt(item)"
          style="padding: 10px 0; border-bottom: 1px solid #f0f0f0; cursor: pointer; color: #333">
          {{ item.adminName ? `在${item.adminName}搜索${item.keyword}` : item.keyword }}
        </div>
      </div>
      <div v-if="suggestList.length" class="px-[32rpx] py-[24rpx]">
        <div v-for="item in suggestList" :key="item.hotPointID || item.id || item.name" @click="selectSuggest(item)" class="flex items-center mb-[60rpx]">
          <img src="/images/map/address-choose.png" alt="icon" class="w-[56rpx] h-[56rpx] mr-[14rpx]">
          <div class="flex flex-col">
            <p class="text-[#1D86FF] font-600 text-[36rpx]">{{ item.name }}</p>
            <div class="flex items-center text-[32rpx] text-[#666] mt-[16rpx]">{{ item.province }}-{{ item.city || item.county }}-{{ item.address }}</div>
          </div>
        </div>
      </div>
      <div v-if="!suggestList.length && !promptList.length" class="p-[48rpx] text-center text-[#aaa]">暂无结果</div>
    </nut-popup>
  </div>
</template>

<script lang="ts" setup>
  import { mapKey } from "@/utils/useMap";
  import { getRequest } from "@/api/customFetch";
  import { getMapSearch } from "@/api/interfaceDocument";
  import { useUserStore } from "@/store/user";
  import { Search, ChevronDown } from "lucide-vue-next";
  import { useRouter } from "vue-router";

  const router = useRouter()
  const userStore = useUserStore();

  const searchText = ref("");
  const suggestList = ref<any[]>([]);
  const promptList = ref<any[]>([]);
  const showPopup = ref(false);
  let map: any = null;
  const defaultLng = userStore.getCoordinate.longitude || 121.5097620985243;
  const defaultLat = userStore.getCoordinate.latitude || 31.30658013237847;
  const defaultZoom = 16;
  // 上海市行政区划国标码
  const defaultSpecify = "156310000";

  // 动态加载天地图API
  function loadTdtScript() {
    return new Promise<void>((resolve, reject) => {
      if ((window as any).T) return resolve();
      const script = document.createElement("script");
      script.type = "text/javascript";
      script.src = `http://api.tianditu.gov.cn/api?v=4.0&tk=${mapKey}`;
      script.onload = () => resolve();
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }

  // 初始化地图
  function initMap() {
    // @ts-ignore
    map = new window.T.Map("mapDiv");
    // @ts-ignore
    map.centerAndZoom(new window.T.LngLat(defaultLng, defaultLat), defaultZoom);
    setIcon(defaultLng, defaultLat, true);
  }

  onMounted(async () => {
    await loadTdtScript();
    initMap();
  });

  // 获取当前地图行政区划码
  function getMapSpecify() {
    // 这里可根据实际业务动态获取当前地图中心点的行政区划码
    // 目前直接返回北京国标码
    return defaultSpecify;
  }

  // 获取当前地图范围和级别
  function getMapBoundAndLevel() {
    if (!map) {
      return { specify: getMapSpecify(), level: defaultZoom };
    }
    // @ts-ignore
    const bounds = map.getBounds();
    // @ts-ignore
    const level = map.getZoom();
    // @ts-ignore
    const sw = bounds.getSouthWest();
    // @ts-ignore
    const ne = bounds.getNorthEast();
    const mapBound = `${sw.lng},${sw.lat},${ne.lng},${ne.lat}`;
    return { mapBound, level, specify: getMapSpecify() };
  }

  // 地址搜索（V2.0行政区划区域搜索服务）
  let suggestTimer: any = null;
  function onInput(val: string) {
    if (suggestTimer) clearTimeout(suggestTimer);
    suggestTimer = setTimeout(() => {
      fetchSuggest(val);
    }, 300);
    showPopup.value = true;
  }

  function onFocus() {
    showPopup.value = true;
  }

  function onClear() {
    suggestList.value = [];
    promptList.value = [];
    showPopup.value = false;
  }

  function onBlur() {
    // 不自动关闭popup，交互更友好
  }

  function fetchSuggest(keyword: string) {
    if (!keyword) {
      suggestList.value = [];
      promptList.value = [];
      return;
    }
    const { specify } = getMapBoundAndLevel();
    const postStr = JSON.stringify({
      keyWord: keyword,
      queryType: "12",
      start: 0,
      count: 10,
      specify,
      show:2
    });

    getRequest(getMapSearch(), { postStr: encodeURIComponent(postStr), type: "query", tk: mapKey }).then((data: any) => {
      if (data && data.resultType === 1 && data.pois) {
        suggestList.value = data.pois
        promptList.value = [];
      } else if (data && data.prompt && Array.isArray(data.prompt)) {
        promptList.value = data.prompt;
        suggestList.value = [];
      } else {
        suggestList.value = [];
        promptList.value = [];
      }
    });
  }

  function setIcon(lng: any, lat: any, isClear: boolean) {
    if (isClear) {
      map.clearOverLays();
    }
    const point = new window.T.LngLat(lng, lat);
    const marker = new window.T.Marker(point);
    map.addOverLay(marker);
  }

  function selectSuggest(item: any) {
    searchText.value = item.name;
    showPopup.value = false;
    if (item.lonlat && map) {
      const [lng, lat] = item.lonlat.split(",").map(Number);
      // @ts-ignore
      map.centerAndZoom(new window.T.LngLat(lng, lat), defaultZoom);
      setIcon(lng, lat, true);
      let address = item.address + item.name;
      userStore.setAddress(address);
      userStore.setCoordinate(lng, lat);
    }
  }

  function searchByPrompt(item: any) {
    searchText.value = item.keyword;
    showPopup.value = true;
    fetchSuggest(item.keyword);
  }

  const toAdministrativePage = () => {
    router.push({path:'/location/administrative'})
  }
</script>

<!-- tailwindcss 样式全部用类名实现 -->
<style scoped></style>
