const WeatherApp = {
    cachedHistoryData: [],
    cachedForecastData: [],
    currentPage: 1,
    itemsPerPage: 10,
    filteredDevices: [],

    init() {
        WeatherUtils.initializeDateInputs();
        WeatherMap.init(window.TIANDITU_KEY || '');
        WeatherMap.loadStations();
        setInterval(() => this.updateOnlineDevices(), 30000);
        this.bindUI();
        window.addEventListener('query-history-data', () => this.queryHistoryData());
        // 大屏：每10分钟刷新一次雷达/雨量瓦片时次并更新显示
        if (window.IS_BIGSCREEN) {
            // 防抖锁，避免重复请求
            this._autoRefreshing = false;
            setInterval(async () => {
                try {
                    // 刷新雷达/雨量瓦片时次
                    if (WeatherMap && typeof WeatherMap.reloadTileTimesAndShow === 'function') {
                        const prodSel = document.getElementById('tileProduct');
                        const prod = prodSel ? prodSel.value : WeatherMap.tileProduct;
                        if (prod && prod !== 'none') {
                            WeatherMap.reloadTileTimesAndShow();
                        }
                    }
                    // 刷新图表/表格（基于当前控件选择）
                    const sid = (document.getElementById('stationInput')?.value || '').trim();
                    if (!this._autoRefreshing && sid) {
                        this._autoRefreshing = true;
                        try { await this.queryHistoryData(); } finally { this._autoRefreshing = false; }
                    }
                } catch (e) { console.warn('自动刷新失败', e); }
            }, 10 * 60 * 1000);
        }
    },

    bindUI() {
        const stationInput = document.getElementById('stationInput');
        if (stationInput) {
            stationInput.addEventListener('input', function() {
                this.value = this.value.toUpperCase().replace(/[^0-9A-F]/g, '');
            });
            stationInput.addEventListener('change', function() {
                const value = this.value.trim();
                if (!value) return;
                if (/^[0-9A-F]+$/i.test(value)) {
                    if (value.length <= 6) this.value = WeatherUtils.hexToDecimal(value);
                } else {
                    const num = parseInt(value);
                    if (!isNaN(num)) this.value = num.toString();
                }
            });
        }

        const showDeviceListBtn = document.getElementById('showDeviceList');
        const modal = document.getElementById('deviceModal');
        const closeBtn = document.querySelector('.close-modal');
        const prevPageBtn = document.getElementById('prevPage');
        const nextPageBtn = document.getElementById('nextPage');

        const deviceListEl = document.getElementById('deviceList');
        if (deviceListEl && modal) {
            deviceListEl.addEventListener('click', (e) => {
                const deviceItem = e.target.closest('.device-item');
                if (!deviceItem) return;
                const decimalId = deviceItem.getAttribute('data-decimal-id');
                const input = document.getElementById('stationInput');
                if (input) input.value = decimalId;
                window.dispatchEvent(new CustomEvent('close-device-modal'));
                this.queryHistoryData();
            });
        }

        const showPastForecast = document.getElementById('showPastForecast');
        if (showPastForecast) {
            showPastForecast.addEventListener('change', () => {
                WeatherTable.display(this.cachedHistoryData, this.cachedForecastData);
            });
        }

        const legendMode = document.getElementById('legendMode');
        if (legendMode) {
            legendMode.addEventListener('change', (e) => {
                const mode = e.target.value;
                if (window.WeatherChart && typeof window.WeatherChart.applyLegendMode === 'function') {
                    window.WeatherChart.applyLegendMode(mode);
                }
            });
        }

        window.switchLayer = (type) => WeatherMap.switchLayer(type);
        window.toggleMap = () => WeatherMap.toggleMap();
        window.queryHistoryData = () => this.queryHistoryData();
    },

    updateDeviceList(page = 1) {
        const deviceListContainer = document.getElementById('deviceList');
        if (!deviceListContainer) return;
        deviceListContainer.innerHTML = '';

        this.filteredDevices = (WeatherMap.stations || [])
            .filter(station => station.device_type === 'WH65LP')
            .sort((a, b) => {
                const aOnline = WeatherUtils.isDeviceOnline(a.last_update);
                const bOnline = WeatherUtils.isDeviceOnline(b.last_update);
                if (aOnline === bOnline) return 0;
                return aOnline ? -1 : 1;
            });

        const totalPages = Math.ceil(this.filteredDevices.length / this.itemsPerPage) || 1;
        this.currentPage = Math.min(Math.max(1, page), totalPages);

        const currentPageEl = document.getElementById('currentPage');
        const totalPagesEl = document.getElementById('totalPages');
        const prevBtn = document.getElementById('prevPage');
        const nextBtn = document.getElementById('nextPage');
        if (currentPageEl) currentPageEl.textContent = this.currentPage;
        if (totalPagesEl) totalPagesEl.textContent = totalPages;
        if (prevBtn) prevBtn.disabled = this.currentPage <= 1;
        if (nextBtn) nextBtn.disabled = this.currentPage >= totalPages;

        const startIndex = (this.currentPage - 1) * this.itemsPerPage;
        const endIndex = startIndex + this.itemsPerPage;
        const currentDevices = this.filteredDevices.slice(startIndex, endIndex);

        currentDevices.forEach(device => {
            const isOnline = WeatherUtils.isDeviceOnline(device.last_update);
            const deviceItem = document.createElement('div');
            deviceItem.className = 'device-item';
            deviceItem.setAttribute('data-decimal-id', device.decimal_id);
            deviceItem.innerHTML = `
                <div style="font-size: 13px; color: #444">
                    ${device.decimal_id} | ${device.name} | ${device.location || '未知位置'}
                </div>
                <span style="color: ${isOnline ? '#28a745' : '#dc3545'}; font-size: 12px; padding: 2px 6px; background: ${isOnline ? '#f0f9f1' : '#fef5f5'}; border-radius: 3px">${isOnline ? '在线' : '离线'}</span>
            `;
            deviceListContainer.appendChild(deviceItem);
        });

        if (this.filteredDevices.length === 0) {
            deviceListContainer.innerHTML = '<div style="padding: 20px; text-align: center; color: #666;">暂无WH65LP设备</div>';
        }
    },

    async updateOnlineDevices() {
        try {
            const response = await fetch('/api/system/status');
            const data = await response.json();
            const onlineEl = document.getElementById('onlineDevices');
            if (onlineEl) onlineEl.textContent = data.online_devices;
        } catch (error) {
            console.error('更新在线设备数量失败:', error);
        }
    },

    async queryHistoryData() {
        const decimalId = (document.getElementById('stationInput')?.value || '').trim();
        if (!decimalId) {
            alert('请输入站点编号');
            return;
        }
        if (!/^\d+$/.test(decimalId)) {
            alert('请输入有效的十进制编号');
            return;
        }

        const startTime = document.getElementById('startDate')?.value || '';
        const endTime = document.getElementById('endDate')?.value || '';
        const interval = document.getElementById('interval')?.value || '1hour';
        const forecastProvider = document.getElementById('forecastProvider')?.value || '';
        if (!startTime || !endTime) {
            alert('请选择开始和结束时间');
            return;
        }

        try {
            const historyParams = new URLSearchParams({
                decimal_id: decimalId,
                start_time: startTime.replace('T', ' ') + ':00',
                end_time: endTime.replace('T', ' ') + ':00',
                interval: interval
            });
            const historyResponse = await fetch(`/api/data?${historyParams}`);
            if (!historyResponse.ok) throw new Error('查询历史数据失败');
            const responseData = await historyResponse.json();
            const historyData = Array.isArray(responseData) ? responseData : [];

            let forecastData = [];
            if (forecastProvider && interval === '1hour') {
                try {
                    const hexID = WeatherUtils.decimalToHex(decimalId);
                    const stationID = `RS485-${hexID}`;
                    // 将预报查询范围按小时对齐：from 向下取整到整点；to 向上取整到整点，再 +3h
                    const parseLocal = (s) => { try { return new Date(s); } catch { return null; } };
                    const floorHour = (d) => { const t = new Date(d); t.setMinutes(0,0,0); return t; };
                    const ceilHour = (d) => { const t = new Date(d); if (t.getMinutes()||t.getSeconds()||t.getMilliseconds()) { t.setHours(t.getHours()+1); } t.setMinutes(0,0,0); return t; };
                    const fmt = (d) => {
                        const y=d.getFullYear(); const m=String(d.getMonth()+1).padStart(2,'0'); const da=String(d.getDate()).padStart(2,'0');
                        const h=String(d.getHours()).padStart(2,'0'); const mi='00'; const s='00';
                        return `${y}-${m}-${da} ${h}:${mi}:${s}`;
                    };
                    const startD = parseLocal(startTime);
                    const endD = parseLocal(endTime);
                    const fromStr = startD && !isNaN(startD) ? fmt(floorHour(startD)) : startTime.replace('T',' ') + ':00';
                    const toStr = endD && !isNaN(endD) ? fmt(new Date(ceilHour(endD).getTime() + 3*60*60*1000)) : endTime.replace('T',' ') + ':00';
                    const forecastParams = new URLSearchParams({
                        station_id: stationID,
                        from: fromStr,
                        to: toStr,
                        provider: forecastProvider,
                        versions: '3'
                    });
                    const forecastResponse = await fetch(`/api/forecast?${forecastParams}`);
                    if (forecastResponse.ok) {
                        const responseData = await forecastResponse.json();
                        forecastData = Array.isArray(responseData) ? responseData : [];
                        console.log(`查询到 ${forecastData.length} 条预报数据`);
                    }
                } catch (e) {
                    console.warn('查询预报数据失败:', e);
                }
            }

            this.cachedHistoryData = historyData;
            this.cachedForecastData = forecastData;

            if (historyData.length === 0 && forecastData.length === 0) {
                alert('该时间段内无数据');
                return;
            }

            const station = (WeatherMap.stations || []).find(s => s.decimal_id == decimalId);
            const stationInfoTitle = document.getElementById('stationInfoTitle');
            if (stationInfoTitle) {
                // 仅展示站点位置（location）；无有效值时保持现有文本不变
                const loc = station?.location || '';
                if (loc) stationInfoTitle.textContent = loc;
            }

            if (!WeatherMap.isMapCollapsed) WeatherMap.toggleMap();

            WeatherChart.display(historyData, forecastData);
            WeatherTable.display(historyData, forecastData);

            const chartContainer = document.getElementById('chartContainer');
            const tableContainer = document.getElementById('tableContainer');
            if (chartContainer) chartContainer.classList.add('show');
            if (tableContainer) tableContainer.classList.add('show');
            setTimeout(() => {
                chartContainer?.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }, 300);

            const legendMode = document.getElementById('legendMode');
            if (legendMode) {
                WeatherChart.applyLegendMode(legendMode.value);
            }

            // 更新大屏摘要区域（未来降雨与过去准确率）
            this.updateSummaryPanel(historyData, forecastData);
        } catch (error) {
            console.error('查询数据失败:', error);
            alert('查询数据失败: ' + error.message);
        }
    }
};

