// 地图相关功能
const WeatherMap = {
    map: null,
    stations: [],
    stationLayer: null,
    clusterLayer: null,
    clusterSource: null,
    singleStationLayer: null,
    combinedChart: null,
    CLUSTER_THRESHOLD: 10,
    isMapCollapsed: false,

    // 初始化地图
    init(tiandituKey) {
        this.initializeLayers();
        this.initializeMap(tiandituKey);
        this.setupEventListeners();
        this.setupTileControls();
        // 默认叠加：组合反射率（radar），并准备默认索引
        this.tileZ = 7; this.tileY = 40; this.tileX = 102;
        this.tileProduct = 'radar';
        const prodSel = document.getElementById('tileProduct');
        if (prodSel) prodSel.value = 'radar';
        // 触发首次加载
        try { this.reloadTileTimesAndShow(); } catch(e) { console.warn('init tiles load failed', e); }
    },

    // 初始化图层
    initializeLayers() {
        this.stationLayer = new ol.layer.Vector({
            source: new ol.source.Vector()
        });

        this.clusterSource = new ol.source.Cluster({
            distance: 60,
            minDistance: 20,
            source: this.stationLayer.getSource(),
            geometryFunction: function(feature) {
                return feature.getGeometry();
            }
        });

        this.clusterLayer = new ol.layer.Vector({
            source: this.clusterSource,
            style: (feature) => this.createClusterStyle(feature)
        });

        this.singleStationLayer = new ol.layer.Vector({
            source: this.stationLayer.getSource(),
            style: (feature) => this.createStationStyle(feature),
            visible: false
        });
    },

    // 初始化地图
    initializeMap(tiandituKey) {
        const layers = this.createMapLayers(tiandituKey);
        this.layers = layers;
        
        this.map = new ol.Map({
            target: 'map',
            layers: [
                layers.satellite,
                layers.vector,
                layers.terrain,
                layers.hybrid,
                // 栅格瓦片叠加层（动态）
                this.createTileOverlayLayer(),
                this.clusterLayer,
                this.singleStationLayer
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([108, 35]),
                zoom: 5,
                minZoom: 3,
                maxZoom: 18
            })
        });

        // 初始化时设置图层状态
        const initialZoom = this.map.getView().getZoom();
        this.updateClusterDistance(initialZoom);
        this.updateLayerVisibility(initialZoom);
    },

    createTileOverlayLayer(){
        // 使用分组图层以支持同一时次叠加多块瓦片
        const group = new ol.layer.Group({
            layers: [],
            zIndex: 999,
            visible: true
        });
        this.tileOverlayGroup = group;
        return group;
    },

    // 创建地图图层
    createMapLayers(tiandituKey) {
        return {
            satellite: new ol.layer.Group({
                layers: [
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.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=${tiandituKey}`
                        })
                    }),
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.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=${tiandituKey}`
                        })
                    })
                ]
            }),
            vector: new ol.layer.Group({
                layers: [
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.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=${tiandituKey}`
                        })
                    }),
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.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=${tiandituKey}`
                        })
                    })
                ],
                visible: false
            }),
            terrain: new ol.layer.Group({
                layers: [
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tiandituKey}`
                        })
                    }),
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.tianditu.gov.cn/cta_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cta&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tiandituKey}`
                        })
                    })
                ],
                visible: false
            }),
            hybrid: new ol.layer.Group({
                layers: [
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.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=${tiandituKey}`
                        })
                    }),
                    new ol.layer.Tile({
                        source: new ol.source.XYZ({
                            url: `https://t{0-7}.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=${tiandituKey}`
                        })
                    })
                ],
                visible: false
            })
        };
    },

    // ---- 瓦片联动：控件与渲染 ----
    setupTileControls(){
        const prodSel = document.getElementById('tileProduct');
        const timeSel = document.getElementById('tileTimeSelect');
        const prevBtn = document.getElementById('btnTilePrev');
        const nextBtn = document.getElementById('btnTileNext');
        if (!prodSel || !timeSel || !prevBtn || !nextBtn) return;

        prodSel.addEventListener('change', async ()=>{
            this.tileProduct = prodSel.value;
            // 切换产品：none 则隐藏图层
            if (this.tileProduct === 'none') {
                this.tileTimes = [];
                this.tileCurrentIdx = -1;
                this.clearTileOverlays();
                this.updateTileCountInfo();
                return;
            }
            await this.reloadTileTimesAndShow();
        });
        const sEl = document.getElementById('startDate');
        const eEl = document.getElementById('endDate');
        const onRangeChange = async ()=>{
            if (this.tileProduct && this.tileProduct !== 'none') {
                await this.reloadTileTimesAndShow();
            }
        };
        if (sEl) sEl.addEventListener('change', onRangeChange);
        if (eEl) eEl.addEventListener('change', onRangeChange);
        timeSel.addEventListener('change', async ()=>{
            const dt = timeSel.value;
            if (!dt) return;
            const idx = (this.tileTimes||[]).indexOf(dt);
            if (idx >= 0) this.tileCurrentIdx = idx;
            await this.loadAndRenderTile(dt);
            this.updateTileCountInfo();
        });
        prevBtn.addEventListener('click', async ()=>{
            if (!this.tileTimes || this.tileTimes.length === 0) return;
            // times 为倒序：上一时次=更老 => idx+1
            if (this.tileCurrentIdx < this.tileTimes.length - 1) {
                this.tileCurrentIdx += 1;
                const dt = this.tileTimes[this.tileCurrentIdx];
                timeSel.value = dt;
                await this.loadAndRenderTile(dt);
                this.updateTileCountInfo();
            }
        });
        nextBtn.addEventListener('click', async ()=>{
            if (!this.tileTimes || this.tileTimes.length === 0) return;
            if (this.tileCurrentIdx > 0) {
                this.tileCurrentIdx -= 1;
                const dt = this.tileTimes[this.tileCurrentIdx];
                timeSel.value = dt;
                await this.loadAndRenderTile(dt);
                this.updateTileCountInfo();
            }
        });
    },

    async reloadTileTimesAndShow(){
        try{
            const times = await this.fetchTileTimes(this.tileProduct, this.tileZ, this.tileY, this.tileX);
            this.tileTimes = times || [];
            const timeSel = document.getElementById('tileTimeSelect');
            if (timeSel){
                timeSel.innerHTML = '';
                if (this.tileTimes.length === 0){
                    const opt = document.createElement('option'); opt.value=''; opt.textContent='无可用时次'; timeSel.appendChild(opt);
                } else {
                    this.tileTimes.forEach(dt=>{ const o=document.createElement('option'); o.value=dt; o.textContent=dt; timeSel.appendChild(o); });
                    this.tileCurrentIdx = 0;
                    timeSel.value = this.tileTimes[0];
                    await this.loadAndRenderTile(this.tileTimes[0]);
                }
                this.updateTileCountInfo();
            }
        }catch(e){ console.error('加载瓦片时次失败', e); }
    },

    updateTileCountInfo(){
        const el = document.getElementById('tileCountInfo');
        if (!el) return;
        const total = this.tileTimes ? this.tileTimes.length : 0;
        const idxDisp = (this.tileCurrentIdx != null && this.tileCurrentIdx >= 0) ? (this.tileCurrentIdx+1) : 0;
        el.textContent = `共${total}条，第${idxDisp}条`;
        const prevBtn = document.getElementById('btnTilePrev');
        const nextBtn = document.getElementById('btnTileNext');
        if (prevBtn) prevBtn.disabled = !(total>0 && this.tileCurrentIdx < total-1);
        if (nextBtn) nextBtn.disabled = !(total>0 && this.tileCurrentIdx > 0);
    },

    async fetchTileTimes(product, z,y,x){
        const sEl = document.getElementById('startDate');
        const eEl = document.getElementById('endDate');
        let url;
        if (product==='rain') url = `/api/rain/times?z=${z}&y=${y}&x=${x}`; else url = `/api/radar/times?z=${z}&y=${y}&x=${x}`;
        if (sEl && eEl && sEl.value && eEl.value) {
            const from = sEl.value.replace('T',' ') + ':00';
            const to = eEl.value.replace('T',' ') + ':00';
            url += `&from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`;
        } else {
            url += '&limit=60';
        }
        const r = await fetch(url);
        if(!r.ok) return [];
        const j = await r.json();
        return j.times || [];
    },

    async loadAndRenderTile(dtStr){
        try{
            const z=this.tileZ,y=this.tileY,x=this.tileX;
            if (this.tileProduct === 'rain') {
                // 雨量：同一时次下叠加所有 y/x 瓦片
                const url = `/api/rain/tiles_at?z=${z}&dt=${encodeURIComponent(dtStr)}`;
                const r = await fetch(url);
                if(!r.ok){
                    // 回退单块接口
                    const url1 = `/api/rain/at?z=${z}&y=${y}&x=${x}&dt=${encodeURIComponent(dtStr)}`;
                    const r1 = await fetch(url1);
                    if(!r1.ok){ console.warn('雨量瓦片未找到', dtStr); return; }
                    const t1 = await r1.json();
                    await this.renderTileOnMap('rain', t1);
                    return;
                }
                const j = await r.json();
                const tiles = Array.isArray(j.tiles) ? j.tiles : [];
                if (tiles.length === 0) { console.warn('该时次无雨量瓦片集合'); this.clearTileOverlays(); return; }
                await this.renderTilesOnMap('rain', tiles);
            } else {
                // radar: 取同一时次该 z 下的所有 y/x 瓦片
                const url = `/api/radar/tiles_at?z=${z}&dt=${encodeURIComponent(dtStr)}`;
                const r = await fetch(url);
                if(!r.ok){
                    // 兼容后备：退回单块接口
                    const url1 = `/api/radar/at?z=${z}&y=${y}&x=${x}&dt=${encodeURIComponent(dtStr)}`;
                    const r1 = await fetch(url1);
                    if(!r1.ok){ console.warn('雷达瓦片未找到', dtStr); return; }
                    const t1 = await r1.json();
                    await this.renderTileOnMap('radar', t1);
                    return;
                }
                const j = await r.json();
                const tiles = Array.isArray(j.tiles) ? j.tiles : [];
                if (tiles.length === 0) { console.warn('该时次无雷达瓦片集合'); this.clearTileOverlays(); return; }
                await this.renderTilesOnMap('radar', tiles);
            }
        }catch(e){ console.error('加载/渲染瓦片失败', e); }
    },

    clearTileOverlays(){
        if (!this.tileOverlayGroup) return;
        // 清空子图层
        const coll = this.tileOverlayGroup.getLayers();
        if (coll) coll.clear();
        this.tileLastList = [];
    },

    addImageOverlayFromCanvas(canvas, extent4326){
        const proj = this.map.getView().getProjection();
        const extentProj = ol.proj.transformExtent(extent4326, 'EPSG:4326', proj);
        const dataURL = canvas.toDataURL('image/png');
        const src = new ol.source.ImageStatic({ url: dataURL, imageExtent: extentProj, projection: proj });
        const layer = new ol.layer.Image({ source: src, opacity: 0.8, visible: true });
        this.tileOverlayGroup.getLayers().push(layer);
    },

    renderTileOnMap(product, t){
        if(!t || !t.values) return;
        const w=t.width, h=t.height, resDeg=t.res_deg;
        const west=t.west, south=t.south, east=t.east, north=t.north;
        // 生成画布
        const canvas = document.createElement('canvas');
        canvas.width = w; canvas.height = h;
        const ctx = canvas.getContext('2d');
        const imgData = ctx.createImageData(w, h);
        // 色带
        let colorFunc;
        if (product==='rain'){
            const edges = [0,5,7.5,10,12.5,15,17.5,20,25,30,40,50,75,100, Infinity];
            const colors = [
                // 0值透明，(0,5) 用绿色，不再用白色
                [126,212,121], [126,212,121], [110,200,109], [97,169,97], [81,148,76], [90,158,112],
                [143,194,254], [92,134,245], [66,87,240], [45,48,214], [26,15,166], [63,22,145], [191,70,148], [213,1,146], [213,1,146]
            ];
            colorFunc = (mm)=>{
                if (mm===0) return [0,0,0,0]; // 0 值透明
                let idx=0; while(idx<edges.length-1 && !(mm>=edges[idx] && mm<edges[idx+1])) idx++;
                const c = colors[Math.min(idx, colors.length-1)]; return [c[0],c[1],c[2],220];
            };
        } else {
            // radar dBZ，0..75 映射 15 段
            const colors = [[0,0,255],[0,191,255],[0,255,255],[127,255,212],[124,252,0],[173,255,47],[255,255,0],[255,215,0],[255,165,0],[255,140,0],[255,69,0],[255,0,0],[220,20,60],[199,21,133],[139,0,139]];
            colorFunc = (dbz)=>{
                let v = Math.max(0, Math.min(75, dbz));
                if (v===0) return [0,0,0,0]; // 0 值透明
                let bin = Math.floor(v/5); if (bin>=colors.length) bin=colors.length-1;
                const c = colors[bin]; return [c[0],c[1],c[2],220];
            };
        }
        // API 行从南到北？我们按数组行序逐行，从上到下绘制需倒置行
        let p=0;
        for(let row=0; row<h; row++){
            const srcRow = t.values[row] || [];
            const dstRow = (h-1-row); // 翻转以匹配北向上
            for(let col=0; col<w; col++){
                const v = srcRow[col];
                let rgba;
                if (v==null){ rgba=[0,0,0,0]; }
                else { rgba = colorFunc(Number(v)); }
                const off = (dstRow*w + col)*4;
                imgData.data[off+0]=rgba[0];
                imgData.data[off+1]=rgba[1];
                imgData.data[off+2]=rgba[2];
                imgData.data[off+3]=rgba[3];
            }
        }
        ctx.putImageData(imgData, 0, 0);
        // 清空并添加唯一图层
        this.clearTileOverlays();
        this.addImageOverlayFromCanvas(canvas, [west, south, east, north]);
        // 保存用于拾取（单块）
        this.tileLastList = [{ product, meta: { west, south, east, north, resDeg, width:w, height:h }, values: t.values }];
        this.setupTileHover();
    },

    renderTilesOnMap(product, tiles){
        // tiles: radarTileResponse[]
        this.clearTileOverlays();
        const lastList = [];
        for (const t of tiles){
            if(!t || !t.values) continue;
            const w=t.width, h=t.height, resDeg=t.res_deg;
            const west=t.west, south=t.south, east=t.east, north=t.north;
            const canvas = document.createElement('canvas');
            canvas.width = w; canvas.height = h;
            const ctx = canvas.getContext('2d');
            const imgData = ctx.createImageData(w, h);
            let colorFunc;
            if (product==='rain'){
                const edges = [0,5,7.5,10,12.5,15,17.5,20,25,30,40,50,75,100, Infinity];
                const colors = [
                    // 0值透明，(0,5) 用绿色，不再用白色
                    [126,212,121], [126,212,121], [110,200,109], [97,169,97], [81,148,76], [90,158,112],
                    [143,194,254], [92,134,245], [66,87,240], [45,48,214], [26,15,166], [63,22,145], [191,70,148], [213,1,146], [213,1,146]
                ];
                colorFunc = (mm)=>{
                    if (mm===0) return [0,0,0,0];
                    let idx=0; while(idx<edges.length-1 && !(mm>=edges[idx] && mm<edges[idx+1])) idx++;
                    const c = colors[Math.min(idx, colors.length-1)]; return [c[0],c[1],c[2],220];
                };
            } else {
                const colors = [[0,0,255],[0,191,255],[0,255,255],[127,255,212],[124,252,0],[173,255,47],[255,255,0],[255,215,0],[255,165,0],[255,140,0],[255,69,0],[255,0,0],[220,20,60],[199,21,133],[139,0,139]];
                colorFunc = (dbz)=>{
                    let v = Math.max(0, Math.min(75, dbz));
                    if (v===0) return [0,0,0,0];
                    let bin = Math.floor(v/5); if (bin>=colors.length) bin=colors.length-1;
                    const c = colors[bin]; return [c[0],c[1],c[2],220];
                };
            }
            for(let row=0; row<h; row++){
                const srcRow = t.values[row] || [];
                const dstRow = (h-1-row);
                for(let col=0; col<w; col++){
                    const v = srcRow[col];
                    let rgba;
                    if (v==null){ rgba=[0,0,0,0]; }
                    else { rgba = colorFunc(Number(v)); }
                    const off = (dstRow*w + col)*4;
                    imgData.data[off+0]=rgba[0];
                    imgData.data[off+1]=rgba[1];
                    imgData.data[off+2]=rgba[2];
                    imgData.data[off+3]=rgba[3];
                }
            }
            ctx.putImageData(imgData, 0, 0);
            this.addImageOverlayFromCanvas(canvas, [west, south, east, north]);
            lastList.push({ product, meta: { west, south, east, north, resDeg, width:w, height:h }, values: t.values });
        }
        this.tileLastList = lastList;
        this.setupTileHover();
    },

    setupTileHover(){
        if (this._hoverBound) return;
        const tip = document.getElementById('tileValueTooltip');
        if (!tip) return;
        this.map.on('pointermove', (evt)=>{
            try{
                // 需要至少一个叠加瓦片
                if (!this.tileLastList || !this.tileOverlayGroup || this.tileOverlayGroup.getLayers().getLength()===0) { tip.style.display='none'; return; }
                const coord = this.map.getEventCoordinate(evt.originalEvent);
                const lonlat = ol.proj.transform(coord, this.map.getView().getProjection(), 'EPSG:4326');
                const lon = lonlat[0], lat = lonlat[1];
                // 选中包含该点的第一块瓦片
                let pickedVal = null, pickedProd = null;
                for (const it of this.tileLastList){
                    const {west,south,east,north,resDeg,width,height} = it.meta;
                    if (lon<west || lon>east || lat<south || lat>north) continue;
                    const col = Math.floor((lon - west)/resDeg);
                    const row = Math.floor((lat - south)/resDeg);
                    if (row<0 || row>=height || col<0 || col>=width) continue;
                    const v = it.values[row]?.[col];
                    if (v==null) continue;
                    pickedVal = Number(v); pickedProd = it.product; break;
                }
                if (pickedVal==null){ tip.style.display='none'; return; }
                const txt = pickedProd==='rain' ? `${pickedVal.toFixed(1)} mm` : `${pickedVal.toFixed(1)} dBZ`;
                tip.textContent = txt;
                // 位置
                const pixel = this.map.getPixelFromCoordinate(coord);
                tip.style.left = (pixel[0]+10) + 'px';
                tip.style.top = (pixel[1]+10) + 'px';
                tip.style.display = 'block';
            }catch{ tip.style.display='none'; }
        });
        this._hoverBound = true;
    },

    // 设置事件监听
    setupEventListeners() {
        // 监听缩放事件
        this.map.getView().on('change:resolution', () => {
            const zoom = this.map.getView().getZoom();
            this.updateClusterDistance(zoom);
            this.updateLayerVisibility(zoom);
        });

        // 添加点击事件
        this.map.on('click', (event) => this.handleMapClick(event));

        // 添加鼠标移动事件
        this.map.on('pointermove', (event) => {
            const pixel = this.map.getEventPixel(event.originalEvent);
            const hit = this.map.hasFeatureAtPixel(pixel);
            this.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
        });
    },

    // 处理地图点击
    handleMapClick(event) {
        const feature = this.map.forEachFeatureAtPixel(event.pixel, feature => feature);
        
        if (!feature) return;

        const features = feature.get('features');
        if (features && features.length > 1) {
            this.handleClusterClick(features);
        } else {
            this.handleStationClick(features ? features[0] : feature);
        }
    },

    // 处理集群点击
    handleClusterClick(features) {
        const extent = ol.extent.createEmpty();
        features.forEach(feature => {
            ol.extent.extend(extent, feature.getGeometry().getExtent());
        });
        
        const zoom = this.map.getView().getZoom();
        const targetZoom = Math.min(
            features.length <= 5 ? this.CLUSTER_THRESHOLD : zoom + 2,
            this.CLUSTER_THRESHOLD
        );
        
        this.map.getView().fit(extent, {
            padding: [100, 100, 100, 100],
            duration: 800,
            maxZoom: targetZoom
        });
    },

    // 处理站点点击
    handleStationClick(feature) {
        const decimalId = feature.get('decimalId');
        if (!decimalId) return;

        document.getElementById('stationInput').value = decimalId;
        
        const center = feature.getGeometry().getCoordinates();
        const currentZoom = this.map.getView().getZoom();
        
        if (currentZoom < this.CLUSTER_THRESHOLD) {
            this.map.getView().animate({
                center: center,
                zoom: this.CLUSTER_THRESHOLD,
                duration: 500
            });
        }
        
        if (document.getElementById('interval').value === '1hour') {
            // 触发查询事件
            window.dispatchEvent(new CustomEvent('query-history-data'));
        }
    },

    // 更新集群距离
    updateClusterDistance(zoom) {
        let distance;
        if (zoom < 5) distance = 120;
        else if (zoom < 7) distance = 90;
        else if (zoom < 9) distance = 60;
        else if (zoom < this.CLUSTER_THRESHOLD) distance = 40;
        else distance = 0;
        
        this.clusterSource.setDistance(distance);
        this.clusterSource.refresh();
        
        setTimeout(() => {
            this.clusterLayer.changed();
            this.singleStationLayer.changed();
        }, 100);
    },

    // 更新图层可见性
    updateLayerVisibility(zoom) {
        if (zoom >= this.CLUSTER_THRESHOLD) {
            this.clusterLayer.setVisible(false);
            this.singleStationLayer.setVisible(true);
        } else {
            this.clusterLayer.setVisible(true);
            this.singleStationLayer.setVisible(false);
        }
    },

    // 创建站点样式
    createStationStyle(feature) {
        const isOnline = new Date(feature.get('lastUpdate')) > new Date(Date.now() - 5*60*1000);
        const zoom = this.map ? this.map.getView().getZoom() : 10;
        let labelText = '';
        
        if (zoom >= this.CLUSTER_THRESHOLD - 2) {
            labelText = `${feature.get('decimalId') || '未知'} | ${feature.get('name') || '未知'} | ${feature.get('location') || '未知'}`;
        }

        return new ol.style.Style({
            image: this.getMarkerIconStyle(isOnline).getImage(),
            text: new ol.style.Text({
                text: labelText,
                font: '11px Arial',
                offsetY: -24,
                textAlign: 'center',
                textBaseline: 'bottom',
                fill: new ol.style.Fill({ color: '#666' }),
                stroke: new ol.style.Stroke({ color: '#fff', width: 2 })
            })
        });
    },

    // 创建集群样式
    createClusterStyle(feature) {
        const features = feature.get('features');
        const size = features.length;
        const zoom = this.map.getView().getZoom();

        if (zoom < this.CLUSTER_THRESHOLD) {
            if (size > 1) {
                const radius = Math.min(16 + size * 0.8, 32);
                const fontSize = Math.min(11 + size/12, 16);
                
                return new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: radius,
                        fill: new ol.style.Fill({ color: 'rgba(0, 123, 255, 0.8)' }),
                        stroke: new ol.style.Stroke({ color: '#fff', width: 2 })
                    }),
                    text: new ol.style.Text({
                        text: String(size),
                        fill: new ol.style.Fill({ color: '#fff' }),
                        font: `bold ${fontSize}px Arial`,
                        offsetY: 1
                    })
                });
            }
            return new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 6,
                    fill: new ol.style.Fill({ 
                        color: new Date(features[0].get('lastUpdate')) > 
                               new Date(Date.now() - 5*60*1000) ? '#007bff' : '#6c757d' 
                    }),
                    stroke: new ol.style.Stroke({ color: '#fff', width: 2 })
                })
            });
        }

        if (size === 1) {
            return this.createStationStyle(features[0]);
        }
        
        const radius = Math.min(16 + size * 0.8, 32);
        const fontSize = Math.min(11 + size/12, 16);
        
        return new ol.style.Style({
            image: new ol.style.Circle({
                radius: radius,
                fill: new ol.style.Fill({ color: 'rgba(0, 123, 255, 0.8)' }),
                stroke: new ol.style.Stroke({ color: '#fff', width: 2 })
            }),
            text: new ol.style.Text({
                text: String(size),
                fill: new ol.style.Fill({ color: '#fff' }),
                font: `bold ${fontSize}px Arial`,
                offsetY: 1
            })
        });
    },

    // 获取标记图标样式
    getMarkerIconStyle(isOnline) {
        const key = isOnline ? 'online' : 'offline';
        if (this.markerStyleCache?.[key]) return this.markerStyleCache[key];

        const iconPath = isOnline ? '/static/images/marker-online.svg' : '/static/images/marker-offline.svg';
        const style = new ol.style.Style({
            image: new ol.style.Icon({
                src: iconPath,
                anchor: [0.5, 1],
                anchorXUnits: 'fraction',
                anchorYUnits: 'fraction',
                scale: 0.9
            })
        });

        if (!this.markerStyleCache) this.markerStyleCache = {};
        this.markerStyleCache[key] = style;
        return style;
    },

    // 切换地图图层
    switchLayer(layerType) {
        Object.keys(this.layers).forEach(key => {
            this.layers[key].setVisible(key === layerType);
        });
    },

    // 切换地图折叠状态
    toggleMap() {
        this.isMapCollapsed = !this.isMapCollapsed;
        const mapContainer = document.getElementById('mapContainer');
        const toggleBtn = document.getElementById('toggleMapBtn');
        
        if (this.isMapCollapsed) {
            mapContainer?.classList.add('collapsed');
            if (toggleBtn) toggleBtn.textContent = '展开地图';
        } else {
            mapContainer?.classList.remove('collapsed');
            if (toggleBtn) toggleBtn.textContent = '折叠地图';
        }
        
        setTimeout(() => {
            this.map.updateSize();
        }, 300);
    },

    // 加载站点数据
    async loadStations() {
        try {
            const response = await fetch('/api/stations');
            if (!response.ok) {
                console.warn('获取站点列表失败，HTTP', response.status);
                this.stations = [];
            } else {
                const data = await response.json();
                this.stations = Array.isArray(data) ? data : [];
            }
            
            // 更新WH65LP设备数量
            const wh65lpDevices = (this.stations || []).filter(station => station.device_type === 'WH65LP');
            const cntEl = document.getElementById('wh65lpCount');
            if (cntEl) cntEl.textContent = wh65lpDevices.length;
            
            this.displayStationsOnMap();
        } catch (error) {
            console.error('加载站点失败:', error);
            this.stations = [];
        }
    },

    // 在地图上显示站点
    displayStationsOnMap() {
        const source = this.stationLayer.getSource();
        source.clear();

        const now = Date.now();
        const fiveMinutesAgo = now - 5 * 60 * 1000;
        let onlineCount = 0;
        let offlineCount = 0;

        this.stations.forEach(station => {
            if (station.latitude && station.longitude) {
                const isOnline = new Date(station.last_update) > new Date(fiveMinutesAgo);
                if (isOnline) onlineCount++; else offlineCount++;

                const feature = new ol.Feature({
                    geometry: new ol.geom.Point(ol.proj.fromLonLat([station.longitude, station.latitude])),
                    stationId: station.station_id,
                    decimalId: station.decimal_id,
                    name: station.name,
                    location: station.location,
                    lastUpdate: station.last_update,
                    isOnline: isOnline
                });

                source.addFeature(feature);
            }
        });

        console.log(`已加载 ${this.stations.length} 个站点，在线: ${onlineCount}，离线: ${offlineCount}`);

        if (source.getFeatures().length > 0) {
            if (source.getFeatures().length === 1) {
                const feature = source.getFeatures()[0];
                this.map.getView().setCenter(feature.getGeometry().getCoordinates());
                this.map.getView().setZoom(12);
            } else {
                const extent = source.getExtent();
                this.map.getView().fit(extent, {
                    padding: [50, 50, 50, 50],
                    maxZoom: 10
                });
            }
        }
        
        this.updateClusterDistance(this.map.getView().getZoom());
    }
};

// 导出地图对象
window.WeatherMap = WeatherMap; 
