<template>
  <div class="map-page with-bottom-nav">
    <div ref="mapContainer" class="map-container" />
    <!-- 定位按钮 -->
    <div class="map-controls">
      <van-button
        v-if="userStore.isAdmin && pendingCreateLngLat"
        icon="plus"
        round
        type="success"
        size="small"
        @click="goCreateTree"
      >
        在此创建许愿树
      </van-button>
      <van-button
        icon="aim"
        round
        type="primary"
        size="small"
        :loading="locating"
        @click="locateUser"
      >
        定位
      </van-button>
    </div>
    <!-- 许愿树信息弹出层 -->
    <van-popup
      v-model:show="showPopup"
      position="bottom"
      round
      :style="{ maxHeight: '45%' }"
      safe-area-inset-bottom
    >
      <div class="tree-popup" v-if="selectedTree">
        <div class="popup-cover" :style="{ background: popupGradient }">
          <span class="popup-emoji">{{ popupEmoji }}</span>
        </div>
        <h3 class="popup-name">{{ selectedTree.name }}</h3>
        <p class="popup-addr">{{ selectedTree.address }}</p>
        <div class="popup-meta">
          <van-tag
            :type="selectedTree.isInRange ? 'success' : 'warning'"
            round
            size="medium"
          >
            {{
              selectedTree.isInRange
                ? "可许愿"
                : "距离 " + fmtDist(selectedTree.distance)
            }}
          </van-tag>
          <span class="popup-count"
            >💬 {{ selectedTree.totalWishes }} 个愿望</span
          >
        </div>
        <div class="popup-actions">
          <van-button
            type="primary"
            block
            round
            size="small"
            @click="goTreeDetail"
          >
            查看详情
          </van-button>
          <van-button
            type="success"
            block
            round
            size="small"
            :disabled="!selectedTree.isInRange"
            @click="goMakeWish"
          >
            {{ selectedTree.isInRange ? "🙏 去许愿" : "需要靠近许愿树" }}
          </van-button>
        </div>
      </div>
    </van-popup>

    <!-- 管理员创建许愿树弹窗 -->
    <van-popup
      v-model:show="showCreatePopup"
      position="bottom"
      round
      :style="{ maxHeight: '70%' }"
      safe-area-inset-bottom
    >
      <div class="create-popup">
        <h3>创建许愿树</h3>
        <van-field v-model="createForm.name" label="名称" placeholder="输入许愿树名称" required />
        <div class="create-cover">
          <span class="create-cover-label">封面图</span>
          <ImageUploader v-model="createForm.coverImages" :max="1" />
        </div>
        <van-field v-model.number="createForm.radius" label="可许愿范围" placeholder="100" type="number">
          <template #suffix><span style="color:#999;font-size:14px">米</span></template>
        </van-field>
        <van-field :model-value="createForm.lng + ', ' + createForm.lat" label="坐标" readonly />
        <div class="create-actions">
          <van-button round plain @click="showCreatePopup = false">取消</van-button>
          <van-button round type="primary" :loading="creating" @click="handleCreateTree">创建</van-button>
        </div>
      </div>
    </van-popup>
  </div>
</template>
<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from "vue";
import { useRouter } from "vue-router";
import { showToast } from "vant";
import { useLocationStore } from "@/stores/location";
import { getUserLocation } from "@/utils/geo";
import { getTreeGradient, getTreeEmoji } from "@/utils/theme";
import { fetchNearbyTrees, createTree } from "@/api/tree";
import { useUserStore } from "@/stores/user";
import { gcj02ToWgs84 } from "@/utils/mapTool";
import markerImg from "@/assets/location-marker.png";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import ImageUploader from "@/components/ImageUploader.vue";
const router = useRouter();
const locationStore = useLocationStore();
const userStore = useUserStore();
const mapContainer = ref<HTMLDivElement>();
const showPopup = ref(false);
const selectedTree = ref<any>(null);
const locating = ref(false);

