<script setup>
import { ref, onMounted } from "vue";
import { get } from "@/utils/request";

const latitude = ref(39.908823);
const longitude = ref(116.39747);
const address = ref("移动地图选择位置");
const currentCity = ref("");
const mapCtx = ref(null);

const keyword = ref("");
const searchResults = ref([]);
const showResults = ref(false);
let searchTimer = null;

onMounted(() => {
  mapCtx.value = uni.createMapContext("pickMap");
  uni.getLocation({
    type: "gcj02",
    success: (res) => {
      latitude.value = res.latitude;
      longitude.value = res.longitude;
      reverseGeocode(res.latitude, res.longitude);
    },
    fail: () => {},
  });
});

const onRegionChange = (e) => {
  if (e.type === "end" || e.detail?.type === "end") {
    mapCtx.value.getCenterLocation({
      success: (res) => {
        latitude.value = res.latitude;
        longitude.value = res.longitude;
        reverseGeocode(res.latitude, res.longitude);
      },
    });
  }
};

const reverseGeocode = async (lat, lng) => {
  try {
    const data = await get("/map/geocoder/reverse", {
      location: `${lat},${lng}`,
    });
    if (data && data.status === 0) {
      const r = data.result;
      const poi = r.pois && r.pois.length > 0 ? r.pois[0].title : "";
      currentCity.value =
        r.address_component?.city || r.ad_info?.city || "";
      address.value =
        poi || r.address || r.formatted_addresses?.recommend || "已定位";
    }
  } catch {
    currentCity.value = "";
    address.value = `${lat.toFixed(6)}, ${lng.toFixed(6)}`;
  }
};

const onSearchInput = () => {
  clearTimeout(searchTimer);
  if (!keyword.value.trim()) {
    searchResults.value = [];
    showResults.value = false;
    return;
  }
  searchTimer = setTimeout(() => {
    searchPlace(keyword.value.trim());
  }, 400);
};

const searchPlace = async (kw) => {
  try {
    const boundary = `nearby(${latitude.value},${longitude.value},50000)`;
    const data = await get("/map/place/search", { keyword: kw, boundary });
    if (data && data.status === 0 && data.data) {
      searchResults.value = data.data.map((item) => ({
        title: item.title,
        address: item.address,
        lat: item.location.lat,
        lng: item.location.lng,
      }));
      showResults.value = true;
    } else {
      searchResults.value = [];
      showResults.value = false;
    }
  } catch {
    searchResults.value = [];
    showResults.value = false;
  }
};

const selectResult = (item) => {
  latitude.value = item.lat;
  longitude.value = item.lng;
  address.value = item.title;
  keyword.value = item.title;
  showResults.value = false;
  searchResults.value = [];
  mapCtx.value.moveToLocation({
    latitude: item.lat,
    longitude: item.lng,
  });
};

const clearSearch = () => {
  keyword.value = "";
  searchResults.value = [];
  showResults.value = false;
};

const confirmLocation = () => {
  uni.$emit("locationPicked", {
    latitude: latitude.value,
    longitude: longitude.value,
    name: address.value,
    city: currentCity.value,
  });
  uni.navigateBack();
};
</script>

<template>
  <view class="pick-page">
    <map
      id="pickMap"
      class="pick-map"
      :latitude="latitude"
      :longitude="longitude"
      :scale="16"
      show-location
      @regionchange="onRegionChange"
    />
    <view class="center-pin">
      <image class="pin-icon" src="/static/marker.svg" mode="aspectFit" />
    </view>

    <!-- 搜索栏 -->
    <view class="search-bar">
      <view class="search-inner">
        <uni-icons type="search" size="18" color="#94a3b8" />
        <input
          v-model="keyword"
          class="search-input"
          placeholder="搜索地点"
          placeholder-class="search-placeholder"
          confirm-type="search"
          @input="onSearchInput"
          @confirm="onSearchInput"
        />
        <view v-if="keyword" class="clear-btn" @tap="clearSearch">
          <uni-icons type="clear" size="18" color="#94a3b8" />
        </view>
      </view>
    </view>

    <!-- 搜索结果列表 -->
    <scroll-view
      v-if="showResults && searchResults.length > 0"
      class="search-results"
      scroll-y
    >
      <view
        v-for="(item, idx) in searchResults"
        :key="idx"
        class="result-item"
        @tap="selectResult(item)"
      >
        <uni-icons type="location" size="18" color="#6366f1" />
        <view class="result-info">
          <text class="result-title">{{ item.title }}</text>
          <text class="result-addr">{{ item.address }}</text>
        </view>
      </view>
    </scroll-view>

    <!-- 底部信息 -->
    <view class="bottom-bar">
      <view class="address-info">
        <uni-icons type="location-filled" size="20" color="#6366f1" />
        <text class="address-text">{{ address }}</text>
      </view>
      <view class="coord-row">
        <text class="coord-text"
          >经度: {{ longitude.toFixed(6) }} 纬度:
          {{ latitude.toFixed(6) }}</text
        >
      </view>
      <button class="confirm-btn" @tap="confirmLocation">确认选点</button>
    </view>
  </view>
</template>

<style scoped>
.pick-page {
  position: relative;
  width: 100vw;
  height: 100vh;
}

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

.center-pin {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -100%);
  pointer-events: none;
  z-index: 10;
}

.pin-icon {
  width: 40px;
  height: 52px;
}

.search-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 24rpx 32rpx;
  padding-top: calc(24rpx + env(safe-area-inset-top));
  z-index: 30;
}

.search-inner {
  display: flex;
  align-items: center;
  background: #ffffff;
  border-radius: 40rpx;
  padding: 0 24rpx;
  height: 80rpx;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
  gap: 12rpx;
}

.search-input {
  flex: 1;
  font-size: 28rpx;
  color: #1e293b;
  height: 80rpx;
}

.search-placeholder {
  color: #94a3b8;
}

.clear-btn {
  padding: 8rpx;
}

.search-results {
  position: absolute;
  top: calc(120rpx + env(safe-area-inset-top));
  left: 32rpx;
  right: 32rpx;
  max-height: 500rpx;
  background: #ffffff;
  border-radius: 16rpx;
  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.12);
  z-index: 30;
  overflow: hidden;
}

.result-item {
  display: flex;
  align-items: flex-start;
  padding: 24rpx;
  gap: 16rpx;
  border-bottom: 1rpx solid #f1f5f9;
}

.result-item:last-child {
  border-bottom: none;
}

.result-item:active {
  background: #f8fafc;
}

.result-info {
  flex: 1;
  overflow: hidden;
}

.result-title {
  font-size: 28rpx;
  color: #1e293b;
  font-weight: 500;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.result-addr {
  font-size: 24rpx;
  color: #94a3b8;
  display: block;
  margin-top: 4rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bottom-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: #ffffff;
  border-radius: 24rpx 24rpx 0 0;
  padding: 32rpx;
  padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
  z-index: 20;
}

.address-info {
  display: flex;
  align-items: center;
  gap: 12rpx;
  margin-bottom: 12rpx;
}

.address-text {
  font-size: 30rpx;
  font-weight: 600;
  color: #1e293b;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.coord-row {
  margin-bottom: 24rpx;
}

.coord-text {
  font-size: 24rpx;
  color: #94a3b8;
}

.confirm-btn {
  width: 100%;
  height: 84rpx;
  line-height: 84rpx;
  background: #6366f1;
  color: #ffffff;
  font-size: 30rpx;
  font-weight: 600;
  border-radius: 16rpx;
  border: none;
}

.confirm-btn::after {
  border: none;
}
</style>
