<?php
// Configurações
$target_dir = __DIR__ . DIRECTORY_SEPARATOR;
$max_size = 5 * 1024 * 1024; // 5MB
$allowed_types = ['zip', 'php', 'txt', 'jpg', 'png', 'pdf'];
$temp_dir = __DIR__ . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR;

// Segurança: diretório base real (resolve symlinks e normaliza)
$base_dir = realpath($target_dir) . DIRECTORY_SEPARATOR;

$errors = [];
$success = '';

// Criar diretório temporário se não existir
if (!is_dir($temp_dir)) {
    mkdir($temp_dir, 0755, true);
}

// Função para validar arquivo
function validateFile($file_path, $file_size, $file_ext, $max_size, $allowed_types) {
    $errors = [];
    
    if ($file_size > $max_size) {
        $errors[] = "Arquivo muito grande. Máximo: " . ($max_size / 1024 / 1024) . "MB";
    }
    
    if (!in_array($file_ext, $allowed_types)) {
        $errors[] = "Tipo não permitido: " . $file_ext;
    }
    
    return $errors;
}

// Função para salvar arquivo
function saveFile($source, $destination, $filename) {
    $target_file = $destination . $filename;
    
    if (file_exists($target_file)) {
        return ["error" => "Arquivo já existe: " . $filename];
    }
    
    if (copy($source, $target_file)) {
        chmod($target_file, 0644);
        return ["success" => true, "path" => $target_file, "name" => $filename];
    }
    
    return ["error" => "Erro ao salvar arquivo"];
}

// ================== NOVO: Gerenciador de Arquivos ==================

// Obter diretório atual (padrão: raiz)
$rel_dir = '';
if (isset($_GET['dir'])) {
    $rel_dir = trim($_GET['dir'], '/\\');
}
// Sanitização: resolver caminho absoluto e garantir que está dentro do diretório base
$current_dir = realpath($base_dir . $rel_dir);
if ($current_dir === false || strpos($current_dir, $base_dir) !== 0) {
    $current_dir = $base_dir;
    $rel_dir = '';
} else {
    $current_dir .= DIRECTORY_SEPARATOR;
}

// Download de arquivo
if (isset($_GET['download']) && !empty($_GET['download'])) {
    $filename = basename($_GET['download']);
    $filepath = realpath($current_dir . $filename);
    if ($filepath && strpos($filepath, $base_dir) === 0 && 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));
        readfile($filepath);
        exit;
    } else {
        $errors[] = "Arquivo não encontrado ou acesso negado.";
    }
}

// Visualização de arquivo texto
if (isset($_GET['view']) && !empty($_GET['view'])) {
    $filename = basename($_GET['view']);
    $filepath = realpath($current_dir . $filename);
    $text_ext = ['txt', 'php', 'html', 'css', 'js', 'log', 'ini', 'md', 'csv', 'xml', 'json'];
    $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    if ($filepath && strpos($filepath, $base_dir) === 0 && is_file($filepath) && in_array($ext, $text_ext)) {
        header('Content-Type: text/plain; charset=utf-8');
        readfile($filepath);
        exit;
    } else {
        $errors[] = "Arquivo não encontrado ou não é um arquivo de texto.";
    }
}

// Cópia de arquivo (via POST)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'copy') {
    $source_name = basename($_POST['source'] ?? '');
    $target_name = basename($_POST['target'] ?? '');
    
    if (empty($source_name) || empty($target_name)) {
        $errors[] = "Nome de arquivo inválido.";
    } else {
        $source_path = realpath($current_dir . $source_name);
        $target_path = $current_dir . $target_name;
        
        // Verificar se fonte existe e está dentro da base
        if (!$source_path || strpos($source_path, $base_dir) !== 0 || !is_file($source_path)) {
            $errors[] = "Arquivo de origem não encontrado.";
        } elseif (file_exists($target_path)) {
            $errors[] = "O arquivo de destino já existe: " . htmlspecialchars($target_name);
        } else {
            if (copy($source_path, $target_path)) {
                $success = "Arquivo copiado com sucesso!<br>Novo nome: " . htmlspecialchars($target_name);
            } else {
                $errors[] = "Erro ao copiar o arquivo.";
            }
        }
    }
}

// ================== FIM DO GERENCIADOR ==================

