<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mark</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            background-color: #f5f5f5;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 1px solid #eee;
        }

        .image-container {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
        }

        .canvas-wrapper {
            flex: 1;
            border: 1px solid #ddd;
            border-radius: 4px;
            overflow: hidden;
        }

        #canvas {
            border: none;
            display: block;
        }

        .controls {
            margin: 20px 0;
            padding: 15px;
            background-color: #f8f9fa;
            border-radius: 4px;
        }

        .label-buttons {
            display: flex;
            gap: 10px;
            margin: 15px 0;
            flex-wrap: wrap;
        }

        .label-btn {
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
            transition: all 0.2s;
        }

        .label-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
        }

        .label-btn.active {
            transform: translateY(-2px);
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        }

        .btn-positive {
            background-color: #28a745;
            color: white;
        }

        .btn-negative {
            background-color: #dc3545;
            color: white;
        }

        .btn-neutral {
            background-color: #6c757d;
            color: white;
        }

        .btn-unclear {
            background-color: #ffc107;
            color: black;
        }

        .btn-primary {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            margin-right: 10px;
        }

        .btn-primary:hover {
            background-color: #0056b3;
        }

        .btn-secondary {
            padding: 10px 20px;
            background-color: #6c757d;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            text-decoration: none;
            display: inline-block;
        }

        .btn-secondary:hover {
            background-color: #545b62;
        }

        .detection-list {
            margin-top: 20px;
            max-height: 300px;
            overflow-y: auto;
        }

        .detection-item {
            padding: 10px;
            border: 1px solid #ddd;
            margin-bottom: 10px;
            border-radius: 4px;
            background-color: #f8f9fa;
        }

        .detection-item.active {
            background-color: #e9f7ef;
            border-color: #28a745;
        }

        .info-panel {
            background-color: #e9f7ef;
            padding: 15px;
            border-radius: 4px;
            margin-bottom: 20px;
        }

        .instructions {
            background-color: #fff3cd;
            padding: 15px;
            border-radius: 4px;
            margin-bottom: 20px;
        }

        .status {
            padding: 10px;
            background-color: #d1ecf1;
            border-radius: 4px;
            margin: 10px 0;
        }
    </style>
</head>

