<template>
  <div class="map-wrapper">
    <div id="header">
      <span class="title">天津市林草资源专项调查——数据展示系统</span>
    </div>
    <div id="map" ref="mapContainer" class="map-container"></div>
    <div id="dateSelectItem" class="date-panel">
        <span class="date-label">选择日期：</span>
        <el-date-picker
          v-model="selectedDate"
          type="date"
          placeholder="选择日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          :disabled-date="disabledDate"
          @change="handleDateChange"
          size="default"
        />
        <button 
          v-if="!hasDateMarkers && selectedDate" 
          class="action-btn show-btn" 
          @click="handleShowData" 
          title="加载当前日期的统计数据"
        >
           <el-icon><Search /></el-icon> 显示数据
        </button>

        <button 
          v-if="hasDateMarkers" 
          class="action-btn clear-btn" 
          @click="clearDateMarkers" 
          title="清除地图上的标注"
        >
           <el-icon><Close /></el-icon> 清除数据
        </button>
      </div>

    <div class="legend-panel">
      <Legend :legendData="legendItems" />
      <div class="control-item group-item">
        <label class="group-header">
          <input type="checkbox" v-model="isStatLayerVisible" />
          <span>统计数据 </span>
        </label>

        <div v-if="isStatLayerVisible" class="group-body">
          <IndicatorSelector 
            :indicators="Object.keys(indicatorData)" 
            v-model="selectedIndicator" 
          />
        </div>
      </div>
      <div class="control-item">
        <label>
          <input type="checkbox" v-model="isPlotLayerVisible" />
          小班图层
        </label>
      </div>
      <div class="control-item">
        <label>
          <input type="checkbox" v-model="isSampleLayerVisible" />
          样地图层
        </label>
      </div>
          
      <button v-if="currentLevel === 'street'" class="back-btn" @click="backToDistrict">
        返回区级
      </button>

    </div>
  </div>
  <PlotPopup :visible="popupVisible" :data="popupData" :position="popupPos" @enter-sample="showSamples"
    @enter-side="showSideTrees" @close="popupVisible = false" />
  <SamplePopup :visible="samplePopupVisible" :data="samplePopupData" :position="samplePopupPos" />

</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, watch } from "vue";
import maplibregl from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";
import { TDT_KEY } from "../assets/tdt_key.js";
import IndicatorSelector from "./IndicatorSelector.vue";
import Legend from "./Legend.vue";
import { samplePlots, sideTrees } from "../assets/mockPlotData.js";
import PlotPopup from "./PlotPopup.vue";
import SamplePopup from "./SamplePopup.vue";
import bbox from "@turf/bbox";
import { Close, Search } from "@element-plus/icons-vue";


const popupVisible = ref(false);
const popupData = ref({});
const popupPos = ref({ x: 0, y: 0 });
const isPlotLayerVisible = ref(false);
const isStatLayerVisible = ref(true);
const isSampleLayerVisible = ref(false);

// 天津市行政区划数据（区级）
const districtUrl ="https://geo.datav.aliyun.com/areas_v3/bound/120000_full.json";


// 区级指标数据
const indicatorData =ref({
  完成状态:{},
  图斑面积:{},
  图斑数量:{},
})
// 状态管理
const selectedIndicator = ref("完成状态");
const currentLevel = ref("district"); // 当前层级
const currentDistrict = ref(""); // 当前区名

const mapContainer = ref(null);
let map = null;
const legendItems = ref([]);
let allStreetsData = null;
const districtCountCache=ref({});
let hoverPopup=null;
const dateMarkers = ref([]); // 存储 Marker 实例
const hasDateMarkers = ref(false); // 控制清除按钮显示
const districtCenters = {};
const SAMPLE_SOURCE_ID = "sample-wms-source";
const SAMPLE_LAYER_ID = "sample-raster-layer";
const SAMPLE_LAYER_NAME = "lydc:YDTB";
watch(isStatLayerVisible, () => {
  updateStatLayerState();
});

watch(isPlotLayerVisible, (newVal) => {
  if (newVal) {
    showPlotLayer();
  } else {
    hidePlotLayer();
  }
});
watch(isSampleLayerVisible, (newVal) => {
  if (newVal) {
    showSamplePlotLayer();
  } else {
    hideSamplePlotLayer();
  }
});
const selectedDate = ref(new Date().toISOString().split('T')[0]); // 默认今天

function calculateDistrictCenters(geojson) {
  if (!geojson || !geojson.features) return;
  geojson.features.forEach(feature => {
    const name = feature.properties.name;
    if (name) {
      // 使用 bbox 计算几何中心
      const [minX, minY, maxX, maxY] = bbox(feature);
      const centerX = (minX + maxX) / 2;
      const centerY = (minY + maxY) / 2;
      districtCenters[name] = [centerX, centerY];
    }
  });
  console.log("📍 行政区中心点计算完毕:", districtCenters);
}

// --- ✅ 修改：日期变更处理 ---
async function handleDateChange(val) {
  if (!val) return;
  console.log("📅 日期已切换为:", val);
  
  // 1. 先清除旧的标注
  clearDateMarkers();

  // 2. 请求新数据
  await fetchDateStats(val);
}

