<?php
// ============================================
// CONFIGURAÇÃO DE SEGURANÇA - DEFINA AQUI
// ============================================

// 1. Onde este script está localizado (pasta do script)
$script_dir = __DIR__ . DIRECTORY_SEPARATOR;
$base_dir = '/home';  // Exemplo Linux
//    Opção B: Diretório específico (recomendado)
// $base_dir = '/var/www/html/';  // Exemplo Linux
// $base_dir = 'C:/xampp/htdocs/';  // Exemplo Windows
// 2. Diretório RAIZ que o gerenciador pode acessar
//$base_dir = DIRECTORY_SEPARATOR; // Linux: /    Windows: C:\

// 3. Tipos de arquivo permitidos para upload
$allowed_types = ['zip', 'php', 'txt', 'jpg', 'png', 'pdf', 'html', 'css', 'js'];

// 4. Tamanho máximo de upload (em bytes)
$max_size = 10 * 1024 * 1024; // 10MB

// 5. Extensões que podem ser visualizadas como texto
$text_extensions = ['txt', 'php', 'html', 'css', 'js', 'log', 'ini', 'md', 'csv', 'xml', 'json', 'htaccess'];

// ============================================
// FIM DAS CONFIGURAÇÕES
// ============================================

// Normalizar caminhos
$base_dir = rtrim(str_replace(['\\', '/'], DIRECTORY_SEPARATOR, realpath($base_dir) ?: $base_dir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$script_dir = realpath($script_dir) . DIRECTORY_SEPARATOR;

// Criar pasta temp na pasta do script (para uploads temporários e zips)
$temp_dir = $script_dir . 'temp' . DIRECTORY_SEPARATOR;
if (!is_dir($temp_dir)) {
    mkdir($temp_dir, 0755, true);
}

$errors = [];
$success = '';

// ============================================
// FUNÇÃO DE SEGURANÇA: Validar caminho
// ============================================
function securePath($user_path, $base_dir) {
    $user_path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $user_path);
    $user_path = preg_replace('/\.\.+/', '', $user_path);
    $full_path = $base_dir . ltrim($user_path, DIRECTORY_SEPARATOR);
    $real_path = realpath($full_path);
    
    if ($real_path === false) {
        $parent = dirname($full_path);
        if (realpath($parent) === false) {
            return false;
        }
        return $full_path;
    }
    
    if (strpos($real_path . DIRECTORY_SEPARATOR, $base_dir) !== 0) {
        return false;
    }
    
    return $real_path . (is_dir($real_path) ? DIRECTORY_SEPARATOR : '');
}

// ============================================
// FUNÇÃO: Compactar itens selecionados
// ============================================
function createZipFromSelection($items, $current_dir, $base_dir, $temp_dir) {
    if (empty($items)) {
        return ['error' => 'Nenhum item selecionado.'];
    }
    
    // Verificar se ZipArchive está disponível
    if (!class_exists('ZipArchive')) {
        return ['error' => 'Extensão ZIP não disponível no servidor.'];
    }
    
    // Criar nome único para o ZIP
    $zip_name = 'backup_' . date('Y-m-d_H-i-s') . '_' . substr(md5(uniqid()), 0, 8) . '.zip';
    $zip_path = $temp_dir . $zip_name;
    
    $zip = new ZipArchive();
    if ($zip->open($zip_path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
        return ['error' => 'Não foi possível criar o arquivo ZIP.'];
    }
    
    $added_count = 0;
    $errors_zip = [];
    
    foreach ($items as $item) {
        $item = basename($item); // Segurança
        $item_path = $current_dir . $item;
        
        if (!file_exists($item_path)) {
            $errors_zip[] = "Item não encontrado: " . htmlspecialchars($item);
            continue;
        }
        
        // Verificar se está dentro da base
        $real_path = realpath($item_path);
        if ($real_path === false || strpos($real_path . DIRECTORY_SEPARATOR, $base_dir) !== 0) {
            $errors_zip[] = "Acesso negado: " . htmlspecialchars($item);
            continue;
        }
        
        if (is_dir($item_path)) {
            // Adicionar pasta recursivamente
            $base_path = dirname($real_path) . DIRECTORY_SEPARATOR;
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($real_path, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::SELF_FIRST
            );
            
            foreach ($files as $file) {
                $file_path = $file->getRealPath();
                $relative_path = substr($file_path, strlen($base_path));
                
                if ($file->isDir()) {
                    $zip->addEmptyDir($relative_path);
                } else {
                    $zip->addFile($file_path, $relative_path);
                }
                $added_count++;
            }
        } else {
            // Adicionar arquivo único
            $zip->addFile($real_path, $item);
            $added_count++;
        }
    }
    
    $zip->close();
    
    if ($added_count === 0) {
        unlink($zip_path);
        return ['error' => 'Nenhum item foi adicionado ao ZIP.'];
    }
    
    return [
        'success' => true,
        'path' => $zip_path,
        'name' => $zip_name,
        'count' => $added_count,
        'errors' => $errors_zip
    ];
}

// ============================================
// FUNÇÃO: Download múltiplo como ZIP
// ============================================
function downloadMultipleAsZip($items, $current_dir, $base_dir) {
    $temp_zip = $base_dir . 'temp_download_' . uniqid() . '.zip';
    
    $zip = new ZipArchive();
    if ($zip->open($temp_zip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
        return false;
    }
    
    foreach ($items as $item) {
        $item = basename($item);
        $item_path = $current_dir . $item;
        
        if (!file_exists($item_path)) continue;
        
        $real_path = realpath($item_path);
        if ($real_path === false || strpos($real_path . DIRECTORY_SEPARATOR, $base_dir) !== 0) continue;
        
        if (is_dir($item_path)) {
            $base_path = dirname($real_path) . DIRECTORY_SEPARATOR;
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($real_path, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::SELF_FIRST
            );
            
            foreach ($files as $file) {
                $file_path = $file->getRealPath();
                $relative_path = substr($file_path, strlen($base_path));
                
                if ($file->isDir()) {
                    $zip->addEmptyDir($relative_path);
                } else {
                    $zip->addFile($file_path, $relative_path);
                }
            }
        } else {
            $zip->addFile($real_path, $item);
        }
    }
    
    $zip->close();
    return $temp_zip;
}

// ============================================
// GERENCIADOR DE ARQUIVOS
// ============================================

// Obter diretório atual da navegação
$rel_dir = '';
if (isset($_GET['dir'])) {
    $rel_dir = trim($_GET['dir'], '/\\');
}

// Validar e obter diretório atual
$current_dir = $base_dir;
if (!empty($rel_dir)) {
    $test_dir = securePath($rel_dir, $base_dir);
    if ($test_dir !== false && is_dir($test_dir)) {
        $current_dir = $test_dir;
    } else {
        $errors[] = "Diretório inválido ou acesso negado.";
        $rel_dir = '';
    }
}

// Calcular caminho relativo para breadcrumbs
$display_rel = str_replace($base_dir, '', $current_dir);

// ============================================
// AÇÃO: Compactar selecionados
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'compress' && !empty($_POST['items'])) {
    $selected_items = $_POST['items'];
    $result = createZipFromSelection($selected_items, $current_dir, $base_dir, $temp_dir);
    
    if (isset($result['error'])) {
        $errors[] = $result['error'];
    } else {
        // Mover ZIP para o diretório atual
        $final_path = $current_dir . $result['name'];
        if (rename($result['path'], $final_path)) {
            chmod($final_path, 0644);
            $success = "✅ Compactação concluída!<br>" .
                      "Arquivo: " . htmlspecialchars($result['name']) . "<br>" .
                      "Itens adicionados: " . $result['count'] . "<br>" .
                      "Tamanho: " . formatSize(filesize($final_path));
            
            if (!empty($result['errors'])) {
                $success .= "<br><small>⚠️ Avisos: " . implode('; ', $result['errors']) . "</small>";
            }
        } else {
            $errors[] = "Erro ao mover arquivo ZIP para o diretório atual.";
        }
    }
}

// ============================================
// AÇÃO: Download múltiplo
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'download_selected' && !empty($_POST['items'])) {
    $selected_items = $_POST['items'];
    
    if (count($selected_items) === 1) {
        // Download único
        $item = basename($selected_items[0]);
        $item_path = $current_dir . $item;
        
        if (is_file($item_path)) {
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="' . $item . '"');
            header('Content-Length: ' . filesize($item_path));
            readfile($item_path);
            exit;
        } else {
            // Se for pasta, compactar primeiro
            $temp_file = downloadMultipleAsZip([$item], $current_dir, $base_dir);
            if ($temp_file && file_exists($temp_file)) {
                header('Content-Description: File Transfer');
                header('Content-Type: application/zip');
                header('Content-Disposition: attachment; filename="' . $item . '.zip"');
                header('Content-Length: ' . filesize($temp_file));
                readfile($temp_file);
                unlink($temp_file);
                exit;
            }
        }
    } else {
        // Múltiplos itens - compactar e baixar
        $temp_file = downloadMultipleAsZip($selected_items, $current_dir, $base_dir);
        if ($temp_file && file_exists($temp_file)) {
            $download_name = 'arquivos_selecionados_' . date('Y-m-d_H-i-s') . '.zip';
            header('Content-Description: File Transfer');
            header('Content-Type: application/zip');
            header('Content-Disposition: attachment; filename="' . $download_name . '"');
            header('Content-Length: ' . filesize($temp_file));
            readfile($temp_file);
            unlink($temp_file);
            exit;
        } else {
            $errors[] = "Erro ao preparar download.";
        }
    }
}

// Ação: Download
if (isset($_GET['download']) && !empty($_GET['download'])) {
    $filename = basename($_GET['download']);
    $filepath = securePath(($rel_dir ? $rel_dir . '/' : '') . $filename, $base_dir);
    
    if ($filepath !== false && is_file($filepath)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Length: ' . filesize($filepath));
        header('Cache-Control: no-cache, must-revalidate');
        readfile($filepath);
        exit;
    } else {
        $errors[] = "Arquivo não encontrado ou acesso negado.";
    }
}

// Ação: Visualizar arquivo texto
if (isset($_GET['view']) && !empty($_GET['view'])) {
    $filename = basename($_GET['view']);
    $filepath = securePath(($rel_dir ? $rel_dir . '/' : '') . $filename, $base_dir);
    $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    
    if ($filepath !== false && is_file($filepath) && in_array($ext, $text_extensions)) {
        header('Content-Type: text/plain; charset=utf-8');
        header('Content-Disposition: inline; filename="' . $filename . '"');
        $filesize = filesize($filepath);
        if ($filesize > 5 * 1024 * 1024) {
            echo "Arquivo muito grande para visualização. Faça o download.";
            exit;
        }
        readfile($filepath);
        exit;
    } else {
        $errors[] = "Arquivo não encontrado, acesso negado ou não é um arquivo de texto.";
    }
}

// Ação: Copiar arquivo
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'copy') {
    $source_name = basename($_POST['source'] ?? '');
    $target_name = basename($_POST['target'] ?? '');
    $target_dir_post = $_POST['target_dir'] ?? '';
    
    if (empty($source_name) || empty($target_name)) {
        $errors[] = "Nome de arquivo inválido.";
    } else {
        $source_path = securePath(($rel_dir ? $rel_dir . '/' : '') . $source_name, $base_dir);
        $dest_dir = !empty($target_dir_post) ? trim($target_dir_post, '/\\') : $rel_dir;
        $dest_dir_path = securePath($dest_dir, $base_dir);
        
        if ($source_path !== false && is_file($source_path) && $dest_dir_path !== false && is_dir($dest_dir_path)) {
            $target_path = $dest_dir_path . $target_name;
            
            if (file_exists($target_path)) {
                $errors[] = "Arquivo de destino já existe: " . htmlspecialchars($target_name);
            } elseif (copy($source_path, $target_path)) {
                chmod($target_path, 0644);
                $success = "Arquivo copiado com sucesso!<br>" .
                          "De: " . htmlspecialchars($source_name) . "<br>" .
                          "Para: " . htmlspecialchars($target_name);
            } else {
                $errors[] = "Erro ao copiar o arquivo. Verifique permissões.";
            }
        } else {
            $errors[] = "Origem ou destino inválido.";
        }
    }
}