// 管理员创建许愿树
const showCreatePopup = ref(false);
const creating = ref(false);
const createForm = ref({ name: '', radius: 100, lng: 0, lat: 0, coverImages: [] as string[] });
const popupGradient = computed(() =>
  getTreeGradient(selectedTree.value?.id || 1),
);
const popupEmoji = computed(() => getTreeEmoji(selectedTree.value?.id || 1));
let map: any = null;
let userMarker: any = null;
let treeMarkers: L.Marker[] = [];
const pendingCreateLngLat = ref<[number, number] | null>(null);
function fmtDist(m: number) {
  return m >= 1000 ? (m / 1000).toFixed(1) + "km" : m + "m";
}
function goTreeDetail() {
  showPopup.value = false;
  router.push(`/tree/${selectedTree.value.id}`);
}
function goMakeWish() {
  showPopup.value = false;
  router.push({ path: "/make-wish", query: { treeId: selectedTree.value.id } });
}
function goCreateTree() {
  if (!pendingCreateLngLat.value) return;
  const [lng, lat] = pendingCreateLngLat.value;
  createForm.value = { name: '', radius: 100, lng: Number(lng.toFixed(6)), lat: Number(lat.toFixed(6)), coverImages: [] };
  showCreatePopup.value = true;
}
async function handleCreateTree() {
  if (!createForm.value.name.trim()) {
    showToast("请输入许愿树名称");
    return;
  }
  creating.value = true;
  try {
    await createTree({
      name: createForm.value.name,
      description: '',
      longitude: createForm.value.lng,
      latitude: createForm.value.lat,
      address: '',
      radius: createForm.value.radius,
      coverImage: createForm.value.coverImages[0] || '',
    });
    showToast("许愿树创建成功");
    showCreatePopup.value = false;
    await loadTrees();
  } catch {
    showToast("创建失败");
  } finally {
    creating.value = false;
  }
}
// 高德瓦片（GCJ-02 坐标系）
async function initMap() {
  try {
    // 尝试获取当前位置作为地图中心
    let lng = 108.372652;
    let lat = 22.84905;
    try {
      const pos = await getUserLocation();
      lng = pos.lng;
      lat = pos.lat;
    } catch {
      // 定位失败使用默认坐标
    }
    // 天地图参数
    const tileOptions = {
      zoomControl: true,
      attributionControl: false,
      minZoom: 0,
      minNativeZoom: 7,
      maxZoom: 22,
      maxNativeZoom: 18,
    };
    const VEC_C =
      "https://t0.tianditu.gov.cn/img_w/wmts?" +
      "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
      "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=";
    const CVA_C =
      "https://t0.tianditu.gov.cn/cia_w/wmts?" +
      "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
      "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=";
    const TK_KEY = "96d2b2c34cf02a4ea614386a16738ba9";
    let layer1 = L.tileLayer(VEC_C + TK_KEY, tileOptions);
    let layer2 = L.tileLayer(CVA_C + TK_KEY, tileOptions);
    map = L.map(mapContainer.value!, {
      center: [lat, lng],
      zoom: 18,
      minZoom: 0,
      maxZoom: 22,
      layers: [layer1, layer2],
      zoomControl: false,
      attributionControl: false,
    });
    // L.tileLayer(GAODE_TILE, {
    //   subdomains: ["1", "2", "3", "4"],
    //   maxZoom: 18,
    // }).addTo(map);
    L.layerGroup().addTo(map);
    L.control.scale({ metric: true, imperial: false }).addTo(map);
    L.control.zoom({ position: "topright" }).addTo(map);
    // 管理员点击地图：移动定位标记到点击位置
    map.on("click", (e: any) => {
      if (!userStore.isAdmin) return;
      showPopup.value = false;
      const { lat, lng } = e.latlng;
      pendingCreateLngLat.value = [lng, lat];
      if (userMarker) map.removeLayer(userMarker);
      const icon = L.icon({
        iconUrl: markerImg,
        iconSize: [25, 45],
        iconAnchor: [12, 45],
      });
      userMarker = L.marker([lat, lng], { icon, zIndexOffset: 200 }).addTo(map);
    });
    locateUser();
  } catch (err) {
    showToast("地图加载失败");
    console.error(err);
  }
}
async function locateUser() {
  locating.value = true;
  try {
    const { lng, lat } = await getUserLocation();
    locationStore.setLocation(lng, lat);
    if (map) {
      map.setView([lat, lng], 18);
      if (userMarker) map.removeLayer(userMarker);
      const icon = L.icon({
        iconUrl: markerImg,
        iconSize: [25, 45],
        iconAnchor: [12, 45],
      });
      userMarker = L.marker([lat, lng], { icon, zIndexOffset: 200 }).addTo(map);
    }
    await loadTrees();
  } catch {
    await loadTrees();
  } finally {
    locating.value = false;
  }
}
async function loadTrees() {
  if (!locationStore.lng) return;
  const trees = await fetchNearbyTrees(
    locationStore.lng,
    locationStore.lat!,
    50000,
    100,
  );
  treeMarkers.forEach((m) => map.removeLayer(m));
  treeMarkers = [];
  trees.forEach((tree: any) => {
    const isIn = tree.isInRange;
    const color = isIn ? "#07c160" : "#ff976a";
    const label = `${tree.name} ${fmtDist(tree.distance)}`;
    const icon = L.divIcon({
      className: "",
      html: `
        <div style="
          position:relative;
          text-align:center;
          background:${color};
          color:#fff;
          padding:4px 10px;
          border-radius:16px;
          font-size:11px;
          white-space:nowrap;
          box-shadow:0 2px 8px rgba(0,0,0,0.3);
          max-width:160px;
          overflow:hidden;
          text-overflow:ellipsis;
        ">
          ${label}
          <div style="
            position:absolute;
            bottom:-6px;
            left:50%;
            transform:translateX(-50%);
            width:0;
            height:0;
            border-left:6px solid transparent;
            border-right:6px solid transparent;
            border-top:6px solid ${color};
          "></div>
        </div>`,
      iconSize: [0, 0] as any,
      iconAnchor: [0, 0],
    });
    // DB 存储的是 GCJ-02 坐标，天地图 img_w 使用 WGS-84，需转换
	    const wgs = gcj02ToWgs84({ lng: tree.longitude, lat: tree.latitude });
	    const marker = L.marker([wgs.lat, wgs.lng], { icon }).addTo(map);
    marker.on("click", () => {
      selectedTree.value = tree;
      showPopup.value = true;
    });
    treeMarkers.push(marker);
  });
}
watch(
  () => [locationStore.lng, locationStore.lat] as const,
  ([lng, lat]) => {
    if (lng != null && lat != null && userMarker) {
      userMarker.setLatLng([lat, lng]);
    }
  },
);
onMounted(async () => {
  await nextTick();
  initMap();
  locationStore.startWatch(5000);
});
onUnmounted(() => {
  locationStore.stopWatch();
  if (map) map.remove();
});
</script>
<style scoped>
.map-page {
  position: relative;
  width: 100%;
  height: 100%;
}
.map-container {
  width: 100%;
  height: 100%;
}
.map-controls {
  position: absolute;
  bottom: 80px;
  right: 16px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tree-popup {
  padding: 16px;
}
.popup-cover {
  width: 100%;
  height: 120px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}
.popup-emoji {
  font-size: 44px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}
.popup-name {
  font-size: 17px;
  margin: 10px 0 4px;
}
.popup-addr {
  font-size: 12px;
  color: #999;
  margin-bottom: 10px;
}
.popup-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}
.popup-count {
  font-size: 12px;
  color: #666;
}
.popup-actions {
  display: flex;
  gap: 8px;
}
.create-popup {
  padding: 16px;
}
.create-popup h3 {
  font-size: 18px;
  margin-bottom: 12px;
  text-align: center;
}
.create-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px 0;
}
.create-cover {
  padding: 12px 16px;
}
.create-cover-label {
  font-size: 14px;
  color: #666;
  margin-bottom: 8px;
  display: block;
}
</style>