// --- ✅ 新增：请求日期统计数据 ---
async function fetchDateStats(dateStr) {
  try {
    const url = `/api/stats/date?date=${dateStr}`;
    const res = await fetch(url);
    const json = await res.json();

    if (json.code === 0 && json.data && json.data.length > 0) {
      renderDateMarkers(json.data);
    } else {
      console.log("该日期无数据");
      // Element Plus 的消息提示 (如果项目里有引入 ElMessage)
      // ElMessage.warning("该日期无统计数据"); 
    }
  } catch (error) {
    console.error("日期统计请求失败:", error);
  }
}

// --- ✅ 新增：渲染标注 ---
function renderDateMarkers(dataList) {
  // 遍历后端返回的数据
  dataList.forEach(item => {
    const name = item.district;
    const center = districtCenters[name];

    // 如果能找到该区的坐标
    if (center) {
      // 1. 创建自定义 HTML 元素
      const el = document.createElement('div');
      el.className = 'date-stat-marker';
      el.innerHTML = `
        <div class="marker-title">${name}</div>
        <div class="marker-row">完成小班: <b>${item.plotcount}</b></div>
        <div class="marker-row">完成样地: <b>${item.sampleplotcount}</b></div>
      `;

      // 2. 创建 MapLibre Marker
      const marker = new maplibregl.Marker({
        element: el,
        anchor: 'bottom', // 标注的“脚”对准中心点
        offset: [0, -10]  // 稍微往上提一点，不遮挡文字
      })
      .setLngLat(center)
      .addTo(map);

      // 3. 存入数组方便管理
      dateMarkers.value.push(marker);
    }
  });

  if (dateMarkers.value.length > 0) {
    hasDateMarkers.value = true;
  }
}
// ✅ 新增：点击“显示数据”按钮的处理函数
async function handleShowData() {
  if (!selectedDate.value) {
    alert("请先选择日期");
    return;
  }
  // 手动触发请求
  await fetchDateStats(selectedDate.value);
}

// --- ✅ 新增：清除标注 ---
function clearDateMarkers() {
  dateMarkers.value.forEach(marker => marker.remove());
  dateMarkers.value = [];
  hasDateMarkers.value = false;
}

// ✅ 可选：禁用未来日期
function disabledDate(time) {
  return time.getTime() > Date.now();
}
function updateStatLayerState() {
  const isVisible = isStatLayerVisible.value ? 'visible' : 'none';
  
  if (currentLevel.value === 'district') {
    // 如果在区级：显示区，隐藏街道
    if (map.getLayer("tianjin-fill")) map.setLayoutProperty("tianjin-fill", "visibility", isVisible);
    if (map.getLayer("tianjin-outline")) map.setLayoutProperty("tianjin-outline", "visibility", isVisible);
    if (map.getLayer("tianjin-label")) map.setLayoutProperty("tianjin-label", "visibility", isVisible);
    
    // 确保街道层隐藏
    if (map.getLayer("street-fill")) map.setLayoutProperty("street-fill", "visibility", "none");
    if (map.getLayer("street-outline")) map.setLayoutProperty("street-outline", "visibility", "none");
    
  } else if (currentLevel.value === 'street') {
    // 如果在街道级：隐藏区，显示街道
    if (map.getLayer("tianjin-fill")) map.setLayoutProperty("tianjin-fill", "visibility", "none");
    if (map.getLayer("tianjin-outline")) map.setLayoutProperty("tianjin-outline", "visibility", "none");
    if (map.getLayer("tianjin-label")) map.setLayoutProperty("tianjin-label", "visibility", "none");
    
    // 控制街道层
    if (map.getLayer("street-fill")) map.setLayoutProperty("street-fill", "visibility", isVisible);
    if (map.getLayer("street-outline")) map.setLayoutProperty("street-outline", "visibility", isVisible);
  }
}

async function fetchDistrictStatus(){
  console.log("🔥 正在尝试发起请求...");
  try{
    const response=await fetch('/api/stats/district')
    const res=await response.json();
    console.log("区级指标数据:",res);
    if(res.code==0&&res.data){
      indicatorData.value={
        完成状态:res.data.completionStatus || {},
        图斑面积:res.data.plotArea || {},
        图斑数量:res.data.plotCount || {},
      };
  

      if (map&&map.getSource("tianjin")){
        updateMapColors("district");
      }
    }
  
  }catch(error){
    console.error("获取区级指标数据失败:",error);
  }
}
async function fetchDistrictCount(districtName){
  if (districtCountCache.value[districtName]){
    return districtCountCache.value[districtName];
  }
  try {
    const url=`/api/stats/district/count?district=${encodeURIComponent(districtName)}`;
    const res=await fetch(url);
    const json=await res.json();
    if(json.code===0&&json.data){
      districtCountCache.value[districtName]=json.data;
      return json.data;
    }
  }catch (error){
    console.log(`获取${districtName}图斑数量失败:`,error);
  }
  return null;
}
// 街道指标
const streetIndicatorData = ref({
  完成状态:{},
  图斑面积:{},
  图斑数量:{},
});