// Ação: Criar nova pasta
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'mkdir') {
    $folder_name = basename($_POST['folder_name'] ?? '');
    
    if (empty($folder_name)) {
        $errors[] = "Nome da pasta inválido.";
    } else {
        $new_folder = $current_dir . $folder_name;
        if (!file_exists($new_folder)) {
            if (mkdir($new_folder, 0755, true)) {
                $success = "Pasta criada com sucesso: " . htmlspecialchars($folder_name);
            } else {
                $errors[] = "Erro ao criar pasta. Verifique permissões.";
            }
        } else {
            $errors[] = "Esta pasta já existe.";
        }
    }
}

// Ação: Deletar arquivo/pasta
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete') {
    $item_name = basename($_POST['item'] ?? '');
    $item_path = securePath(($rel_dir ? $rel_dir . '/' : '') . $item_name, $base_dir);
    
    if ($item_path !== false && $item_path !== $base_dir && strpos($item_path, $base_dir) === 0) {
        if (is_dir($item_path)) {
            $contents = scandir($item_path);
            if (count($contents) <= 2) {
                if (rmdir($item_path)) {
                    $success = "Pasta removida: " . htmlspecialchars($item_name);
                } else {
                    $errors[] = "Erro ao remover pasta.";
                }
            } else {
                $errors[] = "A pasta não está vazia. Remova os arquivos primeiro.";
            }
        } elseif (is_file($item_path)) {
            if (unlink($item_path)) {
                $success = "Arquivo removido: " . htmlspecialchars($item_name);
            } else {
                $errors[] = "Erro ao remover arquivo.";
            }
        } else {
            $errors[] = "Item não encontrado.";
        }
    } else {
        $errors[] = "Operação não permitida.";
    }
}

