{% extends "base.html.j2" %}
<!-- Side quest 18/21: Import your past. Export your future. -->
{% block title %}Import - neopig{% endblock %}

{% block extra_css %}
/* Page layout */
.container { max-width: 800px; margin: 0 auto; }
.subtitle { margin-bottom: 30px; }

/* Upload zone */
.upload-zone {
    border: 3px dashed #333;
    border-radius: 12px;
    padding: 60px 40px;
    text-align: center;
    background: #111;
    cursor: pointer;
    transition: all 0.2s;
}
.upload-zone:hover, .upload-zone.drag-over {
    border-color: #ff6b6b;
    background: #1a1a1a;
}
.upload-zone input[type="file"] { display: none; }
.upload-icon { font-size: 48px; margin-bottom: 15px; }
.upload-text { color: #888; font-size: 16px; }
.upload-hint { color: #555; font-size: 13px; margin-top: 10px; }

.status {
    margin-top: 30px;
    padding: 20px;
    background: #1a1a1a;
    border-radius: 8px;
    border: 1px solid #333;
}
.status-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #222; }
.status-row:last-child { border-bottom: none; }
.status-label { color: #888; }
.status-value { color: #e0e0e0; font-family: monospace; }

.progress { display: none; margin-top: 20px; }
.progress-bar {
    height: 8px; background: #333; border-radius: 4px; overflow: hidden;
}
.progress-fill {
    height: 100%; background: #ff6b6b; width: 0%; transition: width 0.3s;
}
.progress-text { text-align: center; margin-top: 10px; color: #888; font-size: 14px; }

.success { color: #6f6; }
.error { color: #f66; }
{% endblock %}

{% block content %}
<div class="container">
    <h1>{{ t.import_mode }}</h1>
    <p class="subtitle">{{ t.import_subtitle }}</p>

    <div class="upload-zone" id="upload-zone" onclick="document.getElementById('file-input').click()">
        <div class="upload-icon">📦</div>
        <div class="upload-text">{{ t.drop_or_browse }}</div>
        <div class="upload-hint">{{ t.supported_formats }}</div>
        <input type="file" id="file-input" accept=".tar.gz,.tgz,.run">
    </div>

    <div class="progress" id="progress">
        <div class="progress-bar"><div class="progress-fill" id="progress-fill"></div></div>
        <div class="progress-text" id="progress-text">{{ t.uploading }}</div>
    </div>

    <div class="status" id="status">
        <h3 style="margin-top:0;color:#ff6b6b;">{{ t.current_archive }}</h3>
        <div id="status-content">{{ t.loading }}</div>
    </div>
</div>
{% endblock %}

{% block scripts %}
<script>
const T = {{ t_json|safe }};
const zone = document.getElementById('upload-zone');
const fileInput = document.getElementById('file-input');
const progress = document.getElementById('progress');
const progressFill = document.getElementById('progress-fill');
const progressText = document.getElementById('progress-text');

zone.addEventListener('dragover', (e) => { e.preventDefault(); zone.classList.add('drag-over'); });
zone.addEventListener('dragleave', () => zone.classList.remove('drag-over'));
zone.addEventListener('drop', (e) => {
    e.preventDefault();
    zone.classList.remove('drag-over');
    if (e.dataTransfer.files.length) uploadFile(e.dataTransfer.files[0]);
});

fileInput.addEventListener('change', () => {
    if (fileInput.files.length) uploadFile(fileInput.files[0]);
});

const CHUNK_SIZE = 10 * 1024 * 1024;
const MAX_RETRIES = 10;
const RETRY_DELAY = 2000;

let currentUpload = null;

async function uploadFile(file) {
    progress.style.display = 'block';
    progressFill.style.width = '0%';
    progressText.textContent = `${T.initializing_upload} ${file.name}...`;

    try {
        const initRes = await fetch(`/api/import/upload/init?filename=${encodeURIComponent(file.name)}&size=${file.size}`, { method: 'POST' });
        if (!initRes.ok) {
            const err = await initRes.json();
            throw new Error(err.detail || 'Failed to initialize upload');
        }
        const init = await initRes.json();
        currentUpload = { uploadId: init.upload_id, file, offset: 0 };
        await uploadChunks();
    } catch (err) {
        progressText.innerHTML = `<span class="error">✗ ${err.message}</span>`;
    }
}

async function uploadChunks() {
    const { uploadId, file } = currentUpload;
    let retries = 0;

    while (currentUpload.offset < file.size) {
        const start = currentUpload.offset;
        const end = Math.min(start + CHUNK_SIZE, file.size);
        const chunk = file.slice(start, end);

        try {
            const res = await fetch(`/api/import/upload/${uploadId}`, {
                method: 'PATCH',
                headers: {
                    'Content-Type': 'application/octet-stream',
                    'X-Upload-Offset': start.toString()
                },
                body: chunk
            });

            if (!res.ok) {
                if (res.status === 409) {
                    const status = await getUploadStatus(uploadId);
                    currentUpload.offset = status.bytes_received;
                    continue;
                }
                const err = await res.json();
                throw new Error(err.detail || 'Chunk upload failed');
            }

            const data = await res.json();
            currentUpload.offset = data.bytes_received;
            retries = 0;

            const pct = (data.bytes_received / file.size * 100).toFixed(1);
            progressFill.style.width = pct + '%';
            const mb = (data.bytes_received / 1024 / 1024).toFixed(1);
            const totalMb = (file.size / 1024 / 1024).toFixed(1);
            progressText.textContent = `Uploading ${file.name}... ${pct}% (${mb}/${totalMb} MB)`;

        } catch (err) {
            retries++;
            if (retries > MAX_RETRIES) {
                progressText.innerHTML = `<span class="error">✗ ${T.upload_failed_retries}: ${err.message}</span>`;
                return;
            }
            progressText.textContent = `${T.connection_lost_retry} (${retries}/${MAX_RETRIES})...`;
            await new Promise(r => setTimeout(r, RETRY_DELAY));

            try {
                const status = await getUploadStatus(uploadId);
                currentUpload.offset = status.bytes_received;
            } catch (e) {}
        }
    }

    try {
        const completeRes = await fetch(`/api/import/upload/${uploadId}/complete`, { method: 'POST' });
        if (!completeRes.ok) {
            const err = await completeRes.json();
            throw new Error(err.detail || 'Failed to complete upload');
        }
        const result = await completeRes.json();
        progressText.innerHTML = `<span class="success">✓ ${T.archive_loaded} #${result.job_id}</span>`;
        currentUpload = null;
        loadStatus();
    } catch (err) {
        progressText.innerHTML = `<span class="error">✗ ${err.message}</span>`;
    }
}

async function getUploadStatus(uploadId) {
    const res = await fetch(`/api/import/upload/${uploadId}/status`);
    if (!res.ok) throw new Error('Failed to get upload status');
    return await res.json();
}

async function loadStatus() {
    try {
        const res = await fetch('/api/import/status');
        const data = await res.json();
        const content = document.getElementById('status-content');

        content.innerHTML = `
            <div class="status-row"><span class="status-label">${T.media_in_db}</span><span class="status-value">${(data.media_count || 0).toLocaleString()}</span></div>
            <div class="status-row"><span class="status-label">${T.pages_indexed}</span><span class="status-value">${(data.pages_count || 0).toLocaleString()}</span></div>
            <div class="status-row"><span class="status-label">${T.recent_imports}</span><span class="status-value">${data.recent_imports || 0}</span></div>
            <div class="status-row"><a href="/crawl" style="color:#ff6b6b;">${T.view_all_jobs} →</a></div>
        `;
    } catch (err) {
        document.getElementById('status-content').innerHTML = '<div class="error">' + T.failed_load_status + '</div>';
    }
}

loadStatus();
</script>
{% endblock %}