<body>
    <div class="container">
        <!-- <div class="header">
            <h1>ReMark</h1>
            <a href="/list" class="btn-secondary">返回图片列表</a>
        </div> -->

        <!-- <div class="info-panel">
            <h3>图像信息</h3>
            <p><strong>图像 ID:</strong> <span id="image-id"></span></p>
            <p><strong>时间戳：</strong> <span id="image-timestamp"></span></p>
            <p><strong>备注：</strong> <span id="image-comment"></span></p>
        </div> -->

        <!-- <div class="instructions">
            <h3>操作说明</h3>
            <ul>
                <li>选择一个目标类别</li>
                <li>在图像上按住鼠标左键拖拽绘制矩形框</li>
                <li>点击已绘制的框可选中并编辑</li>
                <li>按 Delete 键删除选中的框</li>
                <li>完成标注后点击"保存标注结果"</li>
            </ul>
        </div> -->

        <div class="image-container">
            <div class="canvas-wrapper">
                <canvas id="canvas"></canvas>
            </div>
        </div>

        <div class="controls">
            <h3>目标类别</h3>
            <div class="label-buttons">
                <button class="label-btn btn-positive" data-id="1" data-label="caisson">弹药箱 (1)</button>
                <button class="label-btn btn-negative" data-id="2" data-label="soldier">士兵 (2)</button>
                <button class="label-btn btn-neutral" data-id="3" data-label="gun">枪支 (3)</button>
                <button class="label-btn btn-unclear" data-id="4" data-label="number">数字牌 (4)</button>
                <!-- 插入占位元素 -->
                <div style="flex: 1;"></div>
                <button class="btn-primary" id="save-btn">保存标注结果</button>
                <button class="btn-primary" id="clear-btn">清空所有标注</button>
            </div>

            <div class="status">
                <p>当前状态：<span id="status-text">请选择一个目标类别开始标注</span></p>
                <p>当前选中类别：<span id="selected-label">无</span></p>
            </div>
        </div>

        <div class="detection-list">
            <h3>已标注目标 (<span id="detection-count">0</span>)</h3>
            <div id="detections-container"></div>
        </div>
    </div>

    <script>
        // 从 URL 参数获取图像 ID
        const urlParams = new URLSearchParams(window.location.search);
        const imageId = urlParams.get('id');
        const side = urlParams.get('side') || 'left';

        // 全局变量
        let canvas = null;
        let currentImageData = null;
        let selectedLabel = null;
        let detections = []; // 存储所有检测框
        let isDrawing = false;
        let startX, startY;
        let rect = null;

        // 页面加载时初始化
        document.addEventListener('DOMContentLoaded', function () {
            if (!imageId) {
                alert('缺少图像 ID 参数');
                window.location.href = '/list';
                return;
            }

            window.currentSide = side;
            // document.querySelector('h1').textContent = `人工标注 (${side === 'left' ? '左侧' : '右侧'}图像)`;

            // 初始化 Fabric.js 画布
            canvas = new fabric.Canvas('canvas', {
                selection: false,
                preserveObjectStacking: true
            });

            // 设置画布事件
            setupCanvasEvents();

            // 加载图像数据
            loadImageData(imageId, side);

            // 绑定按钮事件
            document.getElementById('save-btn').addEventListener('click', saveManualAnnotations);
            document.getElementById('clear-btn').addEventListener('click', clearAllAnnotations);

            // 绑定标签按钮事件
            document.querySelectorAll('.label-btn').forEach(button => {
                button.addEventListener('click', function () {
                    // 移除其他按钮的激活状态
                    document.querySelectorAll('.label-btn').forEach(btn => {
                        btn.classList.remove('active');
                    });

                    // 添加当前按钮的激活状态
                    this.classList.add('active');

                    // 记录选中的标签
                    selectedLabel = {
                        id: parseInt(this.getAttribute('data-id')),
                        label: this.getAttribute('data-label')
                    };

                    // 更新显示
                    document.getElementById('selected-label').textContent =
                        `${selectedLabel.label} (${selectedLabel.id})`;
                    document.getElementById('status-text').textContent =
                        `已选择 ${selectedLabel.label}，现在可以在图像上绘制标注框`;
                });
            });

            // 键盘事件处理
            document.addEventListener('keydown', function (e) {
                if (e.key === 'Delete' || e.key === 'Backspace') {
                    const activeObject = canvas.getActiveObject();
                    if (activeObject && activeObject.detectionId !== undefined) {
                        // 删除检测框
                        const detectionId = activeObject.detectionId;
                        detections = detections.filter(d => d.id !== detectionId);
                        canvas.remove(activeObject);
                        updateDetectionsList();
                        document.getElementById('detection-count').textContent = detections.length;
                    }
                }
            });
        });

        // 设置画布事件
        function setupCanvasEvents() {
            canvas.on('mouse:down', function (options) {
                if (!selectedLabel) {
                    alert('请先选择一个目标类别');
                    return;
                }

                const pointer = canvas.getPointer(options.e);
                startX = pointer.x;
                startY = pointer.y;
                isDrawing = true;

                // 创建矩形对象
                rect = new fabric.Rect({
                    left: startX,
                    top: startY,
                    width: 0,
                    height: 0,
                    fill: 'rgba(0,0,0,0)',
                    stroke: getColorForLabel(selectedLabel.id),
                    strokeWidth: 2,
                    selectable: true,
                    hasControls: true,
                    hasBorders: true
                });

                canvas.add(rect);
            });

            canvas.on('mouse:move', function (options) {
                if (!isDrawing) return;

                const pointer = canvas.getPointer(options.e);
                const width = pointer.x - startX;
                const height = pointer.y - startY;

                rect.set({
                    width: width,
                    height: height
                });

                canvas.renderAll();
            });

            canvas.on('mouse:up', function () {
                if (!isDrawing) return;
                isDrawing = false;

                // 确保矩形有最小尺寸
                if (Math.abs(rect.width) < 5 || Math.abs(rect.height) < 5) {
                    canvas.remove(rect);
                    return;
                }

                // 标准化矩形（确保宽度和高度为正）
                if (rect.width < 0) {
                    rect.set({ left: rect.left + rect.width, width: Math.abs(rect.width) });
                }
                if (rect.height < 0) {
                    rect.set({ top: rect.top + rect.height, height: Math.abs(rect.height) });
                }

                // 添加标签文本
                const text = new fabric.Text(`${selectedLabel.label} (${selectedLabel.id})`, {
                    left: rect.left,
                    top: rect.top - 15,
                    fontSize: 14,
                    fill: getColorForLabel(selectedLabel.id),
                    selectable: false
                });

                canvas.add(text);

                // 为矩形添加唯一ID并关联文本
                const detectionId = Date.now(); // 简单的唯一ID生成
                rect.set({
                    detectionId: detectionId,
                    labelText: text
                });

                // 保存检测信息
                const detection = {
                    id: detectionId,
                    categoryId: selectedLabel.id,
                    label: selectedLabel.label,
                    bbox: [
                        Math.round(rect.left * 999 / canvas.width),
                        Math.round(rect.top * 999 / canvas.height),
                        Math.round((rect.left + rect.width) * 999 / canvas.width),
                        Math.round((rect.top + rect.height) * 999 / canvas.height)
                    ]
                };

                detections.push(detection);
                updateDetectionsList();
                document.getElementById('detection-count').textContent = detections.length;

                // 选中新创建的矩形
                canvas.setActiveObject(rect);
            });

            // 对象修改事件
            canvas.on('object:modified', function (options) {
                const modifiedObject = options.target;
                if (modifiedObject.detectionId !== undefined) {
                    // 更新对应的检测信息
                    const detection = detections.find(d => d.id === modifiedObject.detectionId);
                    if (detection) {
                        detection.bbox = [
                            Math.round(modifiedObject.left * 999 / canvas.width),
                            Math.round(modifiedObject.top * 999 / canvas.height),
                            Math.round((modifiedObject.left + modifiedObject.width) * 999 / canvas.width),
                            Math.round((modifiedObject.top + modifiedObject.height) * 999 / canvas.height)
                        ];
                        updateDetectionsList();
                    }

                    // 更新标签文本位置
                    if (modifiedObject.labelText) {
                        modifiedObject.labelText.set({
                            left: modifiedObject.left,
                            top: modifiedObject.top - 15
                        });
                        canvas.renderAll();
                    }
                }
            });
        }

        // 根据标签 ID 获取颜色
        function getColorForLabel(id) {
            const colorMap = {
                1: '#28a745', // 绿色 - 弹药箱
                2: '#dc3545', // 红色 - 士兵
                3: '#6c757d', // 灰色 - 枪支
                4: '#ffc107'  // 黄色 - 数字牌
            };
            return colorMap[id] || '#000000';
        }

        // 加载图像数据
        async function loadImageData(id, side) {
            try {
                const response = await fetch('/api/images');
                if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
                const images = await response.json();

                // 查找指定 ID 的图像
                const image = images.find(img => img.id == id);
                if (!image) {
                    throw new Error('未找到指定的图像');
                }

                currentImageData = image;

                // // 显示图像信息
                // document.getElementById('image-id').textContent = image.id;
                // document.getElementById('image-timestamp').textContent = new Date(image.timestamp * 1000).toISOString();
                // document.getElementById('image-comment').textContent = image.comment || '无';

                // 根据 side 参数决定加载哪一侧的图像
                const imagePath = side === 'left'
                    ? `/static/received/left/${image.left_filename}`
                    : `/static/received/right/${image.right_filename}`;

                const imageInfo = side === 'left'
                    ? `左摄像头图像：${image.left_filename}`
                    : `右摄像头图像：${image.right_filename}`;

                // // 更新图像信息显示
                // document.querySelector('.info-panel h3').textContent = imageInfo;

                // 加载图像到画布
                fabric.Image.fromURL(imagePath, function (img) {
                    // 设置画布尺寸
                    const maxWidth = 800;
                    const maxHeight = 600;
                    let width = img.width;
                    let height = img.height;

                    // 按比例缩放
                    if (width > maxWidth || height > maxHeight) {
                        const ratio = Math.min(maxWidth / width, maxHeight / height);
                        width = width * ratio;
                        height = height * ratio;
                    }

                    canvas.setDimensions({ width: width, height: height });
                    img.set({ selectable: false, evented: false });
                    img.scaleToWidth(width);
                    img.scaleToHeight(height);
                    canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));

                    // 如果已有机器标注结果，则加载显示
                    // loadMachineDetections(image, side);
                });

            } catch (error) {
                console.error('Error loading image data:', error);
                alert('加载图像数据失败：' + error.message);
            }
        }


        // 加载机器标注结果
        function loadMachineDetections(image, side) {
            // if (image.manual_detections && image.manual_detections !== "[]") {
            //     try {
            //         const manualDetections = JSON.parse(image.manual_detections);
            //         if (Array.isArray(manualDetections) && manualDetections.length > 0) {
            //             // 加载人工标注结果到画布
            //             loadDetectionsToCanvas(manualDetections);
            //             document.getElementById('status-text').textContent =
            //                 '已加载人工标注结果，可继续编辑';
            //             return;
            //         }
            //     } catch (e) {
            //         console.error('Error parsing manual detections:', e);
            //     }
            // }
        }

        // 更新检测列表显示
        function updateDetectionsList() {
            const container = document.getElementById('detections-container');
            container.innerHTML = '';

            if (detections.length === 0) {
                container.innerHTML = '<p>暂无标注目标</p>';
                return;
            }

            detections.forEach(detection => {
                const item = document.createElement('div');
                item.className = 'detection-item';
                item.innerHTML = `
                    <strong>${detection.label} (${detection.categoryId})</strong><br>
                    边界框：[${detection.bbox.join(', ')}]
                `;
                container.appendChild(item);
            });
        }

        // 清空所有标注
        function clearAllAnnotations() {
            if (confirm('确定要清空所有标注吗？')) {
                // 删除画布上的所有对象（除了背景图像）
                const objects = canvas.getObjects();
                objects.forEach(obj => {
                    if (obj !== canvas.backgroundImage) {
                        canvas.remove(obj);
                    }
                });

                // 清空检测数据
                detections = [];
                updateDetectionsList();
                document.getElementById('detection-count').textContent = '0';
            }
        }

        // 保存人工标注结果
        async function saveManualAnnotations() {
            if (!currentImageData) {
                alert('图像数据未加载完成');
                return;
            }

            // 构造与机器标注格式一致的 JSON 数据
            const annotationData = {
                detections: detections.map(d => ({
                    id: d.categoryId,
                    label: d.label,
                    bbox: d.bbox
                }))
            };

            try {
                // 发送请求更新标注结果，包含 side 参数
                const response = await fetch('/api/images/manual-detections', {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        id: currentImageData.id,
                        side: window.currentSide, // 添加 side 参数
                        detections: annotationData.detections
                    })
                });

                if (!response.ok) {
                    const errorData = await response.json().catch(() => ({ error: response.statusText }));
                    throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
                }

                const result = await response.json();
                alert('人工标注结果已保存');

                // 返回图片列表页面
                window.location.href = '/list';

            } catch (error) {
                console.error('Error saving manual annotations:', error);
                alert('保存失败：' + error.message);
            }
        }
    </script>
</body>

</html>