// ============================================
// UPLOADS
// ============================================

// Upload via URL com cURL
if (isset($_POST['upload_url'])) {
    $url = trim($_POST['url']);
    $upload_to = isset($_POST['upload_dir']) ? trim($_POST['upload_dir'], '/\\') : '';
    $dest_path = securePath($upload_to, $base_dir);
    
    if ($dest_path === false || !is_dir($dest_path)) {
        $dest_path = $base_dir;
    }
    
    if (empty($url)) {
        $errors[] = "URL não pode estar vazia.";
    } elseif (!filter_var($url, FILTER_VALIDATE_URL)) {
        $errors[] = "URL inválida.";
    } else {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 5,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; FileManager/1.0)'
        ]);
        
        $file_content = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        $curl_error = curl_error($ch);
        curl_close($ch);
        
        if ($curl_error) {
            $errors[] = "Erro cURL: " . $curl_error;
        } elseif ($http_code !== 200) {
            $errors[] = "Erro HTTP: " . $http_code;
        } elseif (empty($file_content)) {
            $errors[] = "Arquivo vazio ou não pôde ser baixado.";
        } else {
            $url_parts = parse_url($url);
            $path_parts = pathinfo($url_parts['path']);
            $original_name = $path_parts['filename'];
            $file_ext = strtolower($path_parts['extension'] ?? '');
            
            if (empty($file_ext) && $content_type) {
                $mime_map = [
                    'application/zip' => 'zip',
                    'application/pdf' => 'pdf',
                    'image/jpeg' => 'jpg',
                    'image/png' => 'png',
                    'text/plain' => 'txt'
                ];
                foreach ($mime_map as $mime => $ext) {
                    if (strpos($content_type, $mime) !== false) {
                        $file_ext = $ext;
                        break;
                    }
                }
            }
            
            if (empty($file_ext)) $file_ext = 'bin';
            if (!in_array($file_ext, $allowed_types)) {
                $errors[] = "Tipo de arquivo não permitido: " . $file_ext;
            } else {
                $filename = $original_name . '_' . time() . '.' . $file_ext;
                $target_path = $dest_path . $filename;
                
                if (file_put_contents($target_path, $file_content)) {
                    chmod($target_path, 0644);
                    $success = "Arquivo baixado com sucesso!<br>" .
                              "Nome: " . htmlspecialchars($filename) . "<br>" .
                              "Tamanho: " . round(strlen($file_content) / 1024, 2) . " KB<br>" .
                              "Salvo em: " . htmlspecialchars(str_replace($base_dir, '', $dest_path));
                } else {
                    $errors[] = "Erro ao salvar arquivo.";
                }
            }
        }
    }
}

