# server.py
from flask import Flask, request, jsonify, render_template_string
import json

app = Flask(__name__)

# 存储告警数据的列表，最多存储5条
alerts = []

# HTML 页面模板
HTML_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
    <title>边缘告警平台</title>
    <style>
        /* 隐藏滚动条 */
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #00093D; /* 主背景色 */
            color: #E0E0E0;
            overflow: hidden; /* 隐藏滚动条 */
            height: 100vh; /* 占满视口高度 */
        }
        
        /* 全屏图片查看器 */
        #image-viewer {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.95); /* 更深的背景 */
            display: none; /* 默认隐藏 */
            justify-content: center;
            align-items: center;
            z-index: 1000;
            cursor: zoom-out; /* 提示可以点击缩小 */
        }
        
        #fullscreen-image {
            max-width: 95%;
            max-height: 95%;
            border: 2px solid #4CAF50;
            border-radius: 4px;
            box-shadow: 0 0 20px rgba(76, 175, 80, 0.3);
        }

        .container {
            max-width: 1200px;
            height: 100vh; /* 容器占满视口 */
            margin: 0 auto;
            background-color: #0A1442; /* 容器背景色 */
            padding: 20px;
            box-sizing: border-box;
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.5);
            display: flex;
            flex-direction: column;
        }
        
        h1 {
            color: #4CAF50; /* 标题颜色 */
            text-align: center;
            margin-top: 20px;
            margin-bottom: 30px;
            font-size: 2.2em;
            text-shadow: 0 0 10px rgba(76, 175, 80, 0.4);
        }
        
        .table-container {
            flex-grow: 1; /* 占据剩余空间 */
            overflow: auto; /* 表格区域可滚动 */
            border: 1px solid #213063;
            border-radius: 8px;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            background-color: #121D4A; /* 表格背景色 */
        }
        
        th, td {
            border: 1px solid #213063;
            padding: 15px 12px;
            text-align: left;
        }
        
        th {
            background-color: #1A2A6C; /* 表头背景色 */
            color: #FFFFFF;
            font-weight: bold;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        
        tr:nth-child(even) {
            background-color: #1A2550; /* 表格行交替色 */
        }
        
        tr:hover {
            background-color: #253569; /* 悬停色 */
        }
        
        .no-alerts {
            text-align: center;
            color: #AAAAAA;
            font-style: italic;
            padding: 40px 20px;
            font-size: 1.1em;
        }
        
        .image-cell {
            text-align: center;
            cursor: pointer; /* 提示图片可点击 */
        }
        
        .alert-image {
            max-width: 180px;
            max-height: 120px;
            border: 1px solid #445588;
            border-radius: 6px;
            transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s;
        }
        
        .alert-image:hover {
            transform: scale(1.03);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
            border-color: #4CAF50;
        }
        
        .timestamp {
            white-space: nowrap;
            font-family: 'Courier New', monospace;
        }
        
        .alert-name {
            font-weight: 500;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="table-container">
            <table id="alerts-table">
                <thead>
                    <tr>
                        <th>告警名称</th>
                        <th>事件图片</th>
                        <th>发生时间</th>
                    </tr>
                </thead>
                <tbody id="alerts-body">
                    <!-- Data will be populated here by JavaScript -->
                </tbody>
            </table>
        </div>
    </div>

    <!-- 全屏图片查看器 -->
    <div id="image-viewer" onclick="closeImageViewer()">
        <img id="fullscreen-image" src="" alt="Fullscreen Image">
    </div>

    <script>
        // 告警名称映射
        const alertNameMap = {
            "14": "跌倒告警",
            "16": "未带安全帽告警"
        };

        // 打开全屏图片查看器
        function openImageViewer(base64Data) {
            const viewer = document.getElementById('image-viewer');
            const img = document.getElementById('fullscreen-image');
            
            if (base64Data && base64Data.length > 50) {
                // 构造 Data URL
                let dataUrl = base64Data;
                if (!base64Data.startsWith('data:image')) {
                    // 假设是 jpeg, 也可以根据需要调整或从数据中判断
                    dataUrl = `data:image/jpeg;base64,${base64Data}`;
                }
                img.src = dataUrl;
                viewer.style.display = 'flex'; // 使用 flex 显示居中
                // 防止背景滚动
                document.body.style.overflow = 'hidden';
            } else {
                console.warn('Invalid or missing base64 image data');
            }
        }

        // 关闭全屏图片查看器
        function closeImageViewer() {
            const viewer = document.getElementById('image-viewer');
            viewer.style.display = 'none';
            // 恢复背景滚动
            document.body.style.overflow = 'hidden'; // 主页面依然无滚动条
        }

        function fetchAlerts() {
            fetch('/api/alerts')
                .then(response => response.json())
                .then(data => {
                    const tbody = document.getElementById('alerts-body');
                    tbody.innerHTML = ''; // Clear existing data

                    if (data.length === 0) {
                        tbody.innerHTML = '<tr><td colspan="3" class="no-alerts">暂无告警数据</td></tr>';
                        return;
                    }

                    data.forEach(alert => {
                        // Convert timestamp to readable format
                        const date = new Date(parseInt(alert.eventTime));
                        const formattedTime = isNaN(date.getTime()) ? 'Invalid Date' : 
                            date.toLocaleString('zh-CN', { 
                                year: 'numeric', month: '2-digit', day: '2-digit',
                                hour: '2-digit', minute: '2-digit', second: '2-digit'
                            }).replace(/\//g, '-');

                        // Determine alert name
                        const alertName = alertNameMap[alert.product_id] || `未知告警 (${alert.product_id})`;

                        const row = document.createElement('tr');
                        
                        // Handle image display and click event
                        let imageCellContent = '<span style="color:#888;">无图片</span>';
                        if (alert.eventPicture && alert.eventPicture.length > 50) {
                            // --- 修复点：不再截取 Base64 字符串 ---
                            // 使用完整的 base64 数据来显示图片
                            const fullBase64 = alert.eventPicture;
                            imageCellContent = `<img src="data:image/jpeg;base64,${fullBase64}" alt="Event Image" class="alert-image" onclick="event.stopPropagation(); openImageViewer('${fullBase64}');">`;
                        } else if (alert.eventPicture) {
                             imageCellContent = `<span style="color:#FF9800;">图片数据过短</span>`;
                        }

                        row.innerHTML = `
                            <td class="alert-name">${alertName}</td>
                            <td class="image-cell">${imageCellContent}</td>
                            <td class="timestamp">${formattedTime}</td>
                        `;
                        
                        tbody.appendChild(row);
                    });
                })
                .catch(error => {
                    console.error('Error fetching alerts:', error);
                    const tbody = document.getElementById('alerts-body');
                    tbody.innerHTML = '<tr><td colspan="3" class="no-alerts">加载数据时出错</td></tr>';
                });
        }

        // Fetch alerts immediately on load
        fetchAlerts();

        // Fetch alerts every 5 seconds
        setInterval(fetchAlerts, 5000);
    </script>
</body>
</html>
"""

@app.route('/', methods=['GET'])
def index():
    """Serve the main HTML page."""
    return render_template_string(HTML_TEMPLATE)

@app.route('/api/alerts', methods=['GET'])
def get_alerts():
    """API endpoint to get the current list of alerts."""
    return jsonify(alerts)

@app.route('/receive_alert', methods=['POST'])
def receive_alert():
    """
    Endpoint to receive alert data from the edge platform.
    Expects a JSON payload with the structure provided in the query.
    """
    global alerts
    try:
        json_data = request.get_json()

        if not json_data:
            return jsonify({"error": "No JSON data provided"}), 400

        data = json_data.get("data", {})
        product_id = data.get("product_id", "")
        event_picture_base64 = data.get("eventPicture", "")
        event_time = data.get("eventTime", "")

        new_alert = {
            "product_id": product_id,
            "eventPicture": event_picture_base64,
            "eventTime": event_time
        }

        alerts.insert(0, new_alert)
        alerts = alerts[:5]

        print(f"Received alert: Type {product_id}, Time: {event_time}")
        return jsonify({"status": "success", "message": "Alert received"}), 200

    except Exception as e:
        print(f"Error processing alert: {e}")
        return jsonify({"error": "Internal server error"}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)