async function fetchStreetStats(districtName) {
  try {
    console.log(`🔥 正在请求【${districtName}】的街道数据...`);
    
    const url = `/api/stats/street?district=${encodeURIComponent(districtName)}`;
    const response = await fetch(url);
    const res = await response.json();

    if (res.code === 0 && res.data) {
      streetIndicatorData.value = {
        完成状态: res.data.completionStatus || {},
        图斑面积: res.data.plotArea || {},
        图斑数量: res.data.plotCount || {},
      };
      console.log("✅ 街道数据获取成功:", streetIndicatorData.value);
      if (currentLevel.value === 'street') {
         // 为了确保地图源(Source)已经创建，可以加一个小延时，或者直接调用
         // 这里的 'street' 对应 updateMapColors 里的 sourceId判断
         updateMapColors('street'); 
      }
    } else {
      console.warn("街道数据返回异常:", res);
    }
  } catch (error) {
    console.error("获取街道指标失败:", error);
  }
}

// 加载街道
async function loadAllStreets() {
  if (!allStreetsData) {
    const res = await fetch("/data/tianjin_street.geojson");
    allStreetsData = await res.json();
  }
}
const MEDIA_BASE_URL = '/photos';
async function fetchPlotData(nyxbh, xiang) {
  try {
    // 1. 构建带参数的 URL
    const url = `/api/stats/plot/attr?nyxbh=${encodeURIComponent(nyxbh)}&xiang=${encodeURIComponent(xiang)}`;

    console.log("🚀 发起后端详情请求:", url);

    // 2. 发起请求
    const response = await fetch(url.toString(), {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
        // 如果有 token，记得在这里加 'Authorization': 'Bearer ...'
      }
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const resJson = await response.json();
    console.log("📦 后端返回的数据:", resJson);

    // 3. 校验后端返回的业务状态码
    if (resJson.code === 0) {
      // 处理数据（特别是媒体路径）
      return processPlotData(resJson.data);
    } else {
      console.error('业务报错:', resJson.message);
      return null;
    }

  } catch (error) {
    console.error('请求失败:', error);
    return null;
  }
}
function processPlotData(data) {
  if (!data) return null;

  // 1. 处理 Shape 数据 (它是字符串格式的 JSON，可能需要转对象)
  let geoJson = null;
  try {
    if (data.shape) {
        geoJson = JSON.parse(data.shape);
    }
  } catch (e) {
    console.error('Shape 解析失败', e);
  }

  // 2. 处理媒体列表
  const images = [];
  const videos = [];

  if (data.mediaPathList && Array.isArray(data.mediaPathList)) {
    data.mediaPathList.forEach(path => {
      // 拼接完整 URL
      const fullUrl = `${MEDIA_BASE_URL}${path}`;
      
      // 简单通过后缀区分类型 (转小写比较)
      const lowerPath = path.toLowerCase();
      if (lowerPath.endsWith('.jpg') || lowerPath.endsWith('.png') || lowerPath.endsWith('.jpeg')) {
        images.push(fullUrl);
      } else if (lowerPath.endsWith('.avi') || lowerPath.endsWith('.mp4')) {
        videos.push(fullUrl);
      }
    });
  }

  // 返回处理后的对象，方便前端直接使用
  return {
    ...data,       // 保留原始属性 (id, cun, linZhong 等)
    geoJson,       // 解析后的地理坐标对象
    images,        // 只有图片链接的数组
    videos         // 只有视频链接的数组
  };
}
async function fetchPlotStats(rootId, databaseName) {
  try {
    const url = `/api/stats/plot/count?rootId=${rootId}&databaseName=${encodeURIComponent(databaseName)}`;
    const res = await fetch(url);
    const json = await res.json();
    if (json.code === 0) {
      return json.data;
    }
  } catch (error) {
    console.error("获取小班下样地统计失败:", error);
  }
  return null;
}
// 定义点击区级多边形的处理函数
async function handleDistrictClick(e) {
  const districtName = e.features[0].properties.name;
  showStreetLevel(districtName);
}

// 定义点击空白返回的处理函数
function handleMapClick(e) {
  const queryLayers = ["tianjin-fill"];
  if (map.getLayer("street-fill")) queryLayers.push("street-fill");

  const features = map.queryRenderedFeatures(e.point, {
    layers: queryLayers,
  });
  if (!features.length && currentLevel.value === "street") {
    backToDistrict();
  }
}

// 初始化地图
onMounted(async () => {
  fetchDistrictStatus();
  console.log("初始化地图");
  map = new maplibregl.Map({
    container: mapContainer.value,
    style: {
      version: 8,
      glyphs: "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
      sources: {
        tdt_vec: {
          type: "raster",
          tiles: Array.from(
            { length: 8 },
            (_, i) =>
              `https://t${i}.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TDT_KEY}`
          ),
          tileSize: 256,
        },
        tdt_cva: {
          type: "raster",
          tiles: Array.from(
            { length: 8 },
            (_, i) =>
              `https://t${i}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TDT_KEY}`
          ),
          tileSize: 256,
        },
      },
      layers: [
        { id: "tdt_vec", type: "raster", source: "tdt_vec" },
        { id: "tdt_cva", type: "raster", source: "tdt_cva" },
      ],
    },
    center: [117.2, 39.13],
    zoom: 8,
    transformRequest: (url, resourceType) => {
      if (url.includes('/geoserver')) {
        return {
          url: url,
          headers: {
            // 将 admin:geoserver 转为 Base64 认证头
            'Authorization': 'Basic ' + btoa('admin:geoserver')
          }
        }
      }
      return { url };
    },
  });

  const res = await fetch(districtUrl);
  const geojson = await res.json();
  calculateDistrictCenters(geojson);

  map.on("load", () => {
    map.addSource("tianjin", { type: "geojson", data: geojson });

    map.addLayer({
      id: "tianjin-fill",
      type: "fill",
      source: "tianjin",
      layout: { visibility: isStatLayerVisible.value ? 'visible' : 'none' },
      paint: { "fill-color": ["coalesce", ["get", "color"], "#b6e3d8"], "fill-opacity": 0.9 },
    });

    map.addLayer({
      id: "tianjin-outline",
      type: "line",
      source: "tianjin",
      layout: { visibility: isStatLayerVisible.value ? 'visible' : 'none' },
      paint: { "line-color": "#ffffff", "line-width": 1 },
    });
    map.addLayer({
      id: "tianjin-label",
      type: "symbol",
      source: "tianjin",
      layout: { visibility: isStatLayerVisible.value ? 'visible' : 'none' },
      layout: {
        "text-field": ["get", "name"], // 获取 properties 中的 name
        "text-size": 14,               // 文字大小
        "text-font": ["Open Sans Regular"], // 指定字体（必须与 glyphs 对应）
        "text-anchor": "center",       // 文字居中
        "text-allow-overlap": false    // 避免文字重叠
      },
      paint: {
        "text-color": "#000000",       // 文字颜色：黑色
        "text-halo-color": "#ffffff",  // 文字描边：白色（为了看清）
        "text-halo-width": 2           // 描边宽度
      }
    });
    updateMapColors();

    // 点击区多边形，下钻街道级
    // map.off("click", "tianjin-fill", handleDistrictClick);
    // map.on("click", "tianjin-fill", handleDistrictClick);


    hoverPopup = new maplibregl.Popup({
      closeButton: false,
      closeOnClick: false,
      className: 'district-hpver-popup',
      maxWidth: '300px'
    });
   let lastHoveredDistrict = null; 

    // 鼠标移动事件
    map.on('mousemove', 'tianjin-fill', async (e) => {
      // 1. 基础校验
      if (currentLevel.value !== 'district' || !isStatLayerVisible.value) return;
      
      const features = map.queryRenderedFeatures(e.point, { layers: ['tianjin-fill'] });
      if (!features.length) {
        // 如果虽然在图层范围内但没取到要素（极端情况），也视为移出
        hoverPopup.remove();
        lastHoveredDistrict = null;
        map.getCanvas().style.cursor = "";
        return;
      }
      
      const districtName = features[0].properties.name;
      
      // 2. 始终更新：鼠标样式和弹窗位置（让弹窗跟手）
      map.getCanvas().style.cursor = "pointer";
      hoverPopup.setLngLat(e.lngLat);

      // 🔥🔥🔥 核心修复：如果鼠标还在同一个区内，直接返回，不执行后面逻辑！
      if (lastHoveredDistrict === districtName) {
        return; 
      }

      // 3. 只有当进入新区域时，才执行下面的代码
      lastHoveredDistrict = districtName; // 更新当前区名
      
      // 先显示弹窗（加载状态），提升交互响应速度
      if (!hoverPopup.isOpen()) hoverPopup.addTo(map);

      // 检查缓存
      let countData = districtCountCache.value[districtName];
      
      if (!countData) {
        // 缓存没有，显示加载中
        hoverPopup.setHTML(`
          <div class="hover-content">
            <div class="hover-title">${districtName}</div>
            <div class="hover-loading">暂无数据</div>
          </div>
        `);
        
        // 发起请求
        countData = await fetchDistrictCount(districtName);
      }
      
      // 4. 数据获取回来后，再次确认：鼠标是否还停留在该区？
      // (防止网络慢，请求回来时鼠标已经移到别的区了，导致弹窗内容错乱)
      if (lastHoveredDistrict === districtName && countData) {
        const htmlContent = `
          <div class="hover-content">
            <div class="hover-title">${districtName}</div>
            <div class="hover-row">
                <span class="label">内业数量：</span>
                <span class="value val-ny">${countData.ny || 0}</span>
            </div>
            <div class="hover-row">
                <span class="label">外业完成：</span>
                <span class="value val-wy">${countData.wy || 0}</span>
            </div>
            <div class="hover-row">
                <span class="label">样地数量：</span>
                <span class="value val-yd">${countData.yd || 0}</span>
            </div>
          </div>
        `;
        hoverPopup.setHTML(htmlContent);
      }
    });

    // 鼠标移出事件
    map.on('mouseleave', 'tianjin-fill', () => {
      map.getCanvas().style.cursor = "";
      // 清空记录
      lastHoveredDistrict = null; 
      if (hoverPopup) {
        hoverPopup.remove();
      }
    });
  });
});

// 更新地图着色
function updateMapColors(level = currentLevel.value) {
  const sourceId = level === "district" ? "tianjin" : "street";
  const data = map.getSource(sourceId)?._data;
  if (!data) return;

  const indicator = level === "district" ? indicatorData.value : streetIndicatorData.value;
  const selected = selectedIndicator.value;
  
  // 防止接口还没返回数据时报错
  if (!indicator[selected]) return;

  if (selected === "完成状态") {
    const colors = { 已采集: "#4CAF50", 已采集未开始: "#FFC107", 未发布: "#BDBDBD" };
    data.features.forEach((f) => {
      let name;
      if (level === 'district') {
        name = f.properties.name; // 区级 GeoJSON 还是叫 name
      } else {
        name = f.properties.乡;   // 街道级 GeoJSON 叫 "乡"
      }
      
      // 增加一个去空格处理
      if (name) name = name.trim();
      const val = indicator[selected][name];
      f.properties.color = colors[val] || "#BDBDBD";
    });
    map.getSource(sourceId).setData(data);
    legendItems.value = Object.entries(colors).map(([k, v]) => ({
      color: v,
      range: k,
    }));
  } else {
    const values = Object.values(indicator[selected]);
    const min = Math.min(...values);
    const max = Math.max(...values);
    const colors = ["#f2f0f7", "#cbc9e2", "#9e9ac8", "#756bb1", "#54278f"];
    const getColor = (v) =>
      colors[Math.floor(((v - min) / (max - min)) * (colors.length - 1))];
    data.features.forEach((f) => {
      let name;
      if (level === 'district') {
        name = f.properties.name;
      } else {
        name = f.properties.乡;
      }
      
      if (name) name = name.trim();

      const v = indicator[selected][name];
      f.properties.color = (v !== undefined && v !== null) ? getColor(v) : "#ccc";
    });
    map.getSource(sourceId).setData(data);
    legendItems.value = colors.map((c, i) => {
      const start = min + (i / colors.length) * (max - min);
      const end = min + ((i + 1) / colors.length) * (max - min);
      return { color: c, range: `${start.toFixed(1)} - ${end.toFixed(1)}` };
    });
  }
}

// 下钻显示街道级
async function showStreetLevel(districtName) {
  currentLevel.value = "street";
  currentDistrict.value = districtName;
  await loadAllStreets();
  fetchStreetStats(districtName);
  // ✅ 筛选出该区所有街道
  const filteredFeatures = allStreetsData.features.filter(
    (f) => f.properties.县 === districtName
  );

  if (filteredFeatures.length === 0) {
    alert(`区【${districtName}】没有找到街道数据`);
    return;
  }

  // ✅ 构建新的 GeoJSON（只包含这个区的街道）
  const streetGeo = {
    type: "FeatureCollection",
    features: filteredFeatures,
  };

  // ✅ 清除旧图层
  if (map.getSource("street")) {
    map.removeLayer("street-fill");
    map.removeLayer("street-outline");
    map.removeSource("street");
  }

  // ✅ 添加新的街道层
  map.addSource("street", {
    type: "geojson",
    data: streetGeo,
  });

  map.addLayer({
    id: "street-fill",
    type: "fill",
    source: "street",
    layout: {
      // ✅ 新增：初始化时就根据复选框决定可见性
      visibility: isStatLayerVisible.value ? 'visible' : 'none'
    },
    paint: {
      "fill-color": "#b3e0e6", // 根据指标设色
      "fill-opacity": 0.8,
    },
  });

  map.addLayer({
    id: "street-outline",
    type: "line",
    source: "street",
    layout: {
      // ✅ 新增：初始化时就根据复选框决定可见性
      visibility: isStatLayerVisible.value ? 'visible' : 'none'
    },
    paint: { "line-width": 1, "line-color": "#ffffff" },
  });


  updateMapColors("street");
  updateStatLayerState();

  // ✅ 隐藏区级图层
  if (map.getLayer("tianjin-fill"))
    map.setLayoutProperty("tianjin-fill", "visibility", "none");
  if (map.getLayer("tianjin-outline"))
    map.setLayoutProperty("tianjin-outline", "visibility", "none");
  if (map.getLayer("tianjin-label"))
  map.setLayoutProperty("tianjin-label", "visibility", "none");

  // ✅ 自动缩放到该区所有街道范围
  const extent = bbox(streetGeo); // [minX, minY, maxX, maxY]

  map.fitBounds(
    [
      [extent[0], extent[1]],
      [extent[2], extent[3]],
    ],
    {
      padding: 40,
      duration: 800,
    }
  );
}

// 返回区级图层
function backToDistrict() {
  if (map.getLayer("street-fill")) {
    map.removeLayer("street-fill");
    map.removeLayer("street-outline");
    map.removeSource("street");
  }
  currentLevel.value = "district";
  updateStatLayerState();
  map.flyTo({ center: [117.2, 39.13], zoom: 8 });
  updateMapColors("district");
}

async function handlePlotClick(e) {
  console.log("🖱️ 点击坐标:", e.lngLat);

  // 1. 基础检查
  if (!map.getLayer("plot-raster-layer") || map.getLayoutProperty("plot-raster-layer", "visibility") === 'none') return;

  // 2. 避让矢量图层 (样地/树)
  const targetLayers = ["samples-fill", "sideTrees"];
  const existingLayers = targetLayers.filter(id => map.getLayer(id) && map.getLayoutProperty(id, "visibility") !== 'none');
  if (existingLayers.length > 0) {
    const vectorFeatures = map.queryRenderedFeatures(e.point, { layers: existingLayers });
    if (vectorFeatures.length > 0) return; 
  }

  const buffer = 0.0001; 
  const lng = e.lngLat.lng;
  const lat = e.lngLat.lat;

  // 构造一个小小的查询框，单位是度
  const bbox = [
    lng - buffer,
    lat - buffer,
    lng + buffer,
    lat + buffer
  ].join(",");

  const baseUrl = "/geoserver/lydc/wms";
  const layerName = "lydc:NYTB4"; 

  const params = new URLSearchParams({
    SERVICE: "WMS",
    VERSION: "1.1.1",
    REQUEST: "GetFeatureInfo",
    FORMAT: "image/png",
    TRANSPARENT: "true",
    QUERY_LAYERS: layerName,
    LAYERS: layerName,
    
    // ✅ 关键 1: 告诉服务器我用经纬度查
    SRS: "EPSG:4326", 
    // ✅ 关键 2: 传过去的是经纬度
    BBOX: bbox,       
    
    // ✅ 关键 3: 欺骗服务器，说这一小块区域是一张 101x101 的图，我点了正中间
    WIDTH: 101,       
    HEIGHT: 101,
    X: 50,
    Y: 50,
    
    INFO_FORMAT: "application/json",
    FEATURE_COUNT: 1, 
    EXCEPTIONS: "application/vnd.ogc.se_xml"
  });

  try {
    const url = `${baseUrl}?${params.toString()}`;

    const wmsRes = await fetch(url);
    if (!wmsRes.ok) throw new Error(`HTTP ${wmsRes.status}`);
    
    const wmsData = await wmsRes.json();
    console.log("WMS GetFeatureInfo 返回:", wmsData);

    if (wmsData.features && wmsData.features.length > 0) {
      const wmsProp = wmsData.features[0].properties;

      const nyxbh = wmsProp.nyxbh || wmsProp.NYXBH;
      let xiang = wmsProp.xiang || wmsProp.XIANG;
      
      if (!xiang && (wmsProp.cun || wmsProp.CUN)) {
         const cunCode = String(wmsProp.cun || wmsProp.CUN);
         xiang = cunCode.substring(0, 9);
      }
      const rootId = wmsProp.id || wmsProp.ID; 
      const databaseName = wmsProp.database_n || wmsProp.DATABASE_N;

      if (nyxbh && xiang&&rootId&&databaseName) {
        const [plotData, sampleData] = await Promise.all([
           fetchPlotData(nyxbh, xiang),
           fetchPlotStats(rootId, databaseName)
        ]);
        if (plotData&&sampleData) {
          const canvasRect = map.getCanvas().getBoundingClientRect();
          const pos = map.project(e.lngLat);
          popupPos.value = { x: pos.x + canvasRect.left, y: pos.y + canvasRect.top };
          popupData.value = {plotData, sampleData };
          popupVisible.value = true;
        } else {
          alert("未查询到详细数据");
        }
      }
    } else {
      console.log("❌ 未命中图斑 (请确认点击位置是否有数据)");
    }
  } catch (error) {
    console.error("查询出错:", error);
  }
}

// 点击空白关闭弹窗
function handleMapClickClosePopup(e) {
  const features = map.queryRenderedFeatures(e.point, {
    layers: ["plot-fill"],
  });
  if (!features.length) popupVisible.value = false;
}

// === 图斑层控制 ===
// === 图斑层控制 ===
let cachedPlotData = null;

function showPlotLayer() {
  // 1. 添加 Source (保持不变)
  if (!map.getSource("plot-wms-source")) {
    const LAYER_NAME = "lydc:NYTB4"; 
    map.addSource("plot-wms-source", {
      type: "raster",
      tiles: [
        `/geoserver/lydc/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=${LAYER_NAME}&FORMAT=image/png&TRANSPARENT=true&WIDTH=256&HEIGHT=256&SRS=EPSG:3857&BBOX={bbox-epsg-3857}`
      ],
      tileSize: 256
    });
  }

  // 2. 添加 Layer
  if (!map.getLayer("plot-raster-layer")) {
    // ✅ 关键修改：添加时，尝试将其放在样地图层下面 (作为 beforeId)
    // 如果 SAMPLE_LAYER_ID 不存在，beforeId 为 undefined，图层会加到最上面
    const beforeId = map.getLayer(SAMPLE_LAYER_ID) ? SAMPLE_LAYER_ID : undefined;
    
    map.addLayer({
      id: "plot-raster-layer",
      type: "raster",
      source: "plot-wms-source",
      paint: { "raster-opacity": 1.0 }
    }, beforeId); // <-- 这里传第二个参数
  } else {
    map.setLayoutProperty("plot-raster-layer", "visibility", "visible");
    
    // ✅ 关键修改：如果图层已存在，且样地图层也在，强制把小班图层挪到样地下面
    if (map.getLayer(SAMPLE_LAYER_ID)) {
      map.moveLayer("plot-raster-layer", SAMPLE_LAYER_ID);
    }
  }

  map.off("click", handlePlotClick); 
  map.on("click", handlePlotClick);
  map.getCanvas().style.cursor = 'pointer';
  console.log("✅ 图斑层已显示");
}

function showSamplePlotLayer() {
  // 1. 添加 Source (保持不变)
  if (!map.getSource(SAMPLE_SOURCE_ID)) {
    map.addSource(SAMPLE_SOURCE_ID, {
      type: "raster",
      tiles: [
        `/geoserver/lydc/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=${SAMPLE_LAYER_NAME}&FORMAT=image/png&TRANSPARENT=true&WIDTH=256&HEIGHT=256&SRS=EPSG:3857&BBOX={bbox-epsg-3857}`
      ],
      tileSize: 256
    });
  }

  // 2. 添加 Layer
  if (!map.getLayer(SAMPLE_LAYER_ID)) {
    map.addLayer({
      id: SAMPLE_LAYER_ID,
      type: "raster",
      source: SAMPLE_SOURCE_ID,
      paint: { "raster-opacity": 1.0 }
    });
    // 添加后，如果小班图层存在，样地默认就在它上面（因为是后加的），所以不用特别处理
  } else {
    map.setLayoutProperty(SAMPLE_LAYER_ID, "visibility", "visible");
    
    // ✅ 关键修改：显式将样地图层挪到最上面 (或者挪到高亮图层下面)
    // 简单做法：直接 moveLayer 到顶层
    map.moveLayer(SAMPLE_LAYER_ID);
  }

  // ✅ 额外优化：如果这时候有高亮的矢量图层（如选中的样地框），要把它们重新提到最上面，否则会被WMS遮住
  if (map.getLayer("samples-fill")) map.moveLayer("samples-fill");
  if (map.getLayer("samples-outline")) map.moveLayer("samples-outline");
  if (map.getLayer("sideTrees")) map.moveLayer("sideTrees");

  console.log("✅ 样地 WMS 图层已加载");
}

function hideSamplePlotLayer() {
  if (map.getLayer(SAMPLE_LAYER_ID)) {
    map.setLayoutProperty(SAMPLE_LAYER_ID, "visibility", "none");
  }
}
// === 显示样地 ===
// === 显示样地（Polygon） ===
function showSamples() {
  // 如果之前存在，则移除旧图层和数据源
  if (map.getLayer("samples-fill")) map.removeLayer("samples-fill");
  if (map.getLayer("samples-outline")) map.removeLayer("samples-outline");
  if (map.getSource("samples")) map.removeSource("samples");

  // 添加样地数据源
  map.addSource("samples", {
    type: "geojson",
    data: samplePlots, // ✅ 样地 Polygon 数据
  });

  // 添加填充图层（样地面）
  map.addLayer({
    id: "samples-fill",
    type: "fill",
    source: "samples",
    paint: {
      "fill-color": "#1976d2",
      "fill-opacity": 0.5,
    },
  });

  // 添加轮廓线图层（边界线）
  map.addLayer({
    id: "samples-outline",
    type: "line",
    source: "samples",
    paint: {
      "line-color": "#0d47a1",
      "line-width": 2,
    },
  });

  map.off("click", "samples-fill", handleSampleClick);
  map.on("click", "samples-fill", handleSampleClick);

  map.off("click", handleCloseSamplePopup);
  map.on("click", handleCloseSamplePopup);
}

// === 显示四旁树 ===
function showSideTrees() {
  if (map.getSource("sideTrees")) map.removeSource("sideTrees");
  if (map.getLayer("sideTrees")) map.removeLayer("sideTrees");

  map.addSource("sideTrees", { type: "geojson", data: sideTrees });
  map.addLayer({
    id: "sideTrees",
    type: "circle",
    source: "sideTrees",
    paint: { "circle-radius": 6, "circle-color": "#388e3c" },
  });
}

function hidePlotLayer() {
  // ✅ 隐藏 WMS 栅格图层
  if (map.getLayer("plot-raster-layer")) {
    map.setLayoutProperty("plot-raster-layer", "visibility", "none");
  }
map.off("click", handlePlotClick);
  // 恢复鼠标样式
  map.getCanvas().style.cursor = '';
  // (保留) 隐藏之前的样地、四旁树等逻辑...
  if (map.getLayer("samples-fill")) map.setLayoutProperty("samples-fill", "visibility", "none");
  if (map.getLayer("samples-outline")) map.setLayoutProperty("samples-outline", "visibility", "none");
  if (map.getLayer("sideTrees")) map.setLayoutProperty("sideTrees", "visibility", "none");

}

// === 样地弹窗状态 ===
const samplePopupVisible = ref(false);
const samplePopupData = ref({});
const samplePopupPos = ref({ x: 0, y: 0 });

// === 样地点击事件 ===
function handleSampleClick(e) {
  const feature = e.features[0];
  let prop = feature.properties;

  // 模拟解析样地属性
  let images = JSON.parse(prop.images || "[]");
  let videos = JSON.parse(prop.videos || "[]");
  let trees = JSON.parse(prop.trees || "[]");

  const canvas = map.getCanvas().getBoundingClientRect();
  const pos = map.project(e.lngLat);
  samplePopupPos.value = { x: pos.x + canvas.left, y: pos.y + canvas.top };

  samplePopupData.value = { ...prop, images, videos, trees };
  samplePopupVisible.value = true;
}

// 点击空白关闭样地弹窗
function handleCloseSamplePopup(e) {
  const features = map.queryRenderedFeatures(e.point, {
    layers: ["samples-fill"],
  });
  if (!features.length) samplePopupVisible.value = false;
}

// 监听指标变化
watch(selectedIndicator, () => updateMapColors());

// 页面卸载时销毁地图，释放 WebGL 上下文
onBeforeUnmount(() => {
  if (map) {
    map.off("click", "tianjin-fill", handleDistrictClick);
    map.off("click", handleMapClick);
    map.off("click", "plot-fill", handlePlotClick);
    map.off("click", handleMapClickClosePopup);
    map.remove();
    map = null;
  }
});
</script>

<style scoped>
.html,
body,
#app,
#header {
  /* 固定高度，比百分比更稳定 */
  height: 60px; 
  width: 100%;
  
  /* ✅ 核心颜色：深森林绿 */
  background-color: #5db862; 
  color: white;
  
  /* 布局：左对齐，垂直居中 */
  display: flex;
  align-items: center; 
  padding: 0 24px; /*哪怕文字很少，左右留白也好看 */
  box-sizing: border-box; /* 防止padding撑破宽度 */
  
  /* 装饰：底部微弱阴影，增加层次感 */
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
  z-index: 10; /* 保证压在地图上面 */
}