// Upload via URL com cURL (mantido)
if (isset($_POST['upload_url'])) {
    $url = trim($_POST['url']);
    
    if (empty($url)) {
        $errors[] = "URL não pode estar vazia.";
    } elseif (!filter_var($url, FILTER_VALIDATE_URL)) {
        $errors[] = "URL inválida.";
    } else {
        // Inicializar cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Para HTTPS sem certificado válido
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; FileUploader/1.0)');
        
        // Headers personalizados (opcional)
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Accept: application/octet-stream, */*'
        ]);
        
        // Executar download
        $file_content = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        $error = curl_error($ch);
        
        curl_close($ch);
        
        if ($error) {
            $errors[] = "Erro 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 {
            // Obter nome do arquivo da URL
            $url_parts = parse_url($url);
            $path_parts = pathinfo($url_parts['path']);
            $original_name = $path_parts['filename'];
            $file_ext = isset($path_parts['extension']) ? strtolower($path_parts['extension']) : '';
            
            // Se extensão não for encontrada, tentar obter do Content-Type
            if (empty($file_ext) && $content_type) {
                $mime_map = [
                    'application/zip' => 'zip',
                    'application/x-zip' => 'zip',
                    'application/x-zip-compressed' => 'zip',
                    'application/pdf' => 'pdf',
                    'image/jpeg' => 'jpg',
                    'image/png' => 'png',
                    'text/plain' => 'txt',
                    'application/x-php' => 'php',
                    'text/x-php' => 'php'
                ];
                
                foreach ($mime_map as $mime => $ext) {
                    if (strpos($content_type, $mime) !== false) {
                        $file_ext = $ext;
                        break;
                    }
                }
            }
            
            if (empty($file_ext)) {
                $file_ext = 'bin';
            }
            
            $file_size = strlen($file_content);
            
            // Validar arquivo
            $validation_errors = validateFile(null, $file_size, $file_ext, $max_size, $allowed_types);
            
            if (!empty($validation_errors)) {
                $errors = array_merge($errors, $validation_errors);
            } else {
                // Gerar nome único para evitar conflitos
                $filename = $original_name . '_' . time() . '.' . $file_ext;
                $temp_file = $temp_dir . $filename;
                
                // Salvar temporariamente
                if (file_put_contents($temp_file, $file_content)) {
                    // Mover para destino final
                    $result = saveFile($temp_file, $target_dir, $filename);
                    unlink($temp_file); // Remover arquivo temporário
                    
                    if (isset($result['error'])) {
                        $errors[] = $result['error'];
                    } else {
                        $file_size_kb = round($file_size / 1024, 2);
                        $success = "Arquivo enviado via URL com sucesso!<br>"
                                 . "Nome: " . htmlspecialchars($filename) . "<br>"
                                 . "Tamanho: " . $file_size_kb . " KB<br>"
                                 . "URL original: " . htmlspecialchars($url) . "<br>"
                                 . "Link: <a href='" . rawurlencode($filename) . "' target='_blank'>Abrir arquivo</a>";
                    }
                } else {
                    $errors[] = "Erro ao salvar arquivo temporário.";
                }
            }
        }
    }
}

// Descompactar ZIP (mantido)
if (isset($_POST['extract_zip'])) {
    $zipFile = basename($_POST['extract_zip']);
    $zipPath = $target_dir . $zipFile;

    if (file_exists($zipPath) && strtolower(pathinfo($zipPath, PATHINFO_EXTENSION)) === 'zip') {
        $zip = new ZipArchive();

        if ($zip->open($zipPath) === TRUE) {
            $extractDir = $target_dir . pathinfo($zipFile, PATHINFO_FILENAME);

            if (!is_dir($extractDir)) {
                mkdir($extractDir, 0755, true);
            }

            $zip->extractTo($extractDir);
            $zip->close();

            $success = "ZIP descompactado com sucesso em: " . htmlspecialchars(basename($extractDir));

        } else {
            $errors[] = "Não foi possível abrir o arquivo ZIP.";
        }
    } else {
        $errors[] = "Arquivo ZIP não encontrado.";
    }
}

// Upload local via formulário (mantido)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['fileToUpload'])) {
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $fileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));

    if (!is_uploaded_file($_FILES["fileToUpload"]["tmp_name"])) {
        $errors[] = "Arquivo inválido.";
    }

    if ($_FILES["fileToUpload"]["size"] > $max_size) {
        $errors[] = "Arquivo muito grande. Máximo: " . ($max_size / 1024 / 1024) . "MB";
    }

    if (!in_array($fileType, $allowed_types)) {
        $errors[] = "Tipo não permitido.";
    }

    if (file_exists($target_file)) {
        $errors[] = "Arquivo já existe.";
    }

    if (empty($errors)) {
        if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
            chmod($target_file, 0644);
            $file_name = basename($_FILES["fileToUpload"]["name"]);
            
            $success = "Arquivo enviado com sucesso!<br>"
                     . "Nome: " . htmlspecialchars($file_name) . "<br>"
                     . "Tamanho: " . round($_FILES["fileToUpload"]["size"] / 1024, 2) . " KB<br>"
                     . "Link: <a href='" . rawurlencode($file_name) . "' target='_blank'>Abrir arquivo</a>";
        } 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>Upload Multi-Fonte com Gerenciador de Arquivos</title>
<style>
body{
    font-family:Arial,sans-serif;
    max-width:1000px;
    margin:auto;
    padding:20px;
    background:#f5f5f5;
}
.container{
    background:white;
    padding:20px;
    border-radius:8px;
    margin-bottom:20px;
    box-shadow:0 2px 4px rgba(0,0,0,0.1);
}
.error{color:#c0392b;background:#ffebee;padding:10px;border-radius:4px; margin-bottom:15px;}
.success{color:#27ae60;background:#e8f5e9;padding:10px;border-radius:4px; margin-bottom:15px;}
.form-group{margin-bottom:15px;}
.form-group label{
    display:block;
    margin-bottom:5px;
    font-weight:bold;
}
input[type="text"], input[type="url"]{
    width:100%;
    padding:8px;
    border:1px solid #ddd;
    border-radius:4px;
    box-sizing:border-box;
}
input[type="file"]{
    padding:8px;
    border:1px solid #ddd;
    border-radius:4px;
    width:100%;
}
input[type="submit"], button{
    background:#007bff;
    color:white;
    border:none;
    padding:8px 16px;
    border-radius:4px;
    cursor:pointer;
    font-size:14px;
}
input[type="submit"]:hover, button:hover{
    background:#0056b3;
}
.zip-item{
    padding:10px;
    border:1px solid #ddd;
    margin-bottom:8px;
    border-radius:4px;
    background:#f9f9f9;
}
.tab-buttons{
    display:flex;
    gap:10px;
    margin-bottom:20px;
    border-bottom:2px solid #ddd;
    padding-bottom:10px;
    flex-wrap: wrap;
}
.tab-button{
    background:#f0f0f0;
    border:none;
    padding:10px 20px;
    cursor:pointer;
    border-radius:4px;
}
.tab-button.active{
    background:#007bff;
    color:white;
}
.tab-content{
    display:none;
}
.tab-content.active{
    display:block;
}
.info-box{
    background:#e3f2fd;
    padding:15px;
    border-radius:4px;
    margin-top:20px;
}
h3{
    margin-top:0;
    color:#333;
}
hr{
    margin:20px 0;
}
/* Estilos do Gerenciador */
.breadcrumb {
    background: #f8f9fa;
    padding: 8px 15px;
    border-radius: 4px;
    margin-bottom: 20px;
    font-size: 14px;
}
.breadcrumb a {
    color: #007bff;
    text-decoration: none;
}
.breadcrumb a:hover {
    text-decoration: underline;
}
.file-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 10px;
}
.file-table th, .file-table td {
    padding: 10px 8px;
    text-align: left;
    border-bottom: 1px solid #eee;
}
.file-table th {
    background: #f2f2f2;
    font-weight: bold;
}
.file-table tr:hover {
    background: #f9f9f9;
}
.action-links a, .copy-form {
    display: inline-block;
    margin-right: 8px;
    font-size: 13px;
}
.copy-form {
    display: inline;
}
.copy-form input[type="text"] {
    width: 150px;
    padding: 4px 6px;
    margin-right: 4px;
    vertical-align: middle;
}
.copy-form button {
    padding: 4px 10px;
    font-size: 12px;
}
.icon {
    margin-right: 6px;
}
</style>
<script>
function showTab(tabId) {
    var tabs = document.getElementsByClassName('tab-content');
    for(var i = 0; i < tabs.length; i++) {
        tabs[i].classList.remove('active');
    }
    var buttons = document.getElementsByClassName('tab-button');
    for(var i = 0; i < buttons.length; i++) {
        buttons[i].classList.remove('active');
    }
    document.getElementById(tabId).classList.add('active');
    event.currentTarget.classList.add('active');
}
// Mostrar/esconder formulário de cópia inline
function toggleCopyForm(filename) {
    var formId = 'copy-form-' + filename.replace(/[^a-zA-Z0-9]/g, '_');
    var form = document.getElementById(formId);
    if (form.style.display === 'none' || form.style.display === '') {
        form.style.display = 'inline';
    } else {
        form.style.display = 'none';
    }
}
</script>
</head>
<body>

