<?php
/**
 * Página pública de carga de archivos grandes
 * 
 * Los clientes acceden a esta página desde un enlace enviado por WhatsApp.
 * NO requiere autenticación — se valida por token único.
 * 
 * URL: /upload.php?token=XXXXX
 */

// No requiere session ni auth del panel
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', 0);

require_once __DIR__ . '/config/config.php';

// Obtener token de la URL
$token = $_GET['token'] ?? '';

if (empty($token) || !preg_match('/^[a-zA-Z0-9]{32,64}$/', $token)) {
    http_response_code(404);
    showErrorPage('Enlace no válido', 'El enlace al que intentas acceder no es válido.');
    exit;
}

// Buscar la solicitud en la BD
try {
    $db = Database::getInstance();
    $request = $db->fetch(
        "SELECT fr.*, u.name as user_name 
         FROM file_requests fr 
         LEFT JOIN users u ON fr.user_id = u.id 
         WHERE fr.token = ?",
        [$token]
    );
} catch (Exception $e) {
    http_response_code(500);
    showErrorPage('Error del sistema', 'No se pudo verificar el enlace. Intenta de nuevo más tarde.');
    exit;
}

if (!$request) {
    http_response_code(404);
    showErrorPage('Enlace no encontrado', 'Este enlace de carga no existe o ya fue eliminado.');
    exit;
}

// Verificar expiración
if (strtotime($request['expires_at']) < time()) {
    http_response_code(410);
    showErrorPage('Enlace expirado', 'Este enlace de carga ha expirado. Solicita uno nuevo al asesor.');
    exit;
}

// Verificar estado
if ($request['status'] === 'cancelled') {
    http_response_code(410);
    showErrorPage('Enlace cancelado', 'Esta solicitud fue cancelada. Contacta a tu asesor.');
    exit;
}

// Verificar archivos ya subidos
$uploadedFiles = [];
try {
    $uploadedFiles = $db->fetchAll(
        "SELECT * FROM file_request_uploads WHERE request_id = ? ORDER BY created_at DESC",
        [$request['id']]
    );
} catch (Exception $e) {
    // No crítico
}

$alreadyUploaded = ($request['status'] === 'uploaded' && count($uploadedFiles) > 0);

// Calcular tamaño máximo legible
$maxSizeMB = round($request['max_file_size'] / (1024 * 1024));
$allowedTypes = explode(',', $request['allowed_types']);

// Auto-detectar APP_URL
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$appUrl = $protocol . '://' . $_SERVER['HTTP_HOST'];

