{% extends "base.html" %}

{% block title %}Media - Art-DAG L1{% endblock %}

{% block content %}
<div class="max-w-6xl mx-auto">
    <div class="flex items-center justify-between mb-6">
        <h1 class="text-3xl font-bold">Media</h1>
        <div class="flex items-center space-x-4">
            <button onclick="document.getElementById('upload-modal').classList.remove('hidden')"
                    class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded font-medium">
                Upload Media
            </button>
            <select id="type-filter" onchange="filterMedia()"
                    class="bg-gray-800 border border-gray-600 rounded px-3 py-2 text-white">
                <option value="">All Types</option>
                <option value="image">Images</option>
                <option value="video">Videos</option>
                <option value="audio">Audio</option>
            </select>
        </div>
    </div>

    <!-- Upload Modal -->
    <div id="upload-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
        <div class="bg-gray-800 rounded-lg p-6 w-full max-w-md border border-gray-700">
            <div class="flex justify-between items-center mb-4">
                <h2 class="text-xl font-semibold">Upload Media</h2>
                <button onclick="document.getElementById('upload-modal').classList.add('hidden')"
                        class="text-gray-400 hover:text-white">
                    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                    </svg>
                </button>
            </div>

            <form id="upload-form" enctype="multipart/form-data" class="space-y-4">
                <div>
                    <label class="block text-gray-400 text-sm mb-1">Files</label>
                    <input type="file" name="files" id="upload-file" required multiple
                           accept="image/*,video/*,audio/*"
                           class="w-full bg-gray-900 border border-gray-600 rounded px-3 py-2 text-white file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:bg-blue-600 file:text-white hover:file:bg-blue-700">
                    <p class="text-gray-500 text-xs mt-1">Select one or more files to upload</p>
                </div>

                <div id="single-name-field">
                    <label class="block text-gray-400 text-sm mb-1">Name (optional, for single file)</label>
                    <input type="text" name="display_name" id="upload-name" placeholder="e.g., my-background-video"
                           class="w-full bg-gray-900 border border-gray-600 rounded px-3 py-2 text-white">
                    <p class="text-gray-500 text-xs mt-1">A friendly name to reference this media in recipes</p>
                </div>

                <div id="upload-progress" class="hidden">
                    <div class="bg-gray-700 rounded-full h-2">
                        <div id="progress-bar" class="bg-blue-600 h-2 rounded-full transition-all" style="width: 0%"></div>
                    </div>
                    <p id="progress-text" class="text-gray-400 text-sm mt-1">Uploading...</p>
                </div>

                <div id="upload-result" class="hidden max-h-48 overflow-y-auto"></div>

                <div class="flex justify-end space-x-3">
                    <button type="button" onclick="document.getElementById('upload-modal').classList.add('hidden')"
                            class="px-4 py-2 rounded border border-gray-600 hover:bg-gray-700">
                        Cancel
                    </button>
                    <button type="submit" id="upload-btn"
                            class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded font-medium">
                        Upload
                    </button>
                </div>
            </form>
        </div>
    </div>

    {% if items %}
    <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4" id="media-grid">
        {% for item in items %}
        {# Determine media category from type or filename #}
        {% set is_image = item.type in ('image', 'image/jpeg', 'image/png', 'image/gif', 'image/webp') or (item.filename and item.filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.webp'))) %}
        {% set is_video = item.type in ('video', 'video/mp4', 'video/webm', 'video/x-matroska') or (item.filename and item.filename.lower().endswith(('.mp4', '.mkv', '.webm', '.mov'))) %}
        {% set is_audio = item.type in ('audio', 'audio/mpeg', 'audio/wav', 'audio/flac') or (item.filename and item.filename.lower().endswith(('.mp3', '.wav', '.flac', '.ogg'))) %}

        <a href="/cache/{{ item.cid }}"
           class="media-item bg-gray-800 rounded-lg overflow-hidden hover:ring-2 hover:ring-blue-500 transition-all"
           data-type="{% if is_image %}image{% elif is_video %}video{% elif is_audio %}audio{% else %}other{% endif %}">

            {% if is_image %}
            <img src="/cache/{{ item.cid }}/raw"
                 alt=""
                 loading="lazy"
                 class="w-full h-40 object-cover">

            {% elif is_video %}
            <div class="relative">
                <video src="/cache/{{ item.cid }}/raw"
                       class="w-full h-40 object-cover"
                       muted
                       onmouseover="this.play()"
                       onmouseout="this.pause(); this.currentTime=0;">
                </video>
                <div class="absolute inset-0 flex items-center justify-center pointer-events-none">
                    <div class="bg-black bg-opacity-50 rounded-full p-2">
                        <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
                            <path d="M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z"/>
                        </svg>
                    </div>
                </div>
            </div>

            {% elif is_audio %}
            <div class="w-full h-40 bg-gray-900 flex flex-col items-center justify-center">
                <svg class="w-12 h-12 text-gray-600 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
                          d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"/>
                </svg>
                <span class="text-gray-500 text-sm">Audio</span>
            </div>

            {% else %}
            <div class="w-full h-40 bg-gray-900 flex items-center justify-center">
                <span class="text-gray-600 text-sm">{{ item.type or 'Media' }}</span>
            </div>
            {% endif %}

            <div class="p-3">
                {% if item.friendly_name %}
                <div class="text-xs text-blue-400 font-medium truncate">{{ item.friendly_name }}</div>
                {% else %}
                <div class="font-mono text-xs text-gray-500 truncate">{{ item.cid[:16] }}...</div>
                {% endif %}
                {% if item.filename %}
                <div class="text-xs text-gray-600 truncate">{{ item.filename }}</div>
                {% endif %}
            </div>
        </a>
        {% endfor %}
    </div>

    {% if has_more %}
    <div hx-get="/media?offset={{ offset + limit }}"
         hx-trigger="revealed"
         hx-swap="beforeend"
         hx-target="#media-grid"
         hx-select=".media-item"
         class="h-20 flex items-center justify-center text-gray-500 mt-4">
        Loading more...
    </div>
    {% endif %}

    {% else %}
    <div class="bg-gray-800 border border-gray-700 rounded-lg p-12 text-center">
        <svg class="w-16 h-16 mx-auto mb-4 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
                  d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
        </svg>
        <p class="text-gray-500 mb-4">No media files yet</p>
        <p class="text-gray-600 text-sm">Run a recipe to generate media artifacts.</p>
    </div>
    {% endif %}
</div>

<script>
function filterMedia() {
    const filter = document.getElementById('type-filter').value;
    document.querySelectorAll('.media-item').forEach(item => {
        if (!filter || item.dataset.type === filter) {
            item.classList.remove('hidden');
        } else {
            item.classList.add('hidden');
        }
    });
}

// Show/hide name field based on file count
document.getElementById('upload-file').addEventListener('change', function(e) {
    const nameField = document.getElementById('single-name-field');
    if (e.target.files.length > 1) {
        nameField.style.display = 'none';
    } else {
        nameField.style.display = 'block';
    }
});

// Handle upload form
document.getElementById('upload-form').addEventListener('submit', async function(e) {
    e.preventDefault();

    const form = e.target;
    const fileInput = document.getElementById('upload-file');
    const files = fileInput.files;
    const displayName = document.getElementById('upload-name').value;
    const progressDiv = document.getElementById('upload-progress');
    const progressBar = document.getElementById('progress-bar');
    const progressText = document.getElementById('progress-text');
    const resultDiv = document.getElementById('upload-result');
    const uploadBtn = document.getElementById('upload-btn');

    // Show progress
    progressDiv.classList.remove('hidden');
    resultDiv.classList.add('hidden');
    uploadBtn.disabled = true;

    const results = [];
    const errors = [];

    const CHUNK_SIZE = 1024 * 1024; // 1MB chunks

    for (let i = 0; i < files.length; i++) {
        const file = files[i];
        const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
        const uploadId = crypto.randomUUID();
        const useChunked = file.size > CHUNK_SIZE * 2; // Use chunked for files > 2MB

        progressText.textContent = `Uploading ${i + 1} of ${files.length}: ${file.name}`;

        try {
            let data;

            if (useChunked && totalChunks > 1) {
                // Chunked upload for large files
                for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
                    const start = chunkIndex * CHUNK_SIZE;
                    const end = Math.min(start + CHUNK_SIZE, file.size);
                    const chunk = file.slice(start, end);

                    const chunkForm = new FormData();
                    chunkForm.append('chunk', chunk);
                    chunkForm.append('upload_id', uploadId);
                    chunkForm.append('chunk_index', chunkIndex);
                    chunkForm.append('total_chunks', totalChunks);
                    chunkForm.append('filename', file.name);
                    if (files.length === 1 && displayName) {
                        chunkForm.append('display_name', displayName);
                    }

                    const chunkProgress = ((i + (chunkIndex + 1) / totalChunks) / files.length) * 100;
                    progressBar.style.width = `${chunkProgress}%`;
                    progressText.textContent = `Uploading ${i + 1} of ${files.length}: ${file.name} (${chunkIndex + 1}/${totalChunks} chunks)`;

                    const response = await fetch('/media/upload/chunk', {
                        method: 'POST',
                        body: chunkForm,
                    });

                    const contentType = response.headers.get('content-type') || '';
                    if (!contentType.includes('application/json')) {
                        const text = await response.text();
                        throw new Error(`Server error (${response.status}): ${text.substring(0, 100)}`);
                    }

                    data = await response.json();
                    if (!response.ok) {
                        throw new Error(data.detail || 'Chunk upload failed');
                    }
                }
            } else {
                // Regular upload for small files
                const formData = new FormData();
                formData.append('file', file);
                if (files.length === 1 && displayName) {
                    formData.append('display_name', displayName);
                }

                progressBar.style.width = `${((i + 0.5) / files.length) * 100}%`;

                const response = await fetch('/media/upload', {
                    method: 'POST',
                    body: formData,
                });

                const contentType = response.headers.get('content-type') || '';
                if (!contentType.includes('application/json')) {
                    const text = await response.text();
                    throw new Error(`Server error (${response.status}): ${text.substring(0, 100)}`);
                }

                data = await response.json();
                if (!response.ok) {
                    throw new Error(data.detail || 'Upload failed');
                }
            }

            results.push({ filename: file.name, friendly_name: data.friendly_name, cid: data.cid });
        } catch (err) {
            errors.push({ filename: file.name, error: err.message });
        }

        progressBar.style.width = `${((i + 1) / files.length) * 100}%`;
    }

    progressText.textContent = 'Upload complete!';

    // Show results
    let html = '';
    if (results.length > 0) {
        html += '<div class="bg-green-900 border border-green-700 rounded p-3 text-green-300 mb-2">';
        html += `<p class="font-medium">${results.length} file(s) uploaded successfully!</p>`;
        for (const r of results) {
            html += `<p class="text-sm mt-1">${r.filename} → <span class="font-mono">${r.friendly_name}</span></p>`;
        }
        html += '</div>';
    }
    if (errors.length > 0) {
        html += '<div class="bg-red-900 border border-red-700 rounded p-3 text-red-300">';
        html += `<p class="font-medium">${errors.length} file(s) failed:</p>`;
        for (const e of errors) {
            html += `<p class="text-sm mt-1">${e.filename}: ${e.error}</p>`;
        }
        html += '</div>';
    }

    resultDiv.innerHTML = html;
    resultDiv.classList.remove('hidden');

    if (results.length > 0) {
        // Reload page after 2 seconds
        setTimeout(() => location.reload(), 2000);
    } else {
        uploadBtn.disabled = false;
        uploadBtn.textContent = 'Upload';
    }
});
</script>
{% endblock %}
