{% extends "base.html" %}

{% block title %}Cameras - ESPILON{% endblock %}

{% block content %}
<div class="page-header">
    <div class="page-title">Cameras <span>Live Feed</span></div>
    <div class="status">
        <div class="status-dot"></div>
        <span id="camera-count">{{ image_files|length }}</span> camera(s)
    </div>
</div>

{% if image_files %}
<div class="grid grid-cameras" id="grid">
    {% for img in image_files %}
    <div class="card" data-camera-id="{{ img.replace('.jpg', '') }}">
        <div class="card-header">
            <span class="name">{{ img.replace('.jpg', '').replace('_', ':') }}</span>
            <div class="card-actions">
                <button class="btn-record" data-camera="{{ img.replace('.jpg', '') }}" title="Start Recording">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
                        <circle cx="12" cy="12" r="8"/>
                    </svg>
                </button>
                <span class="badge badge-live">LIVE</span>
            </div>
        </div>
        <div class="card-body card-body-image">
            <img src="/streams/{{ img }}?t=0"
                 data-src="/streams/{{ img }}"
                 data-default="/static/images/no-signal.png"
                 onerror="this.src=this.dataset.default">
        </div>
        <div class="record-indicator" style="display: none;">
            <span class="record-dot"></span>
            <span class="record-time">00:00</span>
        </div>
    </div>
    {% endfor %}
</div>
{% else %}
<div class="empty-cameras">
    <div class="no-signal-container">
        <img src="/static/images/no-signal.png" alt="No Signal" class="no-signal-img">
        <h2>No active cameras</h2>
        <p>Waiting for ESP32-CAM devices to send frames on UDP port 5000</p>
    </div>
</div>
{% endif %}
{% endblock %}

{% block scripts %}
<style>
    .card-actions {
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .btn-record {
        width: 28px;
        height: 28px;
        border-radius: 50%;
        border: none;
        background: var(--bg-elevated);
        color: var(--text-secondary);
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.2s ease;
    }

    .btn-record:hover {
        background: var(--status-error-bg);
        color: var(--status-error);
    }

    .btn-record.recording {
        background: var(--status-error);
        color: white;
        animation: pulse-record 1.5s infinite;
    }

    @keyframes pulse-record {
        0%, 100% { opacity: 1; }
        50% { opacity: 0.6; }
    }

    .record-indicator {
        padding: 8px 16px;
        background: var(--bg-elevated);
        border-top: 1px solid var(--border-color);
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 12px;
        color: var(--status-error);
    }

    .record-dot {
        width: 8px;
        height: 8px;
        background: var(--status-error);
        border-radius: 50%;
        animation: pulse-record 1s infinite;
    }

    .record-time {
        font-family: 'JetBrains Mono', monospace;
        font-weight: 600;
    }

    .empty-cameras {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 60vh;
    }

    .no-signal-container {
        text-align: center;
    }

    .no-signal-img {
        max-width: 300px;
        margin-bottom: 24px;
        opacity: 0.8;
        border-radius: 12px;
    }

    .no-signal-container h2 {
        font-size: 20px;
        color: var(--text-primary);
        margin-bottom: 8px;
    }

    .no-signal-container p {
        color: var(--text-muted);
        font-size: 14px;
    }

    .card-body-image img {
        min-height: 180px;
        object-fit: contain;
        background: var(--bg-tertiary);
    }
</style>

<script>
    // Recording state
    const recordingState = {};

    // Refresh camera images
    function refresh() {
        const t = Date.now();
        document.querySelectorAll('.card-body-image img').forEach(img => {
            // Only update if not showing default image
            if (!img.src.includes('no-signal')) {
                img.src = img.dataset.src + '?t=' + t;
            }
        });
    }

    // Check for new/removed cameras
    async function checkCameras() {
        try {
            const res = await fetch('/api/cameras');
            const data = await res.json();
            const current = document.querySelectorAll('.card').length;
            document.getElementById('camera-count').textContent = data.count || 0;

            // Update recording states
            if (data.cameras) {
                data.cameras.forEach(cam => {
                    updateRecordingUI(cam.id, cam.recording);
                });
            }

            if (data.count !== current) location.reload();
        } catch (e) {}
    }

    // Update recording UI
    function updateRecordingUI(cameraId, isRecording) {
        const card = document.querySelector(`[data-camera-id="${cameraId}"]`);
        if (!card) return;

        const btn = card.querySelector('.btn-record');
        const indicator = card.querySelector('.record-indicator');

        if (isRecording) {
            btn.classList.add('recording');
            btn.title = 'Stop Recording';
            indicator.style.display = 'flex';

            // Start timer if not already
            if (!recordingState[cameraId]) {
                recordingState[cameraId] = { startTime: Date.now() };
            }
        } else {
            btn.classList.remove('recording');
            btn.title = 'Start Recording';
            indicator.style.display = 'none';
            delete recordingState[cameraId];
        }
    }

    // Update recording timers
    function updateTimers() {
        for (const [cameraId, state] of Object.entries(recordingState)) {
            const card = document.querySelector(`[data-camera-id="${cameraId}"]`);
            if (!card) continue;

            const timeEl = card.querySelector('.record-time');
            if (timeEl) {
                const elapsed = Math.floor((Date.now() - state.startTime) / 1000);
                const mins = Math.floor(elapsed / 60).toString().padStart(2, '0');
                const secs = (elapsed % 60).toString().padStart(2, '0');
                timeEl.textContent = `${mins}:${secs}`;
            }
        }
    }

    // Toggle recording
    async function toggleRecording(cameraId) {
        const btn = document.querySelector(`[data-camera="${cameraId}"]`);
        const isRecording = btn.classList.contains('recording');

        try {
            const endpoint = isRecording ? 'stop' : 'start';
            const res = await fetch(`/api/recording/${endpoint}/${cameraId}`, {
                method: 'POST'
            });
            const data = await res.json();

            if (data.error) {
                console.error('Recording error:', data.error);
                return;
            }

            updateRecordingUI(cameraId, !isRecording);

            if (!isRecording) {
                recordingState[cameraId] = { startTime: Date.now() };
            }
        } catch (e) {
            console.error('Recording toggle failed:', e);
        }
    }

    // Event listeners
    document.querySelectorAll('.btn-record').forEach(btn => {
        btn.addEventListener('click', (e) => {
            e.preventDefault();
            const cameraId = btn.dataset.camera;
            toggleRecording(cameraId);
        });
    });

    // Intervals
    setInterval(refresh, 100);
    setInterval(checkCameras, 5000);
    setInterval(updateTimers, 1000);

    // Initial check
    checkCameras();
</script>
{% endblock %}