function showErrorPage($title, $message) {
    ?>
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title><?= htmlspecialchars($title) ?></title>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
        <style>
            body { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #e5ddd5 0%, #f0f4f7 100%); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
            .error-card { background: white; border-radius: 16px; padding: 40px; text-align: center; box-shadow: 0 8px 30px rgba(0,0,0,0.08); max-width: 400px; }
            .error-icon { font-size: 64px; margin-bottom: 16px; }
        </style>
    </head>
    <body>
        <div class="error-card">
            <div class="error-icon">⚠️</div>
            <h4><?= htmlspecialchars($title) ?></h4>
            <p class="text-muted"><?= htmlspecialchars($message) ?></p>
        </div>
    </body>
    </html>
    <?php
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>📎 Subir archivo</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <style>
        :root {
            --wa-green: #25d366;
            --wa-green-dark: #128c7e;
            --wa-dark: #075e54;
        }

        * { box-sizing: border-box; }

        body {
            min-height: 100vh;
            background: linear-gradient(135deg, #e5ddd5 0%, #f0f4f7 100%);
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            margin: 0;
            padding: 16px;
        }

        .upload-container {
            max-width: 480px;
            margin: 0 auto;
            padding-top: 20px;
        }

        .upload-header {
            background: linear-gradient(180deg, var(--wa-dark) 0%, #054f45 100%);
            color: white;
            padding: 20px 24px;
            border-radius: 16px 16px 0 0;
            text-align: center;
        }

        .upload-header h4 {
            margin: 0 0 4px 0;
            font-size: 18px;
        }

        .upload-header p {
            margin: 0;
            opacity: 0.85;
            font-size: 13px;
        }

        .upload-body {
            background: white;
            padding: 24px;
            border-radius: 0 0 16px 16px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.08);
        }

        .drop-zone {
            border: 2px dashed #ccc;
            border-radius: 12px;
            padding: 40px 20px;
            text-align: center;
            cursor: pointer;
            transition: all 0.2s ease;
            background: #fafafa;
            margin-bottom: 20px;
        }

        .drop-zone:hover, .drop-zone.drag-over {
            border-color: var(--wa-green);
            background: rgba(37, 211, 102, 0.04);
        }

        .drop-zone.drag-over {
            transform: scale(1.01);
        }

        .drop-zone-icon {
            font-size: 48px;
            color: var(--wa-green);
            margin-bottom: 12px;
        }

        .drop-zone-text {
            font-size: 15px;
            color: #555;
            margin-bottom: 8px;
        }

        .drop-zone-hint {
            font-size: 12px;
            color: #999;
        }

        .file-list {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 20px;
        }

        .file-item {
            display: flex;
            align-items: center;
            gap: 12px;
            padding: 10px 12px;
            background: #f8f9fa;
            border-radius: 10px;
            border: 1px solid #eee;
        }

        .file-item-icon {
            font-size: 28px;
            color: var(--wa-green);
            flex-shrink: 0;
        }

        .file-item-info {
            flex: 1;
            min-width: 0;
        }

        .file-item-name {
            font-weight: 600;
            font-size: 14px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .file-item-size {
            font-size: 12px;
            color: #888;
        }

        .file-item-remove {
            color: #dc3545;
            cursor: pointer;
            padding: 4px;
            font-size: 16px;
        }

        .file-item-remove:hover {
            color: #a71d2a;
        }

        .upload-progress {
            display: none;
            margin-bottom: 16px;
        }

        .progress {
            height: 6px;
            border-radius: 3px;
            overflow: hidden;
        }

        .progress-bar {
            background: var(--wa-green);
            transition: width 0.3s ease;
        }

        .btn-upload {
            background: var(--wa-green);
            color: white;
            border: none;
            border-radius: 12px;
            padding: 14px 24px;
            width: 100%;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .btn-upload:hover:not(:disabled) {
            background: var(--wa-green-dark);
            transform: translateY(-1px);
        }

        .btn-upload:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .success-card {
            text-align: center;
            padding: 30px;
        }

        .success-icon {
            font-size: 64px;
            color: var(--wa-green);
            margin-bottom: 16px;
            animation: bounceIn 0.5s ease;
        }

        @keyframes bounceIn {
            0% { transform: scale(0.3); opacity: 0; }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); opacity: 1; }
        }

        .uploaded-files {
            margin-top: 20px;
        }

        .uploaded-file {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 8px 12px;
            background: #e8f5e9;
            border-radius: 8px;
            margin-bottom: 8px;
        }

        .info-banner {
            background: #fff3e0;
            border: 1px solid rgba(255, 152, 0, 0.2);
            border-radius: 10px;
            padding: 12px 16px;
            margin-bottom: 20px;
            font-size: 13px;
            color: #5c3a00;
            display: flex;
            align-items: flex-start;
            gap: 10px;
        }

        .info-banner i {
            color: #ff9800;
            margin-top: 2px;
        }

        .security-badge {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-size: 12px;
            color: #888;
            margin-top: 16px;
        }

        .security-badge i {
            color: var(--wa-green);
        }

        /* Responsive */
        @media (max-width: 480px) {
            body { padding: 8px; }
            .upload-body { padding: 16px; }
            .drop-zone { padding: 28px 16px; }
        }
    </style>
</head>
<body>
    <div class="upload-container">
        <div class="upload-header">
            <h4><i class="fas fa-cloud-upload-alt me-2"></i>Subir archivo</h4>
            <p>Envía archivos de hasta <?= $maxSizeMB ?> MB de forma segura</p>
        </div>

        <div class="upload-body">
            <?php if ($alreadyUploaded): ?>
                <!-- Ya se subieron archivos -->
                <div class="success-card">
                    <div class="success-icon"><i class="fas fa-check-circle"></i></div>
                    <h5>¡Archivos recibidos!</h5>
                    <p class="text-muted">Tus archivos fueron enviados correctamente. El asesor los recibirá en breve.</p>
                    
                    <div class="uploaded-files">
                        <?php foreach ($uploadedFiles as $file): ?>
                        <div class="uploaded-file">
                            <i class="fas fa-file-check text-success"></i>
                            <div style="flex:1; text-align:left;">
                                <div style="font-weight:600; font-size:13px;"><?= htmlspecialchars($file['original_filename']) ?></div>
                                <div style="font-size:12px; color:#888;"><?= formatSize($file['file_size']) ?></div>
                            </div>
                        </div>
                        <?php endforeach; ?>
                    </div>

                    <div class="info-banner mt-3">
                        <i class="fas fa-info-circle"></i>
                        <span>Puedes subir archivos adicionales si lo necesitas.</span>
                    </div>

                    <button class="btn-upload" onclick="showUploadForm()">
                        <i class="fas fa-plus me-2"></i>Subir más archivos
                    </button>
                </div>
            <?php endif; ?>

            <div id="upload-form" style="<?= $alreadyUploaded ? 'display:none' : '' ?>">
                <div class="info-banner">
                    <i class="fas fa-shield-alt"></i>
                    <span>
                        Este enlace es seguro y exclusivo para ti. Los archivos serán recibidos directamente por tu asesor.
                        <br><strong>Máximo: <?= $maxSizeMB ?> MB por archivo.</strong>
                    </span>
                </div>

                <!-- Zona de arrastre -->
                <div class="drop-zone" id="drop-zone" onclick="document.getElementById('file-input-public').click()">
                    <div class="drop-zone-icon"><i class="fas fa-cloud-upload-alt"></i></div>
                    <div class="drop-zone-text">Toca para seleccionar o arrastra tus archivos aquí</div>
                    <div class="drop-zone-hint">
                        <?php
                        $typeLabels = [];
                        if (in_array('image', $allowedTypes)) $typeLabels[] = 'imágenes';
                        if (in_array('document', $allowedTypes)) $typeLabels[] = 'documentos';
                        if (in_array('video', $allowedTypes)) $typeLabels[] = 'videos';
                        if (in_array('audio', $allowedTypes)) $typeLabels[] = 'audios';
                        echo implode(', ', $typeLabels) . ' — hasta ' . $maxSizeMB . ' MB';
                        ?>
                    </div>
                </div>

                <input type="file" id="file-input-public" multiple accept="<?= getAcceptString($allowedTypes) ?>" 
                       style="display:none" onchange="handleFileSelect(event)">

                <!-- Lista de archivos seleccionados -->
                <div class="file-list" id="file-list"></div>

                <!-- Barra de progreso -->
                <div class="upload-progress" id="upload-progress">
                    <div class="d-flex justify-content-between mb-1">
                        <small id="progress-text">Subiendo...</small>
                        <small id="progress-pct">0%</small>
                    </div>
                    <div class="progress">
                        <div class="progress-bar" id="progress-bar" style="width: 0%"></div>
                    </div>
                </div>

                <!-- Botón enviar -->
                <button class="btn-upload" id="btn-submit" onclick="submitFiles()" disabled>
                    <i class="fas fa-paper-plane me-2"></i>Enviar archivos
                </button>

                <div class="security-badge">
                    <i class="fas fa-lock"></i>
                    Conexión cifrada y segura
                </div>
            </div>

            <!-- Estado de éxito (post-upload) -->
            <div id="upload-success" style="display:none">
                <div class="success-card">
                    <div class="success-icon"><i class="fas fa-check-circle"></i></div>
                    <h5>¡Archivos enviados!</h5>
                    <p class="text-muted">Tu asesor recibirá los archivos en breve. Puedes cerrar esta página.</p>
                    <button class="btn-upload mt-3" onclick="showUploadForm()">
                        <i class="fas fa-plus me-2"></i>Subir más archivos
                    </button>
                </div>
            </div>
        </div>
    </div>

    <script>
        const CONFIG = {
            token: '<?= htmlspecialchars($token) ?>',
            maxFileSize: <?= intval($request['max_file_size']) ?>,
            maxFileSizeMB: <?= $maxSizeMB ?>,
            allowedTypes: <?= json_encode($allowedTypes) ?>,
            apiUrl: 'api/file_request_upload.php'
        };

        let selectedFiles = [];

        // === Drag & Drop ===
        const dropZone = document.getElementById('drop-zone');
        
        ['dragenter', 'dragover'].forEach(evt => {
            dropZone.addEventListener(evt, e => {
                e.preventDefault();
                dropZone.classList.add('drag-over');
            });
        });

        ['dragleave', 'drop'].forEach(evt => {
            dropZone.addEventListener(evt, e => {
                e.preventDefault();
                dropZone.classList.remove('drag-over');
            });
        });

        dropZone.addEventListener('drop', e => {
            const files = Array.from(e.dataTransfer.files);
            addFiles(files);
        });

        // === Selección de archivos ===
        function handleFileSelect(event) {
            const files = Array.from(event.target.files);
            addFiles(files);
            event.target.value = ''; // Reset para permitir re-selección
        }

        function addFiles(files) {
            for (const file of files) {
                // Validar tamaño
                if (file.size > CONFIG.maxFileSize) {
                    alert(`El archivo "${file.name}" excede el límite de ${CONFIG.maxFileSizeMB} MB.`);
                    continue;
                }

                // Validar tipo
                if (!isAllowedType(file)) {
                    alert(`El tipo de archivo "${file.name}" no está permitido.`);
                    continue;
                }

                // Evitar duplicados
                if (selectedFiles.some(f => f.name === file.name && f.size === file.size)) {
                    continue;
                }

                selectedFiles.push(file);
            }

            renderFileList();
            updateSubmitButton();
        }

        function isAllowedType(file) {
            const type = file.type || '';
            const ext = file.name.split('.').pop().toLowerCase();

            for (const allowed of CONFIG.allowedTypes) {
                switch (allowed) {
                    case 'image':
                        if (type.startsWith('image/') || ['jpg','jpeg','png','gif','webp','bmp','svg'].includes(ext)) return true;
                        break;
                    case 'document':
                        if (['pdf','doc','docx','xls','xlsx','ppt','pptx','txt','csv','rtf','odt','ods','zip','rar','7z'].includes(ext)) return true;
                        if (type.startsWith('application/')) return true;
                        break;
                    case 'video':
                        if (type.startsWith('video/') || ['mp4','mov','avi','mkv','webm','3gp'].includes(ext)) return true;
                        break;
                    case 'audio':
                        if (type.startsWith('audio/') || ['mp3','ogg','wav','aac','m4a','opus'].includes(ext)) return true;
                        break;
                }
            }
            return false;
        }

        function removeFile(index) {
            selectedFiles.splice(index, 1);
            renderFileList();
            updateSubmitButton();
        }

        function renderFileList() {
            const list = document.getElementById('file-list');
            if (selectedFiles.length === 0) {
                list.innerHTML = '';
                return;
            }

            list.innerHTML = selectedFiles.map((file, i) => `
                <div class="file-item">
                    <div class="file-item-icon">
                        <i class="${getFileIcon(file)}"></i>
                    </div>
                    <div class="file-item-info">
                        <div class="file-item-name">${escapeHtml(file.name)}</div>
                        <div class="file-item-size">${formatSize(file.size)}</div>
                    </div>
                    <div class="file-item-remove" onclick="removeFile(${i})">
                        <i class="fas fa-times-circle"></i>
                    </div>
                </div>
            `).join('');
        }

        function updateSubmitButton() {
            const btn = document.getElementById('btn-submit');
            btn.disabled = selectedFiles.length === 0;
            if (selectedFiles.length > 0) {
                btn.innerHTML = `<i class="fas fa-paper-plane me-2"></i>Enviar ${selectedFiles.length} archivo${selectedFiles.length > 1 ? 's' : ''}`;
            } else {
                btn.innerHTML = '<i class="fas fa-paper-plane me-2"></i>Enviar archivos';
            }
        }

        // === Subida de archivos ===
        async function submitFiles() {
            if (selectedFiles.length === 0) return;

            const btn = document.getElementById('btn-submit');
            const progress = document.getElementById('upload-progress');
            const progressBar = document.getElementById('progress-bar');
            const progressText = document.getElementById('progress-text');
            const progressPct = document.getElementById('progress-pct');

            btn.disabled = true;
            btn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Subiendo...';
            progress.style.display = 'block';

            let uploaded = 0;
            const total = selectedFiles.length;
            let errors = [];

            for (let i = 0; i < selectedFiles.length; i++) {
                const file = selectedFiles[i];
                progressText.textContent = `Subiendo ${file.name}... (${i + 1}/${total})`;

                try {
                    const formData = new FormData();
                    formData.append('token', CONFIG.token);
                    formData.append('file', file);

                    const response = await uploadWithProgress(formData, (pct) => {
                        const totalPct = Math.round(((i + pct / 100) / total) * 100);
                        progressBar.style.width = totalPct + '%';
                        progressPct.textContent = totalPct + '%';
                    });

                    if (response.success) {
                        uploaded++;
                    } else {
                        errors.push(`${file.name}: ${response.error || 'Error desconocido'}`);
                    }
                } catch (e) {
                    errors.push(`${file.name}: Error de conexión`);
                }
            }

            if (uploaded > 0) {
                // Mostrar éxito
                document.getElementById('upload-form').style.display = 'none';
                document.getElementById('upload-success').style.display = 'block';
                selectedFiles = [];

                if (errors.length > 0) {
                    alert(`Se subieron ${uploaded}/${total} archivos.\n\nErrores:\n${errors.join('\n')}`);
                }
            } else {
                alert('No se pudieron subir los archivos.\n\n' + errors.join('\n'));
                btn.disabled = false;
                btn.innerHTML = '<i class="fas fa-paper-plane me-2"></i>Reintentar';
            }

            progress.style.display = 'none';
            progressBar.style.width = '0%';
        }

        function uploadWithProgress(formData, onProgress) {
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                
                xhr.upload.addEventListener('progress', e => {
                    if (e.lengthComputable) {
                        onProgress(Math.round((e.loaded / e.total) * 100));
                    }
                });

                xhr.addEventListener('load', () => {
                    try {
                        const data = JSON.parse(xhr.responseText);
                        resolve(data);
                    } catch (e) {
                        resolve({ success: xhr.status === 200, error: 'Respuesta inválida' });
                    }
                });

                xhr.addEventListener('error', () => reject(new Error('Error de red')));
                xhr.addEventListener('timeout', () => reject(new Error('Tiempo de espera agotado')));

                xhr.open('POST', CONFIG.apiUrl);
                xhr.timeout = 120000; // 2 minutos por archivo
                xhr.send(formData);
            });
        }

        function showUploadForm() {
            document.getElementById('upload-success').style.display = 'none';
            const successCards = document.querySelectorAll('.success-card');
            successCards.forEach(c => c.style.display = 'none');
            document.getElementById('upload-form').style.display = 'block';
            selectedFiles = [];
            renderFileList();
            updateSubmitButton();
        }

        // === Utilidades ===
        function getFileIcon(file) {
            const ext = file.name.split('.').pop().toLowerCase();
            if (file.type.startsWith('image/')) return 'fas fa-file-image text-primary';
            if (file.type.startsWith('video/')) return 'fas fa-file-video text-danger';
            if (file.type.startsWith('audio/')) return 'fas fa-file-audio text-warning';
            const icons = {
                pdf: 'fas fa-file-pdf text-danger',
                doc: 'fas fa-file-word text-primary', docx: 'fas fa-file-word text-primary',
                xls: 'fas fa-file-excel text-success', xlsx: 'fas fa-file-excel text-success',
                ppt: 'fas fa-file-powerpoint text-warning', pptx: 'fas fa-file-powerpoint text-warning',
                zip: 'fas fa-file-archive text-secondary', rar: 'fas fa-file-archive text-secondary',
                txt: 'fas fa-file-alt text-muted', csv: 'fas fa-file-csv text-success',
            };
            return icons[ext] || 'fas fa-file text-muted';
        }

        function formatSize(bytes) {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return (bytes / Math.pow(k, i)).toFixed(1) + ' ' + sizes[i];
        }

        function escapeHtml(text) {
            const d = document.createElement('div');
            d.textContent = text;
            return d.innerHTML;
        }
    </script>
</body>
</html>

<?php
// Helpers PHP
function formatSize($bytes) {
    if ($bytes == 0) return '0 B';
    $k = 1024;
    $sizes = ['B', 'KB', 'MB', 'GB'];
    $i = floor(log($bytes) / log($k));
    return round($bytes / pow($k, $i), 1) . ' ' . $sizes[$i];
}

function getAcceptString($types) {
    $accepts = [];
    if (in_array('image', $types)) $accepts[] = 'image/*';
    if (in_array('document', $types)) {
        $accepts = array_merge($accepts, [
            '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', 
            '.txt', '.csv', '.rtf', '.odt', '.zip', '.rar', '.7z'
        ]);
    }
    if (in_array('video', $types)) $accepts[] = 'video/*';
    if (in_array('audio', $types)) $accepts[] = 'audio/*';
    return implode(',', $accepts);
}
?>