// Upload local
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['fileToUpload'])) {
    $upload_to = isset($_POST['upload_dir']) ? trim($_POST['upload_dir'], '/\\') : '';
    $dest_path = securePath($upload_to, $base_dir);
    
    if ($dest_path === false || !is_dir($dest_path)) {
        $dest_path = $base_dir;
    }
    
    $file_name = basename($_FILES["fileToUpload"]["name"]);
    $target_file = $dest_path . $file_name;
    $fileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
    
    if (!is_uploaded_file($_FILES["fileToUpload"]["tmp_name"])) {
        $errors[] = "Arquivo inválido.";
    } elseif ($_FILES["fileToUpload"]["size"] > $max_size) {
        $errors[] = "Arquivo muito grande. Máximo: " . ($max_size / 1024 / 1024) . "MB";
    } elseif (!in_array($fileType, $allowed_types)) {
        $errors[] = "Tipo de arquivo não permitido.";
    } elseif (file_exists($target_file)) {
        $errors[] = "Arquivo já existe.";
    } else {
        if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
            chmod($target_file, 0644);
            $success = "Upload realizado com sucesso!<br>" .
                      "Nome: " . htmlspecialchars($file_name) . "<br>" .
                      "Tamanho: " . round($_FILES["fileToUpload"]["size"] / 1024, 2) . " KB";
        } else {
            $errors[] = "Erro ao mover arquivo.";
        }
    }
}
?>

