{% extends "base.html" %}
{% block title %}Downloads - Viral Social Pro{% endblock %}
{% block nav_downloads %}active{% endblock %}

{% block content %}
<div class="p-6 space-y-6" x-data="downloadsApp()" x-init="loadDownloads()">
    <!-- Header -->
    <div class="gradient-bg rounded-2xl p-8 text-white">
        <h1 class="text-3xl font-bold mb-2">Downloads</h1>
        <p class="text-indigo-200">Baixe e gerencie seus videos</p>
    </div>

    <!-- Download Section -->
    <div class="bg-white rounded-xl shadow-sm p-6">
        <div class="flex items-center justify-between mb-4">
            <h2 class="text-lg font-bold text-gray-900">Download de Videos</h2>
            <div class="flex bg-gray-100 rounded-lg p-1">
                <button @click="dlMode = 'single'"
                        :class="dlMode === 'single' ? 'bg-white shadow-sm text-gray-900' : 'text-gray-500'"
                        class="px-4 py-1.5 rounded-md text-sm font-medium transition">
                    URL Unica
                </button>
                <button @click="dlMode = 'bulk'"
                        :class="dlMode === 'bulk' ? 'bg-white shadow-sm text-gray-900' : 'text-gray-500'"
                        class="px-4 py-1.5 rounded-md text-sm font-medium transition">
                    Download em Massa
                </button>
            </div>
        </div>

        <p class="text-sm text-gray-500 mb-4">
            <span x-show="dlMode === 'single'">Cole a URL de qualquer video do YouTube, TikTok, Instagram ou Sora para baixar.</span>
            <span x-show="dlMode === 'bulk'" x-cloak>Cole quantas URLs quiser (uma por linha). O sistema gerencia tudo automaticamente.</span>
        </p>

        <!-- Single URL mode -->
        <div x-show="dlMode === 'single'">
            <div class="flex gap-4">
                <input type="text" x-model="directUrl"
                       placeholder="Cole a URL do video (YouTube, TikTok, Instagram ou Sora)..."
                       class="flex-1 px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-brand-500 outline-none"
                       @keydown.enter="downloadDirect()">
                <button @click="downloadDirect()"
                        :disabled="directLoading"
                        class="px-8 py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 font-medium transition disabled:opacity-50">
                    <span x-show="!directLoading">Baixar</span>
                    <span x-show="directLoading" class="flex items-center gap-2">
                        <svg class="animate-spin h-5 w-5" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>
                        Baixando...
                    </span>
                </button>
            </div>
            <div x-show="directResult" x-cloak class="mt-3 text-sm text-green-600 font-medium" x-text="directResult"></div>
            <div x-show="directError" x-cloak class="mt-3 text-sm text-red-600 font-medium" x-text="directError"></div>
        </div>

        <!-- Bulk URL mode -->
        <div x-show="dlMode === 'bulk'" x-cloak>
            <!-- Input phase -->
            <div x-show="!bulkActive">
                <textarea x-model="bulkUrls" rows="8"
                          placeholder="Cole as URLs aqui, uma por linha (sem limite!)&#10;&#10;https://www.youtube.com/watch?v=...&#10;https://www.tiktok.com/@user/video/...&#10;https://sora.chatgpt.com/p/s_...&#10;&#10;Cole 10, 50, 200 ou mais URLs - o sistema processa tudo automaticamente!"
                          class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-brand-500 outline-none font-mono text-sm resize-y"></textarea>
                <div class="flex items-center justify-between mt-3">
                    <span class="text-xs text-gray-400" x-text="`${bulkUrlCount} URL(s) detectada(s)`"></span>
                    <button @click="startBulkDownload()"
                            :disabled="bulkLoading || bulkUrlCount === 0"
                            class="px-8 py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 font-medium transition disabled:opacity-50">
                        <span x-show="!bulkLoading">Baixar Todos</span>
                        <span x-show="bulkLoading" class="flex items-center gap-2">
                            <svg class="animate-spin h-5 w-5" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>
                            Iniciando...
                        </span>
                    </button>
                </div>
            </div>

            <!-- Progress view -->
            <div x-show="bulkActive" x-cloak>
                <!-- Overall progress -->
                <div class="mb-4">
                    <div class="flex justify-between text-sm mb-1">
                        <span class="text-gray-600" x-text="bulkStatusText"></span>
                        <span class="font-medium" x-text="`${bulkTotalDone + bulkTotalErrors} / ${bulkTotalUrls}`"></span>
                    </div>
                    <div class="w-full bg-gray-200 rounded-full h-3">
                        <div class="h-3 rounded-full transition-all duration-300"
                             :class="bulkTotalErrors > 0 ? 'bg-orange-500' : 'bg-brand-500'"
                             :style="`width: ${bulkTotalUrls ? ((bulkTotalDone + bulkTotalErrors) / bulkTotalUrls * 100) : 0}%`"></div>
                    </div>
                    <div class="flex gap-3 mt-1 text-xs">
                        <span x-show="bulkTotalDone > 0" class="text-green-600" x-text="`${bulkTotalDone} concluido(s)`"></span>
                        <span x-show="bulkTotalErrors > 0" class="text-red-500" x-text="`${bulkTotalErrors} erro(s)`"></span>
                        <span x-show="bulkBatchTotal > 1" class="text-blue-500" x-text="`Lote ${bulkBatchCurrent} de ${bulkBatchTotal}`"></span>
                    </div>
                </div>

                <!-- URL list with statuses -->
                <div class="space-y-2 max-h-96 overflow-y-auto">
                    <template x-for="(item, idx) in bulkAllItems" :key="idx">
                        <div class="flex items-center gap-3 p-2.5 rounded-lg text-sm"
                             :class="{
                                 'bg-gray-50': item.status === 'pending' || item.status === 'queued',
                                 'bg-blue-50 border border-blue-200': item.status === 'downloading',
                                 'bg-green-50': item.status === 'done',
                                 'bg-red-50': item.status === 'error'
                             }">
                            <div class="w-5 h-5 flex items-center justify-center flex-shrink-0">
                                <span x-show="item.status === 'pending' || item.status === 'queued'" class="text-gray-400 text-xs">&#9711;</span>
                                <svg x-show="item.status === 'downloading'" class="animate-spin h-4 w-4 text-blue-500" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>
                                <span x-show="item.status === 'done'" class="text-green-500 text-sm">&#10003;</span>
                                <span x-show="item.status === 'error'" class="text-red-500 text-sm">&#10007;</span>
                            </div>
                            <span class="flex-1 truncate font-mono text-xs text-gray-600" x-text="item.url"></span>
                            <span x-show="item.status === 'done'" class="text-xs text-green-600 whitespace-nowrap font-medium"
                                  x-text="item.size_formatted"></span>
                            <span x-show="item.status === 'error'" class="text-xs text-red-500 truncate max-w-[200px]"
                                  x-text="item.error" :title="item.error"></span>
                            <button x-show="item.status === 'done' && item.path" @click="downloadFile(item.path)"
                                    class="text-xs px-2.5 py-1 bg-green-500 text-white rounded-lg hover:bg-green-600 transition whitespace-nowrap flex-shrink-0">
                                Baixar
                            </button>
                        </div>
                    </template>
                </div>

                <!-- Action buttons -->
                <div class="flex gap-3 mt-4">
                    <button x-show="!bulkFinished" @click="cancelBulk()"
                            class="px-4 py-2 bg-red-100 text-red-600 rounded-lg hover:bg-red-200 font-medium text-sm transition">
                        Cancelar
                    </button>
                    <button x-show="bulkFinished"
                            @click="resetBulk()"
                            class="px-4 py-2 bg-gray-100 text-gray-600 rounded-lg hover:bg-gray-200 font-medium text-sm transition">
                        Novo Download
                    </button>
                    <button x-show="bulkTotalDone > 0 && bulkFinished" @click="downloadAllCompleted()"
                            class="px-4 py-2 bg-brand-100 text-brand-700 rounded-lg hover:bg-brand-200 font-medium text-sm transition">
                        Baixar Todos Concluidos
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- Filter -->
    <div class="bg-white rounded-xl p-4 shadow-sm flex gap-3">
        <button @click="filterPlatform = ''" :class="filterPlatform === '' ? 'bg-brand-500 text-white' : 'bg-gray-100 text-gray-700'"
                class="px-4 py-2 rounded-lg font-medium text-sm transition">Todos</button>
        <button @click="filterPlatform = 'youtube'" :class="filterPlatform === 'youtube' ? 'bg-red-500 text-white' : 'bg-gray-100 text-gray-700'"
                class="px-4 py-2 rounded-lg font-medium text-sm transition">YouTube</button>
        <button @click="filterPlatform = 'tiktok'" :class="filterPlatform === 'tiktok' ? 'bg-gray-900 text-white' : 'bg-gray-100 text-gray-700'"
                class="px-4 py-2 rounded-lg font-medium text-sm transition">TikTok</button>
        <button @click="filterPlatform = 'instagram'" :class="filterPlatform === 'instagram' ? 'bg-pink-500 text-white' : 'bg-gray-100 text-gray-700'"
                class="px-4 py-2 rounded-lg font-medium text-sm transition">Instagram</button>
    </div>

    <!-- Downloads List -->
    <div class="bg-white rounded-xl shadow-sm">
        <template x-if="loading">
            <div class="p-16 text-center text-gray-500">Carregando...</div>
        </template>

        <template x-if="!loading && filteredFiles.length === 0">
            <div class="p-16 text-center">
                <div class="text-6xl mb-4">&#128229;</div>
                <h3 class="text-lg font-medium text-gray-900 mb-2">Nenhum download ainda</h3>
                <p class="text-gray-500">Use o formulario acima para baixar videos</p>
            </div>
        </template>

        <template x-if="!loading && filteredFiles.length > 0">
            <div class="divide-y divide-gray-100">
                <template x-for="file in filteredFiles" :key="file.path">
                    <div class="p-4 flex items-center gap-4 hover:bg-gray-50 transition">
                        <div class="w-10 h-10 rounded-lg flex items-center justify-center text-lg"
                             :class="{
                                 'bg-red-100': file.platform === 'youtube',
                                 'bg-gray-100': file.platform === 'tiktok',
                                 'bg-pink-100': file.platform === 'instagram',
                             }">
                            <span x-text="file.platform === 'youtube' ? '&#9654;&#65039;' : file.platform === 'tiktok' ? '&#127925;' : '&#128247;'"></span>
                        </div>
                        <div class="flex-1 min-w-0">
                            <p class="text-sm font-medium text-gray-900 truncate" x-text="file.filename"></p>
                            <p class="text-xs text-gray-500">
                                <span x-text="file.platform" class="uppercase"></span> ·
                                <span x-text="file.size_formatted"></span> ·
                                <span x-text="new Date(file.downloaded_at).toLocaleDateString('pt-BR')"></span>
                            </p>
                        </div>
                        <a :href="`/api/downloads/file?path=${encodeURIComponent(file.path)}`"
                           :download="file.filename"
                           class="px-4 py-2 text-sm font-medium bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition flex items-center gap-2">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
                            Baixar
                        </a>
                    </div>
                </template>
            </div>
        </template>
    </div>
