"""HTML templates for the voice control web interface."""

HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Voice Control Debug</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            font-family: 'Segoe UI', system-ui, sans-serif;
            background: #1a1a2e;
            color: #eee;
            min-height: 100vh;
            padding: 20px;
        }
        .header {
            text-align: center;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 1px solid #333;
        }
        .header h1 { color: #00d4ff; font-size: 1.5em; }
        .header .status {
            margin-top: 8px;
            font-size: 0.9em;
        }
        .status-dot {
            display: inline-block;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            margin-right: 6px;
        }
        .status-dot.ok { background: #00ff88; }
        .status-dot.warn { background: #ffaa00; }
        .status-dot.error { background: #ff4444; }

        .grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
            gap: 15px;
            max-width: 1400px;
            margin: 0 auto;
        }
        .card {
            background: #16213e;
            border-radius: 8px;
            padding: 15px;
            border: 1px solid #0f3460;
        }
        .card h2 {
            color: #00d4ff;
            font-size: 1em;
            margin-bottom: 12px;
            padding-bottom: 8px;
            border-bottom: 1px solid #0f3460;
        }

        /* Command Input */
        .command-form {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
        }
        .command-form input {
            flex: 1;
            padding: 10px 12px;
            border: 1px solid #0f3460;
            border-radius: 6px;
            background: #1a1a2e;
            color: #fff;
            font-size: 14px;
        }
        .command-form input:focus {
            outline: none;
            border-color: #00d4ff;
        }
        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.2s;
        }
        .btn-primary {
            background: #00d4ff;
            color: #000;
        }
        .btn-primary:hover { background: #00b8e0; }
        .btn-primary:disabled { background: #555; color: #888; cursor: not-allowed; }
        .btn-secondary {
            background: #333;
            color: #fff;
        }
        .btn-secondary:hover { background: #444; }
        .btn-danger {
            background: #ff4444;
            color: #fff;
        }
        .btn-danger:hover { background: #cc3333; }
        .btn-success {
            background: #00ff88;
            color: #000;
        }
        .btn-success:hover { background: #00cc6a; }

        /* Quick Commands */
        .quick-commands {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
        }
        .quick-btn {
            padding: 8px 14px;
            background: #0f3460;
            border: 1px solid #1a4a7a;
            border-radius: 20px;
            color: #00d4ff;
            cursor: pointer;
            font-size: 13px;
            transition: all 0.2s;
        }
        .quick-btn:hover {
            background: #1a4a7a;
            border-color: #00d4ff;
        }

        /* Status Grid */
        .status-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
        }
        .status-item {
            background: #1a1a2e;
            padding: 10px;
            border-radius: 6px;
        }
        .status-item .label {
            font-size: 11px;
            color: #888;
            text-transform: uppercase;
            margin-bottom: 4px;
        }
        .status-item .value {
            font-size: 14px;
            font-weight: 500;
        }
        .status-item .value.ok { color: #00ff88; }
        .status-item .value.warn { color: #ffaa00; }
        .status-item .value.error { color: #ff4444; }

        /* Pose Display */
        .pose-grid {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 8px;
        }
        .pose-item {
            background: #1a1a2e;
            padding: 10px;
            border-radius: 6px;
            text-align: center;
        }
        .pose-item .label {
            font-size: 11px;
            color: #888;
            margin-bottom: 4px;
        }
        .pose-item .value {
            font-size: 16px;
            font-weight: 600;
            color: #00d4ff;
            font-family: monospace;
        }

        /* Objects List */
        .objects-list {
            max-height: 300px;
            overflow-y: auto;
        }
        .object-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8px 10px;
            background: #1a1a2e;
            border-radius: 6px;
            margin-bottom: 6px;
            font-size: 13px;
        }
        .object-item .type { color: #00d4ff; font-weight: 500; }
        .object-item .color-badge {
            padding: 2px 8px;
            border-radius: 10px;
            font-size: 11px;
        }
        .color-badge.red { background: #ff4444; color: #fff; }
        .color-badge.blue { background: #4488ff; color: #fff; }
        .color-badge.yellow { background: #ffcc00; color: #000; }
        .color-badge.white { background: #fff; color: #000; }
        .object-item .pos {
            font-family: monospace;
            font-size: 11px;
            color: #888;
        }
        .object-item.held {
            border: 2px solid #00ff88;
            background: #1a3a2e;
        }
        .object-item.held::before {
            content: '\\1F91A';
            margin-right: 6px;
        }

        /* Scene State */
        .scene-state {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-bottom: 12px;
        }
        .held-object {
            grid-column: span 2;
            background: #1a3a2e;
            border: 1px solid #00ff88;
            padding: 12px;
            border-radius: 6px;
        }
        .held-object.empty {
            background: #1a1a2e;
            border-color: #333;
        }
        .held-object .label {
            font-size: 11px;
            color: #00ff88;
            text-transform: uppercase;
            margin-bottom: 6px;
        }
        .held-object.empty .label {
            color: #666;
        }
        .held-object .info {
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
        }
        .held-object .field {
            display: flex;
            flex-direction: column;
        }
        .held-object .field .key {
            font-size: 10px;
            color: #888;
        }
        .held-object .field .val {
            font-size: 14px;
            color: #fff;
            font-weight: 500;
        }

        /* Queue Display */
        .queue-list {
            max-height: 150px;
            overflow-y: auto;
        }
        .queue-item {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 8px 10px;
            background: #1a1a2e;
            border-radius: 6px;
            margin-bottom: 6px;
            font-size: 13px;
        }
        .queue-item .index {
            background: #0f3460;
            color: #00d4ff;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 11px;
        }
        .queue-item .action { color: #00ff88; font-weight: 500; }
        .queue-item.pending { border-left: 3px solid #ffaa00; }

        /* Log Display */
        .log {
            max-height: 250px;
            overflow-y: auto;
            font-family: monospace;
            font-size: 12px;
        }
        .log-entry {
            padding: 6px 10px;
            border-bottom: 1px solid #0f3460;
        }
        .log-entry:last-child { border-bottom: none; }
        .log-entry .time {
            color: #666;
            margin-right: 10px;
        }
        .log-entry.error { color: #ff4444; }
        .log-entry.success { color: #00ff88; }
        .log-entry.info { color: #00d4ff; }

        /* Parse Result */
        .parse-result {
            background: #1a1a2e;
            padding: 12px;
            border-radius: 6px;
            font-family: monospace;
            font-size: 13px;
        }
        .parse-result .field {
            display: flex;
            justify-content: space-between;
            padding: 4px 0;
            border-bottom: 1px solid #0f3460;
        }
        .parse-result .field:last-child { border-bottom: none; }
        .parse-result .key { color: #888; }
        .parse-result .val { color: #00d4ff; }

        /* Empty State */
        .empty {
            text-align: center;
            color: #666;
            padding: 20px;
            font-style: italic;
        }

        /* Camera View */
        .camera-container {
            position: relative;
            background: #000;
            border-radius: 6px;
            overflow: hidden;
            min-height: 240px;
        }
        .camera-container img {
            width: 100%;
            height: auto;
            display: block;
        }
        .camera-overlay {
            position: absolute;
            top: 10px;
            right: 10px;
            background: rgba(0,0,0,0.6);
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 11px;
        }
        .camera-overlay.ok { color: #00ff88; }
        .camera-overlay.stale { color: #ffaa00; }
        .camera-overlay.error { color: #ff4444; }
        .no-image {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 240px;
            color: #666;
            font-style: italic;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>Voice Control Debug Interface</h1>
        <div class="status">
            <span class="status-dot" id="status-dot"></span>
            <span id="status-text">Connecting...</span>
        </div>
    </div>

    <div class="grid">
        <!-- Camera View -->
        <div class="card" style="grid-column: span 2;">
            <h2>Camera View <span id="camera-status" style="font-weight:normal;font-size:11px;color:#888;"></span></h2>
            <div class="camera-container" id="camera-container">
                <div class="no-image" id="no-image">No camera image available</div>
                <img id="camera-img" style="display:none;" alt="Camera feed">
                <div class="camera-overlay" id="camera-overlay"></div>
            </div>
        </div>

        <!-- Command Input -->
        <div class="card">
            <h2>Send Command</h2>
            <form class="command-form" id="command-form">
                <input type="text" id="command-input" placeholder="Enter voice command (e.g., 'sube', 'agarra el cubo rojo')" autocomplete="off">
                <button type="submit" class="btn btn-primary" id="btn-send">Send</button>
            </form>
            <div class="quick-commands">
                <button class="quick-btn" onclick="sendQuick('sube')">Sube</button>
                <button class="quick-btn" onclick="sendQuick('baja')">Baja</button>
                <button class="quick-btn" onclick="sendQuick('agarra el cubo rojo')">Cubo Rojo</button>
                <button class="quick-btn" onclick="sendQuick('agarra el cubo azul')">Cubo Azul</button>
                <button class="quick-btn" onclick="sendQuick('suelta')">Soltar</button>
                <button class="quick-btn" onclick="sendQuick('reinicia')">Reiniciar</button>
            </div>
        </div>

        <!-- Status -->
        <div class="card">
            <h2>System Status</h2>
            <div class="status-grid">
                <div class="status-item">
                    <div class="label">Pose Available</div>
                    <div class="value" id="st-pose">--</div>
                </div>
                <div class="status-item">
                    <div class="label">Pose Age</div>
                    <div class="value" id="st-pose-age">--</div>
                </div>
                <div class="status-item">
                    <div class="label">Objects Detected</div>
                    <div class="value" id="st-objects">--</div>
                </div>
                <div class="status-item">
                    <div class="label">Static Objects</div>
                    <div class="value" id="st-static">--</div>
                </div>
                <div class="status-item">
                    <div class="label">Queue Size</div>
                    <div class="value" id="st-queue">--</div>
                </div>
                <div class="status-item">
                    <div class="label">Pending Command</div>
                    <div class="value" id="st-pending">--</div>
                </div>
            </div>
        </div>

        <!-- TCP Pose -->
        <div class="card">
            <h2>TCP Pose</h2>
            <div class="pose-grid">
                <div class="pose-item">
                    <div class="label">X (mm)</div>
                    <div class="value" id="pose-x">--</div>
                </div>
                <div class="pose-item">
                    <div class="label">Y (mm)</div>
                    <div class="value" id="pose-y">--</div>
                </div>
                <div class="pose-item">
                    <div class="label">Z (mm)</div>
                    <div class="value" id="pose-z">--</div>
                </div>
                <div class="pose-item">
                    <div class="label">Roll</div>
                    <div class="value" id="pose-roll">--</div>
                </div>
                <div class="pose-item">
                    <div class="label">Pitch</div>
                    <div class="value" id="pose-pitch">--</div>
                </div>
                <div class="pose-item">
                    <div class="label">Yaw</div>
                    <div class="value" id="pose-yaw">--</div>
                </div>
            </div>
        </div>

        <!-- Last Parse Result -->
        <div class="card">
            <h2>Last Parse Result</h2>
            <div class="parse-result" id="parse-result">
                <div class="empty">No command parsed yet</div>
            </div>
            <div style="margin-top: 10px; font-size: 12px; color: #888;">
                <span>Last input: </span><span id="last-input">--</span>
            </div>
        </div>

        <!-- Scene State -->
        <div class="card">
            <h2>Scene State</h2>
            <div class="scene-state">
                <div class="status-item">
                    <div class="label">Update Mode</div>
                    <div class="value" id="scene-mode">--</div>
                </div>
                <div class="status-item">
                    <div class="label">Captured</div>
                    <div class="value" id="scene-captured">--</div>
                </div>
            </div>
            <div class="held-object empty" id="held-object-card">
                <div class="label">Held Object</div>
                <div class="info" id="held-object-info">
                    <span style="color:#666;font-style:italic;">Not holding any object</span>
                </div>
            </div>
        </div>

        <!-- Detected Objects -->
        <div class="card">
            <h2>Detected Objects</h2>
            <div class="objects-list" id="objects-list">
                <div class="empty">No objects detected</div>
            </div>
        </div>

        <!-- Command Queue -->
        <div class="card">
            <h2>Command Queue</h2>
            <div class="queue-list" id="queue-list">
                <div class="empty">Queue is empty</div>
            </div>
            <div style="margin-top: 10px;">
                <button class="btn btn-danger btn-sm" onclick="clearQueue()">Clear Queue</button>
            </div>
        </div>

        <!-- Log -->
        <div class="card" style="grid-column: span 2;">
            <h2>Activity Log</h2>
            <div class="log" id="log"></div>
        </div>
    </div>

    <script>
        const $ = id => document.getElementById(id);

        async function fetchJson(url, opts = {}) {
            try {
                const res = await fetch(url, opts);
                return await res.json();
            } catch (e) {
                return { error: e.message };
            }
        }

        function log(msg, type = 'info') {
            const logEl = $('log');
            const time = new Date().toLocaleTimeString();
            const entry = document.createElement('div');
            entry.className = 'log-entry ' + type;
            entry.innerHTML = '<span class="time">' + time + '</span>' + msg;
            logEl.insertBefore(entry, logEl.firstChild);
            if (logEl.children.length > 100) logEl.removeChild(logEl.lastChild);
        }

        async function updateStatus() {
            const data = await fetchJson('/api/status');
            if (data.error) {
                $('status-dot').className = 'status-dot error';
                $('status-text').textContent = 'Error: ' + data.error;
                return;
            }

            $('status-dot').className = 'status-dot ok';
            $('status-text').textContent = 'Connected';

            $('st-pose').textContent = data.has_pose ? 'Yes' : 'No';
            $('st-pose').className = 'value ' + (data.has_pose ? 'ok' : 'warn');

            $('st-pose-age').textContent = data.pose_age_ms !== null ? data.pose_age_ms + 'ms' : '--';
            $('st-pose-age').className = 'value ' + (data.pose_age_ms < 1000 ? 'ok' : 'warn');

            $('st-objects').textContent = data.object_count;
            $('st-static').textContent = data.static_object_count;
            $('st-queue').textContent = data.queue_size;
            $('st-queue').className = 'value ' + (data.queue_size > 0 ? 'warn' : 'ok');

            $('st-pending').textContent = data.has_pending_command ? 'Yes' : 'No';
            $('st-pending').className = 'value ' + (data.has_pending_command ? 'warn' : 'ok');

            // Update pose
            if (data.pose) {
                $('pose-x').textContent = data.pose[0].toFixed(1);
                $('pose-y').textContent = data.pose[1].toFixed(1);
                $('pose-z').textContent = data.pose[2].toFixed(1);
                $('pose-roll').textContent = data.pose[3].toFixed(1);
                $('pose-pitch').textContent = data.pose[4].toFixed(1);
                $('pose-yaw').textContent = data.pose[5].toFixed(1);
            }

            // Update last input
            $('last-input').textContent = data.last_voice_input || '--';

            // Update parse result
            if (data.last_parse_result) {
                let html = '';
                for (const [k, v] of Object.entries(data.last_parse_result)) {
                    html += '<div class="field"><span class="key">' + k + '</span><span class="val">' + v + '</span></div>';
                }
                $('parse-result').innerHTML = html;
            }
        }

        let currentHeldId = null;

        async function updateScene() {
            const data = await fetchJson('/api/scene');
            if (data.error) return;

            // Update scene mode
            $('scene-mode').textContent = data.update_mode || '--';
            $('scene-mode').className = 'value ' + (data.update_mode === 'static' ? 'warn' : 'ok');

            // Update captured status
            $('scene-captured').textContent = data.is_captured ? 'Yes' : 'No';
            $('scene-captured').className = 'value ' + (data.is_captured ? 'ok' : 'warn');

            // Update held object
            currentHeldId = data.held_object_id;
            const heldCard = $('held-object-card');
            const heldInfo = $('held-object-info');

            if (data.held_object) {
                const obj = data.held_object;
                heldCard.className = 'held-object';
                const pos = obj.position_mm ? obj.position_mm.map(v => v.toFixed(0)).join(', ') : '--';
                heldInfo.innerHTML =
                    '<div class="field"><span class="key">ID</span><span class="val">' + obj.id + '</span></div>' +
                    '<div class="field"><span class="key">Type</span><span class="val">' + (obj.object_type || '?') + '</span></div>' +
                    '<div class="field"><span class="key">Color</span><span class="val">' + (obj.color || '?') + '</span></div>' +
                    '<div class="field"><span class="key">Size</span><span class="val">' + (obj.size || 'normal') + '</span></div>' +
                    '<div class="field"><span class="key">Height</span><span class="val">' + (obj.height_mm || 0).toFixed(1) + 'mm</span></div>' +
                    '<div class="field"><span class="key">Position</span><span class="val">[' + pos + ']</span></div>';
            } else if (data.held_object_id) {
                heldCard.className = 'held-object';
                heldInfo.innerHTML = '<span style="color:#ffaa00;">Holding ID: ' + data.held_object_id + ' (not in scene)</span>';
            } else {
                heldCard.className = 'held-object empty';
                heldInfo.innerHTML = '<span style="color:#666;font-style:italic;">Not holding any object</span>';
            }
        }

        async function updateObjects() {
            const data = await fetchJson('/api/scene');
            if (data.error) return;

            const list = $('objects-list');
            const detected = data.detected || [];
            const staticObjs = data.static || [];
            const heldId = data.held_object_id;

            if (detected.length === 0 && staticObjs.length === 0) {
                list.innerHTML = '<div class="empty">No objects detected</div>';
                return;
            }

            let html = '';

            // Detected objects
            if (detected.length > 0) {
                html += '<div style="font-size:11px;color:#00d4ff;margin-bottom:6px;">Detected (' + detected.length + ')</div>';
                html += detected.map(obj => {
                    const pos = obj.position_mm ? obj.position_mm.map(v => v.toFixed(0)).join(', ') : '--';
                    const colorClass = obj.color || 'white';
                    const conf = obj.confidence ? (obj.confidence * 100).toFixed(0) + '%' : '';
                    const size = obj.size || '';
                    const isHeld = obj.id === heldId;
                    const stackInfo = obj.on_top_of ? ' on:' + obj.on_top_of : '';
                    return '<div class="object-item' + (isHeld ? ' held' : '') + '">' +
                        '<span class="type">' + (obj.object_type || '?') + '</span>' +
                        '<span class="color-badge ' + colorClass + '">' + (obj.color || '?') + '</span>' +
                        '<span style="color:#888;font-size:10px;">' + size + '</span>' +
                        '<span style="color:#00ff88;font-size:10px;">' + conf + '</span>' +
                        '<span class="pos">[' + pos + ']' + stackInfo + '</span>' +
                        '</div>';
                }).join('');
            }

            // Static objects
            if (staticObjs.length > 0) {
                html += '<div style="font-size:11px;color:#888;margin:8px 0 6px 0;">Static (' + staticObjs.length + ')</div>';
                html += staticObjs.map(obj => {
                    const pos = obj.position_mm ? obj.position_mm.map(v => v.toFixed(0)).join(', ') : '--';
                    const colorClass = obj.color || 'white';
                    const isHeld = obj.id === heldId;
                    return '<div class="object-item' + (isHeld ? ' held' : '') + '" style="opacity:0.7;">' +
                        '<span class="type">' + (obj.object_type || '?') + '</span>' +
                        '<span class="color-badge ' + colorClass + '">' + (obj.color || '?') + '</span>' +
                        '<span class="pos">[' + pos + ']</span>' +
                        '</div>';
                }).join('');
            }

            list.innerHTML = html;
        }

        async function updateQueue() {
            const data = await fetchJson('/api/queue');
            if (data.error) return;

            const list = $('queue-list');
            if (!data.length) {
                list.innerHTML = '<div class="empty">Queue is empty</div>';
                return;
            }

            list.innerHTML = data.map((item, i) => {
                const payload = JSON.stringify(item.payload || {});
                return '<div class="queue-item">' +
                    '<span class="index">' + (i + 1) + '</span>' +
                    '<span class="action">' + item.action + '</span>' +
                    '<span style="color:#888;font-size:11px">' + payload + '</span>' +
                    '</div>';
            }).join('');
        }

        async function sendCommand(text) {
            if (!text.trim()) return;

            $('btn-send').disabled = true;
            log('Sending: "' + text + '"', 'info');

            const res = await fetchJson('/api/command', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ text: text })
            });

            $('btn-send').disabled = false;

            if (res.ok) {
                log('Response: ' + res.text, 'success');
            } else {
                log('Error: ' + (res.text || res.detail || 'Unknown error'), 'error');
            }

            $('command-input').value = '';
            updateStatus();
            updateQueue();
        }

        function sendQuick(text) {
            $('command-input').value = text;
            sendCommand(text);
        }

        async function clearQueue() {
            log('Clearing queue...', 'info');
            const res = await fetchJson('/api/queue/clear', { method: 'POST' });
            if (res.ok) {
                log('Queue cleared', 'success');
            } else {
                log('Failed to clear queue', 'error');
            }
            updateQueue();
        }

        // Form submit
        $('command-form').addEventListener('submit', e => {
            e.preventDefault();
            sendCommand($('command-input').value);
        });

        // Camera update
        let cameraErrorCount = 0;
        async function updateCamera() {
            const info = await fetchJson('/api/image/info');
            const overlay = $('camera-overlay');
            const img = $('camera-img');
            const noImage = $('no-image');
            const status = $('camera-status');

            if (info.error || !info.has_image) {
                cameraErrorCount++;
                if (cameraErrorCount > 3) {
                    img.style.display = 'none';
                    noImage.style.display = 'flex';
                    overlay.textContent = '';
                    status.textContent = '(no feed)';
                }
                return;
            }

            cameraErrorCount = 0;
            noImage.style.display = 'none';
            img.style.display = 'block';

            // Update image with cache-busting
            const newSrc = '/api/image?t=' + Date.now();
            if (img.src !== newSrc) {
                img.src = newSrc;
            }

            // Update overlay
            const ageMs = info.age_ms || 0;
            if (ageMs < 500) {
                overlay.textContent = 'LIVE';
                overlay.className = 'camera-overlay ok';
            } else if (ageMs < 2000) {
                overlay.textContent = ageMs + 'ms';
                overlay.className = 'camera-overlay stale';
            } else {
                overlay.textContent = 'STALE ' + (ageMs/1000).toFixed(1) + 's';
                overlay.className = 'camera-overlay error';
            }
            status.textContent = '';
        }

        // Auto-refresh
        setInterval(updateStatus, 500);
        setInterval(updateScene, 500);
        setInterval(updateObjects, 1000);
        setInterval(updateQueue, 500);
        setInterval(updateCamera, 100);

        // Initial load
        updateStatus();
        updateScene();
        updateObjects();
        updateQueue();
        updateCamera();
        log('Interface loaded', 'info');
    </script>
</body>
</html>
"""