<div class="container">
    <h2>Upload Multi-Fonte + Gerenciador</h2>
    
    <?php if (!empty($errors)): ?>
    <div class="error">
        <strong>Erros:</strong>
        <ul>
            <?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-local')">Upload Local</button>
        <button class="tab-button" onclick="showTab('tab-url')">Upload via URL (cURL)</button>
        <button class="tab-button" onclick="showTab('tab-manager')">Gerenciador de Arquivos</button>
    </div>
    
    <!-- Upload Local -->
    <div id="tab-local" class="tab-content active">
        <form method="post" enctype="multipart/form-data">
            <div class="form-group">
                <label>Selecione o arquivo do seu computador:</label>
                <input type="file" name="fileToUpload" required>
            </div>
            <div class="form-group">
                <input type="submit" value="Enviar Arquivo">
            </div>
        </form>
    </div>
    
    <!-- Upload via URL com cURL -->
    <div id="tab-url" class="tab-content">
        <form method="post">
            <div class="form-group">
                <label>URL do arquivo para download:</label>
                <input type="url" name="url" placeholder="https://exemplo.com/arquivo.zip" required>
                <small style="color:#666;">Exemplo: https://www.example.com/documento.pdf</small>
            </div>
            <div class="form-group">
                <input type="submit" name="upload_url" value="Baixar via cURL">
            </div>
        </form>
    </div>
    
    <!-- GERENCIADOR DE ARQUIVOS -->
    <div id="tab-manager" class="tab-content">
        <h3>Gerenciador de Arquivos</h3>
        
        <!-- Breadcrumb -->
        <div class="breadcrumb">
            <a href="?dir=">📁 Raiz</a>
            <?php
            if (!empty($rel_dir)) {
                $parts = explode('/', str_replace('\\', '/', $rel_dir));
                $path_acc = '';
                foreach ($parts as $i => $part) {
                    $path_acc .= ($i == 0 ? '' : '/') . $part;
                    echo ' / <a href="?dir=' . rawurlencode($path_acc) . '">📁 ' . htmlspecialchars($part) . '</a>';
                }
            }
            ?>
        </div>
        
        <!-- Listagem de arquivos e pastas -->
        <table class="file-table">
            <thead>
                <tr>
                    <th>Nome</th>
                    <th>Tamanho</th>
                    <th>Tipo</th>
                    <th>Ações</th>
                </tr>
            </thead>
            <tbody>
            <?php
            // Ler diretório atual
            $items = scandir($current_dir);
            // Ordenar: pastas primeiro, depois arquivos, ambos em ordem alfabética
            $dirs = [];
            $files = [];
            foreach ($items as $item) {
                if ($item === '.' || $item === '..') 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="4">Pasta vazia.</td></tr>';
            }
            
            foreach ($all as $item) {
                $full = $current_dir . $item;
                $is_dir = is_dir($full);
                $icon = $is_dir ? '📁' : '📄';
                $size = $is_dir ? '-' : formatSize(filesize($full));
                $ext = $is_dir ? 'Pasta' : strtoupper(pathinfo($item, PATHINFO_EXTENSION));
                
                echo '<tr>';
                if ($is_dir) {
                    // Link para navegar
                    $new_dir = ($rel_dir ? $rel_dir . '/' : '') . $item;
                    echo '<td><span class="icon">' . $icon . '</span> <a href="?dir=' . rawurlencode($new_dir) . '">' . htmlspecialchars($item) . '</a></td>';
                } else {
                    // Nome simples (ações à parte)
                    echo '<td><span class="icon">' . $icon . '</span> ' . htmlspecialchars($item) . '</td>';
                }
                echo '<td>' . $size . '</td>';
                echo '<td>' . htmlspecialchars($ext) . '</td>';
                
                // Ações
                echo '<td class="action-links">';
                if (!$is_dir) {
                    // Download
                    echo '<a href="?dir=' . rawurlencode($rel_dir) . '&download=' . rawurlencode($item) . '">⬇️ Download</a> ';
                    
                    // Visualizar (apenas se extensão de texto)
                    $text_exts = ['txt','php','html','css','js','log','ini','md','csv','xml','json'];
                    if (in_array(strtolower(pathinfo($item, PATHINFO_EXTENSION)), $text_exts)) {
                        echo '<a href="?dir=' . rawurlencode($rel_dir) . '&view=' . rawurlencode($item) . '" target="_blank">👁️ Ver</a> ';
                    }
                    
                    // Copiar
                    $form_id = 'copy-form-' . preg_replace('/[^a-zA-Z0-9]/', '_', $item);
                    echo '<span style="display:inline-block;">';
                    echo '<a href="javascript:void(0)" onclick="toggleCopyForm(\'' . htmlspecialchars($item, ENT_QUOTES) . '\')">📋 Copiar</a>';
                    echo '<span id="' . $form_id . '" style="display:none; margin-left:5px;">';
                    echo '<form method="post" class="copy-form" action="?dir=' . rawurlencode($rel_dir) . '">';
                    echo '<input type="hidden" name="action" value="copy">';
                    echo '<input type="hidden" name="source" value="' . htmlspecialchars($item) . '">';
                    echo '<input type="text" name="target" placeholder="novo_nome.ext" required>';
                    echo '<button type="submit">✔️</button>';
                    echo '</form>';
                    echo '</span>';
                    echo '</span>';
                } else {
                    echo '—';
                }
                echo '</td>';
                echo '</tr>';
            }
            ?>
            </tbody>
        </table>
    </div>