/* 标题文字样式 */
.title {
  font-size: 20px;
  font-weight: 600; /* 半粗体 */
  letter-spacing: 1px; /* 字间距稍微拉开一点，更大气 */
  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
}

/* 3. 地图区域：自动填满剩余空间 */
.map-wrapper {
  flex: 1; /* 自动占据 Header 剩下的高度 */
  position: relative;
  width: 100%;
  background-color: #eef2f3; /* 地图加载前的背景色 */
}

.map-container {
  width: 100%;
  height: 100%;
}
.map-wrapper,
.map-container {
  width: 100%;
  height: 95%;
  margin: 0;
  padding: 0;
}

.map-wrapper {
  position: relative;
}

.map-container {
  width: 100%;
  height: 100%;
}
.legend-panel {
  position: absolute;
  right: 20px;
  bottom: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

.legend-panel > * {
  background: rgba(255, 255, 255, 0.9);
  border-radius: 8px;
  padding: 8px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}

.back-btn {
  border: none;
  background: #1976d2;
  color: white;
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
}
.back-btn:hover {
  background: #1565c0;
}
.control-item {
  background: white;
  padding: 8px;
  border-radius: 4px;
  box-shadow: 0 0 4px rgba(0,0,0,0.2);
  margin-bottom: 5px;
  cursor: pointer;
}
.control-item label {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
}
.date-panel {
  position: absolute;
  top: 80px;
  right: 20px;
  z-index: 100;
  background-color: rgba(255, 255, 255, 0.95);
  padding: 10px 15px;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  gap: 10px; /* 元素之间的间距 */
}

/* 按钮通用基础样式 */
.action-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  border: none;
  border-radius: 4px;
  padding: 0 12px;
  cursor: pointer;
  font-size: 12px;
  height: 32px; /* 和 Element Plus 的输入框高度一致 */
  color: white;
  transition: background 0.3s;
  white-space: nowrap;
}