<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gerenciador de Arquivos - Compactação e Download Múltiplo</title>
<style>
body {
    font-family: 'Segoe UI', Arial, sans-serif;
    max-width: 1200px;
    margin: auto;
    padding: 20px;
    background: #f0f2f5;
}
.container {
    background: white;
    padding: 25px;
    border-radius: 10px;
    margin-bottom: 20px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.error {
    color: #d32f2f;
    background: #ffebee;
    padding: 12px;
    border-radius: 6px;
    margin-bottom: 15px;
    border-left: 4px solid #d32f2f;
}
.success {
    color: #2e7d32;
    background: #e8f5e9;
    padding: 12px;
    border-radius: 6px;
    margin-bottom: 15px;
    border-left: 4px solid #2e7d32;
}
.tab-buttons {
    display: flex;
    gap: 10px;
    margin-bottom: 25px;
    border-bottom: 2px solid #e0e0e0;
    padding-bottom: 15px;
    flex-wrap: wrap;
}
.tab-button {
    background: #e0e0e0;
    border: none;
    padding: 10px 20px;
    cursor: pointer;
    border-radius: 6px;
    font-size: 14px;
    transition: all 0.3s;
}
.tab-button.active {
    background: #1976d2;
    color: white;
}
.tab-content {
    display: none;
}
.tab-content.active {
    display: block;
}
.form-group {
    margin-bottom: 15px;
}
.form-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: 600;
    color: #333;
}
input[type="text"], input[type="url"], input[type="file"], select {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 6px;
    box-sizing: border-box;
    font-size: 14px;
}
input[type="submit"], button {
    background: #1976d2;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 14px;
    transition: background 0.3s;
}
input[type="submit"]:hover, button:hover {
    background: #1565c0;
}
.breadcrumb {
    background: #f5f5f5;
    padding: 10px 15px;
    border-radius: 6px;
    margin-bottom: 20px;
    font-size: 14px;
}
.breadcrumb a {
    color: #1976d2;
    text-decoration: none;
}
.breadcrumb a:hover {
    text-decoration: underline;
}
.file-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 10px;
}
.file-table th {
    background: #1976d2;
    color: white;
    padding: 12px;
    text-align: left;
}
.file-table td {
    padding: 10px 12px;
    border-bottom: 1px solid #eee;
}
.file-table tr:hover {
    background: #f5f5f5;
}
.file-table tr.selected {
    background: #e3f2fd;
}
.action-btn {
    display: inline-block;
    padding: 4px 10px;
    margin: 0 3px;
    border-radius: 4px;
    font-size: 12px;
    text-decoration: none;
    cursor: pointer;
    border: none;
    color: white;
}
.btn-download { background: #4caf50; }
.btn-view { background: #2196f3; }
.btn-copy { background: #ff9800; }
.btn-delete { background: #f44336; }
.btn-mkdir { background: #9c27b0; }
.btn-compress { background: #00bcd4; }
.btn-download-selected { background: #4caf50; padding: 12px 24px; font-size: 14px; }
.inline-form {
    display: inline;
}
.inline-form input[type="text"] {
    width: 120px;
    padding: 4px 8px;
    margin: 0 5px;
    vertical-align: middle;
}
.info-box {
    background: #e3f2fd;
    padding: 20px;
    border-radius: 8px;
    margin-top: 20px;
}
.info-box h3 {
    margin-top: 0;
    color: #1976d2;
}
small {
    color: #666;
    display: block;
    margin-top: 4px;
}
.path-display {
    background: #fff3e0;
    padding: 8px 12px;
    border-radius: 4px;
    font-family: monospace;
    font-size: 13px;
    margin-bottom: 15px;
    border: 1px solid #ffe0b2;
}
.selection-bar {
    background: #e3f2fd;
    padding: 15px;
    border-radius: 6px;
    margin-bottom: 15px;
    display: none;
    border: 2px solid #1976d2;
}
.selection-bar.active {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}
.selection-info {
    font-weight: bold;
    color: #1976d2;
}
.checkbox-cell {
    width: 30px;
    text-align: center;
}
.select-all-container {
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    gap: 10px;
}
.select-all-container label {
    cursor: pointer;
    user-select: none;
}
input[type="checkbox"] {
    width: 16px;
    height: 16px;
    cursor: pointer;
}
</style>
<script>
function showTab(tabId) {
    document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
    document.querySelectorAll('.tab-button').forEach(b => b.classList.remove('active'));
    document.getElementById(tabId).classList.add('active');
    event.currentTarget.classList.add('active');
}

function toggleCopyForm(filename) {
    var formId = 'copy-form-' + filename.replace(/[^a-zA-Z0-9]/g, '_');
    var form = document.getElementById(formId);
    form.style.display = form.style.display === 'none' ? 'inline' : 'none';
}

function confirmDelete(item, type) {
    return confirm('Tem certeza que deseja deletar ' + type + ': ' + item + '?');
}

// Funções de seleção múltipla
let selectedItems = new Set();

function toggleSelectAll(source) {
    const checkboxes = document.getElementsByClassName('item-checkbox');
    for (let checkbox of checkboxes) {
        checkbox.checked = source.checked;
        if (source.checked) {
            selectedItems.add(checkbox.value);
        } else {
            selectedItems.delete(checkbox.value);
        }
    }
    updateSelectionBar();
    updateRowHighlight();
}

function toggleItem(checkbox) {
    if (checkbox.checked) {
        selectedItems.add(checkbox.value);
    } else {
        selectedItems.delete(checkbox.value);
    }
    updateSelectionBar();
    updateRowHighlight();
    updateSelectAllCheckbox();
}

function updateSelectAllCheckbox() {
    const selectAll = document.getElementById('select-all');
    const checkboxes = document.getElementsByClassName('item-checkbox');
    selectAll.checked = checkboxes.length > 0 && selectedItems.size === checkboxes.length;
    selectAll.indeterminate = selectedItems.size > 0 && selectedItems.size < checkboxes.length;
}

function updateSelectionBar() {
    const bar = document.getElementById('selection-bar');
    const count = document.getElementById('selection-count');
    const hiddenInput = document.getElementById('selected-items-input');
    
    if (selectedItems.size > 0) {
        bar.classList.add('active');
        count.textContent = selectedItems.size;
        hiddenInput.value = Array.from(selectedItems).join(',');
    } else {
        bar.classList.remove('active');
        count.textContent = '0';
        hiddenInput.value = '';
    }
}

function updateRowHighlight() {
    const rows = document.getElementsByClassName('file-row');
    for (let row of rows) {
        const checkbox = row.querySelector('.item-checkbox');
        if (checkbox && checkbox.checked) {
            row.classList.add('selected');
        } else {
            row.classList.remove('selected');
        }
    }
}

function downloadSelected() {
    if (selectedItems.size === 0) {
        alert('Selecione pelo menos um item.');
        return false;
    }
    document.getElementById('download-form').submit();
    return true;
}

function compressSelected() {
    if (selectedItems.size === 0) {
        alert('Selecione pelo menos um item para compactar.');
        return false;
    }
    if (confirm('Compactar ' + selectedItems.size + ' item(ns) em um arquivo ZIP?')) {
        document.getElementById('compress-form').submit();
        return true;
    }
    return false;
}
</script>
</head>
<body>

<div class="container">
    <h2>📁 Gerenciador de Arquivos Avançado</h2>
    
    <div class="path-display">
        📍 Script em: <?= htmlspecialchars($script_dir) ?><br>
        🌐 Acesso permitido a partir de: <?= htmlspecialchars($base_dir) ?>
    </div>
    
    <?php if (!empty($errors)): ?>
    <div class="error">
        <strong>⚠️ Erros:</strong>
        <ul style="margin:5px 0;">
            <?php foreach ($errors as $error): ?>
            <li><?= htmlspecialchars($error) ?></li>
            <?php endforeach; ?>
        </ul>
    </div>
    <?php endif; ?>
    
    <?php if (!empty($success)): ?>
    <div class="success">
        <strong>✅ Sucesso!</strong><br>
        <?= $success ?>
    </div>
    <?php endif; ?>
    
    <div class="tab-buttons">
        <button class="tab-button active" onclick="showTab('tab-manager')">📂 Gerenciador</button>
        <button class="tab-button" onclick="showTab('tab-local')">📤 Upload Local</button>
        <button class="tab-button" onclick="showTab('tab-url')">🌐 Upload via URL</button>
    </div>
    
    <!-- ============================================ -->
    <!-- GERENCIADOR DE ARQUIVOS -->
    <!-- ============================================ -->
    <div id="tab-manager" class="tab-content active">
        <h3>Explorador de Arquivos</h3>
        
        <!-- Breadcrumb -->
        <div class="breadcrumb">
            <a href="?dir=">🏠 /</a>
            <?php
            if (!empty($display_rel)) {
                $parts = explode('/', str_replace('\\', '/', trim($display_rel, '/')));
                $path_acc = '';
                foreach ($parts as $i => $part) {
                    if (empty($part)) continue;
                    $path_acc .= ($i == 0 ? '' : '/') . $part;
                    echo ' / <a href="?dir=' . rawurlencode($path_acc) . '">📁 ' . htmlspecialchars($part) . '</a>';
                }
            }
            ?>
        </div>
        
        <!-- Criar nova pasta -->
        <form method="post" style="margin-bottom: 15px;" class="inline-form">
            <input type="hidden" name="action" value="mkdir">
            <input type="text" name="folder_name" placeholder="Nome da nova pasta" required>
            <button type="submit" class="btn-mkdir">📁 Criar Pasta</button>
        </form>
        
        <!-- Barra de seleção -->
        <div id="selection-bar" class="selection-bar">
            <span class="selection-info">📋 <span id="selection-count">0</span> itens selecionados</span>
            <div style="display: flex; gap: 10px;">
                <form id="download-form" method="post" style="display: inline;">
                    <input type="hidden" name="action" value="download_selected">
                    <input type="hidden" name="items" id="selected-items-input" value="">
                    <button type="button" onclick="downloadSelected()" class="btn-download-selected">
                        ⬇️ Baixar Selecionados
                    </button>
                </form>
                <form id="compress-form" method="post" style="display: inline;">
                    <input type="hidden" name="action" value="compress">
                    <input type="hidden" name="items" id="compress-items-input" value="">
                    <button type="button" onclick="compressSelected()" class="action-btn btn-compress" style="padding: 12px 24px; font-size: 14px;">
                        📦 Compactar Selecionados
                    </button>
                </form>
            </div>
        </div>
        
        <!-- Selecionar todos -->
        <div class="select-all-container">
            <input type="checkbox" id="select-all" onchange="toggleSelectAll(this)">
            <label for="select-all"><strong>Selecionar todos</strong></label>
        </div>
        
        <!-- Listagem -->
        <form id="main-form" method="post">
            <table class="file-table">
                <thead>
                    <tr>
                        <th class="checkbox-cell">☑️</th>
                        <th>Nome</th>
                        <th>Tamanho</th>
                        <th>Modificado</th>
                        <th>Ações</th>
                    </tr>
                </thead>
                <tbody>
                <?php
                $items = @scandir($current_dir);
                if ($items === false) {
                    echo '<tr><td colspan="5">❌ Sem permissão para acessar este diretório.</td></tr>';
                } else {
                    $dirs = [];
                    $files = [];
                    
                    foreach ($items as $item) {
                        if ($item === '.' || $item === '..') continue;
                        if ($item === 'temp' && realpath($current_dir . $item) === realpath($temp_dir)) continue;
                        $full = $current_dir . $item;
                        if (is_dir($full)) {
                            $dirs[] = $item;
                        } else {
                            $files[] = $item;
                        }
                    }
                    
                    natcasesort($dirs);
                    natcasesort($files);
                    $all = array_merge($dirs, $files);
                    
                    if (empty($all)) {
                        echo '<tr><td colspan="5">📭 Diretório vazio.</td></tr>';
                    }
                    
                    foreach ($all as $item) {
                        $full = $current_dir . $item;
                        $is_dir = is_dir($full);
                        $icon = $is_dir ? '📁' : '📄';
                        $size = $is_dir ? '-' : formatSize(filesize($full));
                        $modified = date('d/m/Y H:i', filemtime($full));
                        
                        echo '<tr class="file-row">';
                        
                        // Checkbox
                        echo '<td class="checkbox-cell">';
                        echo '<input type="checkbox" class="item-checkbox" value="' . htmlspecialchars($item) . '" onchange="toggleItem(this)">';
                        echo '</td>';
                        
                        // Nome
                        if ($is_dir) {
                            $new_dir = ($display_rel ? $display_rel . '/' : '') . $item;
                            echo '<td><a href="?dir=' . rawurlencode($new_dir) . '">' . $icon . ' ' . htmlspecialchars($item) . '/</a></td>';
                        } else {
                            echo '<td>' . $icon . ' ' . htmlspecialchars($item) . '</td>';
                        }
                        
                        echo '<td>' . $size . '</td>';
                        echo '<td>' . $modified . '</td>';
                        
                        // Ações
                        echo '<td>';
                        if (!$is_dir) {
                            echo '<a href="?dir=' . rawurlencode($display_rel) . '&download=' . rawurlencode($item) . '" class="action-btn btn-download">⬇️</a> ';
                            
                            if (in_array(strtolower(pathinfo($item, PATHINFO_EXTENSION)), $text_extensions)) {
                                echo '<a href="?dir=' . rawurlencode($display_rel) . '&view=' . rawurlencode($item) . '" target="_blank" class="action-btn btn-view">👁️</a> ';
                            }
                            
                            $form_id = 'copy-form-' . preg_replace('/[^a-zA-Z0-9]/', '_', $item);
                            echo '<button onclick="toggleCopyForm(\'' . htmlspecialchars($item, ENT_QUOTES) . '\')" class="action-btn btn-copy">📋</button>';
                            echo '<span id="' . $form_id . '" style="display:none;">';
                            echo '<form method="post" class="inline-form" action="?dir=' . rawurlencode($display_rel) . '">';
                            echo '<input type="hidden" name="action" value="copy">';
                            echo '<input type="hidden" name="source" value="' . htmlspecialchars($item) . '">';
                            echo '<input type="hidden" name="target_dir" value="' . htmlspecialchars($display_rel) . '">';
                            echo '<input type="text" name="target" placeholder="novo_nome.ext" required>';
                            echo '<button type="submit">✔️</button>';
                            echo '</form>';
                            echo '</span> ';
                        }
                        
                        echo '<form method="post" class="inline-form" onsubmit="return confirmDelete(\'' . htmlspecialchars($item, ENT_QUOTES) . '\', \'' . ($is_dir ? 'pasta' : 'arquivo') . '\')">';
                        echo '<input type="hidden" name="action" value="delete">';
                        echo '<input type="hidden" name="item" value="' . htmlspecialchars($item) . '">';
                        echo '<button type="submit" class="action-btn btn-delete">🗑️</button>';
                        echo '</form>';
                        
                        echo '</td>';
                        echo '</tr>';
                    }
                }
                ?>
                </tbody>
            </table>
        </form>
    </div>
    
    <!-- ============================================ -->
    <!-- UPLOAD LOCAL -->
    <!-- ============================================ -->
    <div id="tab-local" class="tab-content">
        <h3>Upload de Arquivo Local</h3>
        <form method="post" enctype="multipart/form-data">
            <div class="form-group">
                <label>Selecione o arquivo:</label>
                <input type="file" name="fileToUpload" required>
            </div>
            <div class="form-group">
                <label>Destino (relativo à base):</label>
                <input type="text" name="upload_dir" value="<?= htmlspecialchars($display_rel) ?>" placeholder="subpasta/">
                <small>Deixe em branco para salvar na raiz.</small>
            </div>
            <input type="submit" value="📤 Enviar Arquivo">
        </form>
    </div>
    
    <!-- ============================================ -->
    <!-- UPLOAD VIA URL -->
    <!-- ============================================ -->
    <div id="tab-url" class="tab-content">
        <h3>Download via URL (cURL)</h3>
        <form method="post">
            <div class="form-group">
                <label>URL do arquivo:</label>
                <input type="url" name="url" placeholder="https://exemplo.com/arquivo.zip" required>
            </div>
            <div class="form-group">
                <label>Destino (relativo à base):</label>
                <input type="text" name="upload_dir" value="<?= htmlspecialchars($display_rel) ?>" placeholder="subpasta/">
            </div>
            <input type="submit" name="upload_url" value="🌐 Baixar Arquivo">
        </form>
    </div>
</div>

<!-- Informações -->
<div class="container info-box">
    <h3>ℹ️ Informações</h3>
    <ul>
        <li><strong>Tamanho máximo upload:</strong> <?= round($max_size / 1024 / 1024, 2) ?> MB</li>
        <li><strong>Tipos permitidos:</strong> <?= implode(', ', $allowed_types) ?></li>
        <li><strong>cURL:</strong> <?= function_exists('curl_version') ? '✅ Disponível' : '❌ Não disponível' ?></li>
        <li><strong>ZIP:</strong> <?= class_exists('ZipArchive') ? '✅ Disponível' : '❌ Não disponível' ?></li>
        <li><strong>Diretório base:</strong> <?= htmlspecialchars($base_dir) ?></li>
        <li><strong>Local do script:</strong> <?= htmlspecialchars($script_dir) ?></li>
    </ul>
    <small>⚠️ Atenção: Mantenha este script em local seguro. Não exponha publicamente sem proteção adicional.</small>
    <div style="margin-top: 15px;">
        <strong>🆕 Novas funcionalidades:</strong>
        <ul>
            <li>✅ Seleção múltipla de arquivos e pastas</li>
            <li>✅ Download de múltiplos itens (compactados em ZIP)</li>
            <li>✅ Compactar itens selecionados e salvar no diretório atual</li>
            <li>✅ Destaque visual dos itens selecionados</li>
            <li>✅ Selecionar/desselecionar todos</li>
        </ul>
    </div>
</div>

<script>
// Sincronizar os campos hidden dos formulários de ação
document.getElementById('compress-form').addEventListener('submit', function(e) {
    document.getElementById('compress-items-input').value = document.getElementById('selected-items-input').value;
});

// Atualizar campos hidden quando a página carrega
window.addEventListener('load', function() {
    updateSelectionBar();
});
</script>

</body>
</html>

<?php
function formatSize($bytes) {
    if ($bytes === 0) return '0 B';
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $i = floor(log($bytes, 1024));
    return round($bytes / pow(1024, $i), 1) . ' ' . $units[$i];
}
?>