window.WeatherApp = WeatherApp;

document.addEventListener('DOMContentLoaded', () => {
    WeatherApp.init();
}); 

// 扩展：用于大屏摘要展示
WeatherApp.updateSummaryPanel = function(historyData, forecastData){
    try{
        const elFuture = document.getElementById('futureRainSummary');
        const elAcc = document.getElementById('pastAccuracySummary');
        if (!elFuture && !elAcc) return;

        // --- 未来1~3小时降雨 ---
        const fmt = (n)=> (n==null||isNaN(Number(n))) ? '--' : Number(n).toFixed(1);
        const pad2 = (n)=> String(n).padStart(2,'0');
        const fmtDT = (d)=> `${d.getFullYear()}-${pad2(d.getMonth()+1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:00:00`;
        const now = new Date();
        const ceilHour = (d)=>{ const t = new Date(d); if (t.getMinutes()||t.getSeconds()||t.getMilliseconds()) t.setHours(t.getHours()+1); t.setMinutes(0,0,0); return t; };
        const t1 = ceilHour(now), t2 = new Date(t1.getTime()+3600*1000), t3 = new Date(t1.getTime()+2*3600*1000);
        const pickBestAt = (dtStr)=>{
            const cand = (forecastData||[]).filter(x=>x.date_time===dtStr && x.rainfall!=null);
            if (cand.length===0) return null;
            // 选择最小 lead_hours 的记录
            cand.sort((a,b)=> (a.lead_hours??99)-(b.lead_hours??99));
            return cand[0].rainfall;
        };
        const r1 = pickBestAt(fmtDT(t1));
        const r2 = pickBestAt(fmtDT(t2));
        const r3 = pickBestAt(fmtDT(t3));
        const futureSum = [r1,r2,r3].reduce((s,v)=> s + (v!=null?Number(v):0), 0);
        if (elFuture) elFuture.textContent = `未来1~3小时降雨 ${fmt(futureSum)} 毫米`;

        // 预警等级：>0.4 红色；>0.0 橙色；否则无
        try {
            const panel = document.getElementById('summaryPanel');
            const screen = document.querySelector('.screen');
            const setLevel = (sum) => {
                const isRed = sum > 1;
                const isOrange = !isRed && sum > 0 && sum < 1;
                if (panel) {
                    panel.classList.toggle('alert-red', isRed);
                    panel.classList.toggle('alert-on', isOrange);
                    if (!isRed && !isOrange) { panel.classList.remove('alert-red','alert-on'); }
                }
                if (screen) {
                    screen.classList.toggle('alert-red', isRed);
                    screen.classList.toggle('alert-on', isOrange);
                    if (!isRed && !isOrange) { screen.classList.remove('alert-red','alert-on'); }
                }
            };
            setLevel(futureSum);
        } catch {}

        // --- 过去预报准确率（按小时分档 [0,5), [5,10), [10,∞)）---
        const bucketOf = (mm)=>{
            if (mm==null || isNaN(Number(mm))) return null;
            const v = Math.max(0, Number(mm));
            if (v < 5) return 0; if (v < 10) return 1; return 2;
        };
        const rainActual = new Map();
        (historyData||[]).forEach(it=>{ if (it && it.date_time) rainActual.set(it.date_time, it.rainfall); });
        const tally = (lead)=>{
            let correct=0,total=0;
            (forecastData||[]).forEach(f=>{
                if (f.lead_hours!==lead) return;
                const a = rainActual.get(f.date_time);
                if (a==null) return;
                const ba=bucketOf(a), bf=bucketOf(f.rainfall);
                if (ba==null || bf==null) return;
                total += 1; if (ba===bf) correct += 1;
            });
            return {correct,total};
        };
        const rH1 = tally(1), rH2 = tally(2), rH3 = tally(3);
        const pct = (r)=> r.total>0 ? `${(r.correct/r.total*100).toFixed(1)}%` : '--';
        if (elAcc) elAcc.textContent = `过去预报准确率  +1h: ${pct(rH1)}  +2h: ${pct(rH2)}  +3h: ${pct(rH3)}`;
    }catch(e){ console.warn('更新摘要失败', e); }
}