/* 🔵 显示按钮：蓝色 */
.show-btn {
  background-color: #409eff; /* Element Blue */
}
.show-btn:hover {
  background-color: #66b1ff;
}

/* 🔴 清除按钮：红色 */
.clear-btn {
  background-color: #f56c6c; /* Element Red */
}
.clear-btn:hover {
  background-color: #ff4d4f;
}

/* 图标微调 */
.action-btn :deep(.el-icon) {
  font-size: 14px;
}

/* 调整 Element Plus 输入框的宽度 */
:deep(.el-date-editor.el-input) {
  width: 160px;
}
:deep(.district-hover-popup .maplibregl-popup-content) {
  padding: 10px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  font-family: "Microsoft YaHei", sans-serif;
  min-width: 150px;
}

:deep(.hover-content) {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

:deep(.hover-title) {
  font-size: 14px;
  font-weight: bold;
  color: #333;
  border-bottom: 1px solid #eee;
  padding-bottom: 4px;
  margin-bottom: 2px;
}

:deep(.hover-row) {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #666;
}

:deep(.hover-row .value) {
  font-weight: 600;
}

/* 给不同数值加点颜色区分 */
:deep(.val-ny) { color: #1976d2; }
:deep(.val-wy) { color: #388e3c; }
:deep(.val-yd) { color: #f57c00; }

:deep(.hover-loading) {
  font-size: 12px;
  color: #999;
  text-align: center;
  padding: 5px 0;
}

</style>
