{% extends 'base.html' %}
{% load static %}

{% block title %}多模型智能检测 - 茄子在线检测系统{% endblock %}

{% block content %}
<div class="row justify-content-center">
    <div class="col-lg-12">
        <div class="text-center mb-5 fade-in-up">
            <h2 class="fw-bold" style="color: #6f42c1;">
                <i class="bi bi-grid-1x2-fill me-2"></i>多模型协同检测
            </h2>
            <p class="text-muted">选择多个 AI 模型，对比不同算法的检测效果</p>
        </div>

        <div class="card shadow-sm border-0 mb-5 fade-in-up" style="border-radius: 15px;">
            <div class="card-body p-4">
                <h5 class="card-title fw-bold text-secondary mb-3"><i class="bi bi-cpu me-2"></i>第一步：选择模型</h5>
                <div class="row justify-content-center">
                    <div class="col-md-8">
                        <div class="input-group">
                            <span class="input-group-text bg-light border-0"><i class="bi bi-list-check"></i></span>
                            <select id="modelSelect" class="form-select form-select-lg shadow-none border-light bg-light" multiple size="4">
                                </select>
                        </div>
                        <div class="d-flex align-items-center mt-2 text-muted small justify-content-center">
                            <i class="bi bi-info-circle me-1"></i>
                            <span>按住 <strong>Ctrl</strong> (Windows) 或 <strong>Command</strong> (Mac) 可多选</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="row g-4 mb-5">
            <div class="col-md-4 fade-in-up" style="animation-delay: 0.1s;">
                <div class="card h-100 shadow-hover border-0 function-card">
                    <div class="card-body text-center p-4">
                        <div class="icon-circle bg-primary-subtle text-primary mb-3"><i class="bi bi-image"></i></div>
                        <h4 class="fw-bold mb-3">图片检测</h4>
                        <input type="file" id="imageInput" accept="image/*" class="form-control mb-3" style="font-size: 0.9rem;">
                        <button onclick="uploadImages()" class="btn btn-primary w-100 rounded-pill"><i class="bi bi-upload me-2"></i>上传并检测</button>
                    </div>
                </div>
            </div>

            <div class="col-md-4 fade-in-up" style="animation-delay: 0.2s;">
                <div class="card h-100 shadow-hover border-0 function-card">
                    <div class="card-body text-center p-4">
                        <div class="icon-circle bg-success-subtle text-success mb-3"><i class="bi bi-camera-video"></i></div>
                        <h4 class="fw-bold mb-3">视频检测</h4>
                        <input type="file" id="videoInput" accept="video/*" class="form-control mb-3" style="font-size: 0.9rem;">
                        <button onclick="uploadVideo()" class="btn btn-success w-100 rounded-pill"><i class="bi bi-play-circle me-2"></i>上传并分析</button>
                    </div>
                </div>
            </div>

            <div class="col-md-4 fade-in-up" style="animation-delay: 0.3s;">
                <div class="card h-100 shadow-hover border-0 function-card">
                    <div class="card-body text-center p-4">
                        <div class="icon-circle bg-danger-subtle text-danger mb-3"><i class="bi bi-webcam"></i></div>
                        <h4 class="fw-bold mb-3">实时监控</h4>
                        <div class="mt-auto pt-4">
                            <button id="startCameraDetection" onclick="startCameraDetection()" class="btn btn-outline-danger w-100 rounded-pill mb-2">
                                <i class="bi bi-record-circle me-2"></i>开始摄像头检测
                            </button>
                            <button id="stopCameraDetection" onclick="stopCameraDetection()" style="display: none;" class="btn btn-danger w-100 rounded-pill beat-animation">
                                <i class="bi bi-stop-circle me-2"></i>停止摄像头检测
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="results-section">
            <div id="imageSectionTitle" class="d-none mb-3 border-start border-4 border-primary ps-3"><h4 class="fw-bold">图片检测结果</h4></div>
            <div class="row g-4 mb-5" id="imageResults"></div>

            <div id="videoSectionTitle" class="d-none mb-3 border-start border-4 border-success ps-3"><h4 class="fw-bold">视频检测结果</h4></div>
            <div class="row g-4 mb-5" id="videoResults"></div>

            <div id="cameraSectionTitle" class="d-none mb-3 border-start border-4 border-danger ps-3"><h4 class="fw-bold">摄像头实时画面</h4></div>
            <div class="row g-4 mb-5" id="cameraResults"></div>
        </div>
    </div>