</div>

<div class="container">
    <h2>Arquivos ZIP Disponíveis (na raiz)</h2>
    
    <?php
    $files = scandir($target_dir);
    $hasZip = false;
    
    foreach ($files as $file) {
        if (
            is_file($target_dir . $file) &&
            strtolower(pathinfo($file, PATHINFO_EXTENSION)) === 'zip'
        ) {
            $hasZip = true;
            echo '<div class="zip-item">';
            echo '<strong>' . htmlspecialchars($file) . '</strong>';
            echo '<form method="post" style="display:inline;margin-left:10px;">';
            echo '<input type="hidden" name="extract_zip" value="' . htmlspecialchars($file) . '">';
            echo '<input type="submit" value="Descompactar">';
            echo '</form>';
            echo '</div>';
        }
    }
    
    if (!$hasZip) {
        echo '<p>Nenhum arquivo ZIP encontrado.</p>';
    }
    ?>
</div>

<div class="container info-box">
    <h3>Informações do Sistema</h3>
    <ul>
        <li><strong>Tamanho máximo:</strong> <?= round($max_size / 1024 / 1024, 2) ?> MB</li>
        <li><strong>Tipos permitidos:</strong> <?= implode(', ', $allowed_types) ?></li>
        <li><strong>Diretório de upload:</strong> <?= htmlspecialchars($target_dir) ?></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>
    </ul>
    
    <h3>Funcionalidades</h3>
    <ul>
        <li>✅ Upload de arquivos do computador</li>
        <li>✅ Download de arquivos via URL com cURL</li>
        <li>✅ Descompactação de arquivos ZIP</li>
        <li>✅ Validação de tipo e tamanho</li>
        <li>✅ Suporte a HTTPS (com verificação SSL opcional)</li>
        <li>✅ Gerenciador de arquivos com navegação, download, visualização e cópia</li>
    </ul>
</div>

</body>
</html>

<?php
// Função auxiliar para formatar tamanho
function formatSize($bytes) {
    $units = ['B', 'KB', 'MB', 'GB'];
    $i = 0;
    while ($bytes >= 1024 && $i < count($units)-1) {
        $bytes /= 1024;
        $i++;
    }
    return round($bytes, 1) . ' ' . $units[$i];
}
?>