</div>
{% endblock %}

{% block scripts %}
<script>
function downloadsApp() {
    return {
        // File listing
        files: [],
        loading: true,
        filterPlatform: '',

        // Download mode
        dlMode: 'single',

        // Single download
        directUrl: '',
        directLoading: false,
        directResult: '',
        directError: '',

        // Bulk download with auto-batching
        bulkUrls: '',
        bulkLoading: false,
        bulkActive: false,
        bulkCancelled: false,
        bulkAllItems: [],       // all URLs with their status
        bulkTotalUrls: 0,
        bulkTotalDone: 0,
        bulkTotalErrors: 0,
        bulkBatchTotal: 0,
        bulkBatchCurrent: 0,
        bulkFinished: false,
        _pollTimer: null,
        _downloadedPaths: new Set(),

        BATCH_SIZE: 20,

        get bulkUrlCount() {
            return this.bulkUrls.split('\n').filter(u => u.trim()).length;
        },

        get filteredFiles() {
            if (!this.filterPlatform) return this.files;
            return this.files.filter(f => f.platform === this.filterPlatform);
        },

        get bulkStatusText() {
            if (this.bulkCancelled) return 'Cancelado';
            if (this.bulkFinished) return 'Concluido!';
            if (this.bulkBatchTotal > 1) return `Baixando... (Lote ${this.bulkBatchCurrent}/${this.bulkBatchTotal})`;
            return 'Baixando...';
        },

        async loadDownloads() {
            try {
                const data = await apiCall('/api/downloads');
                this.files = data.files;
            } catch (e) {}
            this.loading = false;
        },

        async downloadDirect() {
            if (!this.directUrl) { showToast('Cole a URL do video', 'warning'); return; }
            this.directLoading = true;
            this.directResult = '';
            this.directError = '';
            try {
                const params = new URLSearchParams({ url: this.directUrl });
                const data = await apiCall(`/api/download/url?${params}`, 'POST');
                if (data.success) {
                    this.directResult = `Download concluido: ${data.filename} (${data.size_formatted})`;
                    showToast(this.directResult, 'success');
                    this.downloadFile(data.path);
                    this.loadDownloads();
                } else {
                    this.directError = `Erro: ${data.error}`;
                    showToast(this.directError, 'error');
                }
            } catch (e) {
                this.directError = e.message || 'Erro no download';
                showToast(this.directError, 'error');
            }
            this.directLoading = false;
        },

        async startBulkDownload() {
            const allUrls = this.bulkUrls.split('\n').map(u => u.trim()).filter(u => u);
            if (allUrls.length === 0) return;

            this.bulkLoading = true;
            this.bulkActive = true;
            this.bulkCancelled = false;
            this.bulkFinished = false;
            this.bulkTotalUrls = allUrls.length;
            this.bulkTotalDone = 0;
            this.bulkTotalErrors = 0;
            this._downloadedPaths = new Set();

            // Build the full items list
            this.bulkAllItems = allUrls.map(url => ({
                url,
                status: 'queued',
                filename: '',
                path: '',
                size_formatted: '',
                error: '',
            }));

            // Split into batches
            const batches = [];
            for (let i = 0; i < allUrls.length; i += this.BATCH_SIZE) {
                batches.push(allUrls.slice(i, i + this.BATCH_SIZE));
            }
            this.bulkBatchTotal = batches.length;
            this.bulkBatchCurrent = 0;
            this.bulkLoading = false;

            // Process batches sequentially
            for (let b = 0; b < batches.length; b++) {
                if (this.bulkCancelled) break;

                this.bulkBatchCurrent = b + 1;
                const batchUrls = batches[b];
                const batchOffset = b * this.BATCH_SIZE;

                // Mark this batch as pending
                for (let j = 0; j < batchUrls.length; j++) {
                    this.bulkAllItems[batchOffset + j].status = 'pending';
                }

                try {
                    const params = new URLSearchParams({
                        urls: batchUrls.join('\n'),
                        quality: 'best',
                    });
                    const data = await apiCall(`/api/download/bulk?${params}`, 'POST');

                    if (batches.length > 1) {
                        showToast(`Lote ${b + 1}/${batches.length}: ${batchUrls.length} videos...`, 'info');
                    } else {
                        showToast(`Iniciando download de ${data.total} videos...`, 'info');
                    }

                    // Poll this batch until done
                    await this._pollBatchUntilDone(data.job_id, batchOffset, batchUrls.length);

                } catch (e) {
                    // Mark remaining URLs in this batch as error
                    for (let j = 0; j < batchUrls.length; j++) {
                        const item = this.bulkAllItems[batchOffset + j];
                        if (item.status === 'pending' || item.status === 'queued') {
                            item.status = 'error';
                            item.error = e.message || 'Erro ao iniciar lote';
                            this.bulkTotalErrors++;
                        }
                    }
                    showToast(`Erro no lote ${b + 1}: ${e.message}`, 'error');
                }
            }

            this.bulkFinished = true;
            if (!this.bulkCancelled) {
                const msg = `Download concluido: ${this.bulkTotalDone}/${this.bulkTotalUrls} videos`;
                showToast(msg, this.bulkTotalErrors > 0 ? 'warning' : 'success');
            }
            this.loadDownloads();
        },

        _pollBatchUntilDone(jobId, offset, batchSize) {
            return new Promise((resolve) => {
                const poll = setInterval(async () => {
                    if (this.bulkCancelled) {
                        clearInterval(poll);
                        try { await apiCall(`/api/download/bulk/${jobId}/cancel`, 'POST'); } catch(e) {}
                        resolve();
                        return;
                    }

                    try {
                        const resp = await fetch(`/api/download/bulk/${jobId}/status`);
                        if (!resp.ok) return;
                        const status = await resp.json();

                        // Update individual items
                        for (let i = 0; i < (status.urls || []).length; i++) {
                            const remote = status.urls[i];
                            const local = this.bulkAllItems[offset + i];
                            if (!local) continue;

                            local.status = remote.status;
                            local.filename = remote.filename;
                            local.path = remote.path;
                            local.size_formatted = remote.size_formatted;
                            local.error = remote.error;
                        }

                        // Update totals from all items
                        this.bulkTotalDone = this.bulkAllItems.filter(i => i.status === 'done').length;
                        this.bulkTotalErrors = this.bulkAllItems.filter(i => i.status === 'error').length;

                        // Auto-download completed files
                        const newDone = (status.urls || []).filter(
                            item => item.status === 'done' && item.path && !this._downloadedPaths.has(item.path)
                        );
                        for (let i = 0; i < newDone.length; i++) {
                            this._downloadedPaths.add(newDone[i].path);
                            setTimeout(() => this.downloadFile(newDone[i].path), i * 1500);
                        }

                        if (status.status === 'completed' || status.status === 'cancelled') {
                            clearInterval(poll);
                            resolve();
                        }
                    } catch (e) {
                        // Continue polling on network errors
                    }
                }, 2000);

                this._pollTimer = poll;
            });
        },

        cancelBulk() {
            this.bulkCancelled = true;
            showToast('Cancelando downloads...', 'info');
        },

        resetBulk() {
            this.bulkActive = false;
            this.bulkFinished = false;
            this.bulkCancelled = false;
            this.bulkUrls = '';
            this.bulkAllItems = [];
            this.bulkTotalUrls = 0;
            this.bulkTotalDone = 0;
            this.bulkTotalErrors = 0;
            this.bulkBatchTotal = 0;
            this.bulkBatchCurrent = 0;
            this._downloadedPaths = new Set();
            if (this._pollTimer) { clearInterval(this._pollTimer); this._pollTimer = null; }
        },

        downloadAllCompleted() {
            const completed = this.bulkAllItems.filter(i => i.status === 'done' && i.path);
            for (let i = 0; i < completed.length; i++) {
                setTimeout(() => this.downloadFile(completed[i].path), i * 1500);
            }
            showToast(`Baixando ${completed.length} arquivos...`, 'info');
        },

        downloadFile(path) {
            const iframe = document.createElement('iframe');
            iframe.style.display = 'none';
            iframe.src = `/api/downloads/file?path=${encodeURIComponent(path)}`;
            document.body.appendChild(iframe);
            setTimeout(() => { try { document.body.removeChild(iframe); } catch(e) {} }, 60000);
        },
    };
}
</script>
{% endblock %}