</div>

<style>
    /* 动画与视觉效果 */
    .fade-in-up { animation: fadeInUp 0.6s ease-out forwards; opacity: 0; transform: translateY(20px); }
    @keyframes fadeInUp { to { opacity: 1; transform: translateY(0); } }
    .shadow-hover { transition: transform 0.3s ease, box-shadow 0.3s ease; }
    .shadow-hover:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1) !important; }
    .icon-circle { width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.8rem; margin: 0 auto; }
    .beat-animation { animation: beat 1.5s infinite; }
    @keyframes beat { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } }
    .result-card-img { width: 100%; border-radius: 8px; transition: transform 0.3s ease; min-height: 200px; object-fit: contain; background: #f8f9fa; }
</style>

<script>
    let cameraEventSource = null;

    // 加载模型列表
    function loadModels() {
        fetch('/multi_model_detection/get_models/')
            .then(response => response.json())
            .then(data => {
                const modelSelect = document.getElementById('modelSelect');
                data.models.forEach(model => {
                    const option = document.createElement('option');
                    option.value = model;
                    option.text = model;
                    modelSelect.appendChild(option);
                });
            })
            .catch(error => { console.error('Error:', error); alert('加载模型失败'); });
    }
    window.onload = loadModels;

    // 图片上传
    function uploadImages() {
        const models = Array.from(document.getElementById('modelSelect').selectedOptions).map(option => option.value);
        const file = document.getElementById('imageInput').files[0];
        if (!file || models.length === 0) { alert('请选择模型和图片'); return; }

        const formData = new FormData();
        models.forEach(model => formData.append('model', model));
        formData.append('image', file);

        document.getElementById('imageSectionTitle').classList.remove('d-none');
        const resultsDiv = document.getElementById('imageResults');
        resultsDiv.innerHTML = '<div class="col-12 text-center text-muted"><div class="spinner-border text-primary spinner-border-sm"></div> 检测中...</div>';

        fetch('/multi_model_detection/upload_pest/', { method: 'POST', body: formData })
        .then(response => response.json())
        .then(data => {
            resultsDiv.innerHTML = '';
            if (data.results) {
                data.results.forEach(result => {
                    const colDiv = document.createElement('div');
                    colDiv.className = 'col-md-4 fade-in-up';
                    const content = result.resultImage ?
                        `<img src="data:image/jpeg;base64,${result.resultImage}" class="result-card-img shadow-sm">` :
                        `<p class="text-danger">${result.error}</p>`;
                    colDiv.innerHTML = createCardHtml(result.model, content, 'primary');
                    resultsDiv.appendChild(colDiv);
                });
            }
        });
    }

    // 视频上传
    function uploadVideo() {
        const models = Array.from(document.getElementById('modelSelect').selectedOptions).map(option => option.value);
        const file = document.getElementById('videoInput').files[0];
        if (!file || models.length === 0) { alert('请选择模型和视频'); return; }

        const formData = new FormData();
        models.forEach(model => formData.append('model', model));
        formData.append('video', file);

        document.getElementById('videoSectionTitle').classList.remove('d-none');
        const resultsDiv = document.getElementById('videoResults');
        resultsDiv.innerHTML = '<div class="col-12 text-center text-muted"><div class="spinner-border text-success spinner-border-sm"></div> 处理中...</div>';

        fetch('/multi_model_detection/upload_video_pest/', { method: 'POST', body: formData })
        .then(response => response.json())
        .then(data => {
            resultsDiv.innerHTML = '';
            Object.keys(data).forEach(model => {
                const colDiv = document.createElement('div');
                colDiv.className = 'col-md-4 fade-in-up';
                // 动态创建 Video 确保兼容性
                const videoId = `vid-${Math.random().toString(36).substr(2, 9)}`;
                colDiv.innerHTML = createCardHtml(model, `<div id="${videoId}"></div>`, 'success');
                resultsDiv.appendChild(colDiv);

                const videoElement = document.createElement('video');
                videoElement.controls = true;
                videoElement.style.width = '100%';
                videoElement.className = 'shadow-sm rounded';
                videoElement.src = `data:video/mp4;base64,${data[model]}`;
                setTimeout(() => { document.getElementById(videoId).appendChild(videoElement); }, 0);
            });
        });
    }

    // ★★★ 摄像头检测 (核心修改：解决闪烁问题) ★★★
    function startCameraDetection() {
        const models = Array.from(document.getElementById('modelSelect').selectedOptions).map(option => option.value);
        if (models.length === 0) { alert('请至少选择一个模型'); return; }

        document.getElementById('startCameraDetection').style.display = 'none';
        document.getElementById('stopCameraDetection').style.display = 'inline-block';
        document.getElementById('cameraSectionTitle').classList.remove('d-none');

        // 第一次先清空，准备接收流
        const cameraResults = document.getElementById('cameraResults');
        if (!cameraResults.hasChildNodes()) {
             cameraResults.innerHTML = '<div class="col-12 text-center text-muted small" id="camera-loading">正在连接...</div>';
        }

        cameraEventSource = new EventSource(`/multi_model_detection/camera_detect_pest/?model=${encodeURIComponent(models.join(','))}`);

        cameraEventSource.onmessage = function (event) {
            // 移除 Loading 提示
            const loading = document.getElementById('camera-loading');
            if (loading) loading.remove();

            const data = JSON.parse(event.data);

            for (const model in data) {
                // 1. 生成唯一的 DOM ID，例如 "stream-img-YOLOv8"
                // 这里的 safeId 是为了防止模型名称里有特殊字符
                const safeId = model.replace(/[^a-zA-Z0-9-_]/g, '');
                const imgId = `stream-img-${safeId}`;

                // 2. 检查这个模型的图片元素是否已经存在于页面上
                const existingImg = document.getElementById(imgId);

                if (existingImg) {
                    // ★★★ 关键点：如果存在，只更新 src，不重绘 DOM，彻底解决闪烁！
                    if (typeof data[model] === 'string' && data[model].startsWith('data:image')) {
                        existingImg.src = data[model];
                    }
                } else {
                    // 3. 如果不存在（第一次收到帧），才创建卡片结构
                    const colDiv = document.createElement('div');
                    colDiv.className = 'col-md-4 fade-in-up';

                    let content = '';
                    if (typeof data[model] === 'string' && data[model].startsWith('data:image')) {
                        // 注意这里给 img 加上了 id
                        content = `<img id="${imgId}" src="${data[model]}" class="result-card-img shadow-sm" alt="Live Stream">`;
                    } else {
                        content = `<p class="text-danger small">${data[model] || '错误'}</p>`;
                    }

                    colDiv.innerHTML = createCardHtml(model, content, 'danger');
                    cameraResults.appendChild(colDiv);
                }
            }
        };

        cameraEventSource.onerror = function (error) {
            console.error('EventSource error:', error);
            if (cameraEventSource) cameraEventSource.close();
            alert('连接断开');
            stopCameraDetection();
        };
    }

    function stopCameraDetection() {
        if (cameraEventSource) {
            cameraEventSource.close();
            cameraEventSource = null;
        }
        // 停止时才清空界面
        document.getElementById('cameraResults').innerHTML = '';
        document.getElementById('startCameraDetection').style.display = 'inline-block';
        document.getElementById('stopCameraDetection').style.display = 'none';
    }

    // 辅助函数：统一生成卡片HTML
    function createCardHtml(title, content, colorTheme) {
        return `
            <div class="card h-100 border-0 shadow-sm">
                <div class="card-header bg-white border-bottom-0 pt-3 text-center">
                    <span class="badge bg-${colorTheme} bg-opacity-10 text-${colorTheme} px-3 py-2 rounded-pill">
                        ${title}
                    </span>
                </div>
                <div class="card-body text-center p-2">${content}</div>
            </div>
        `;
    }
</script>
{% endblock %}