<?php
session_start();

// Файл для хранения хеша пароля
$authFile = 'auth_data.json';
$error = '';

// --- 1. ВЫХОД ИЗ СИСТЕМЫ ---
if (isset($_GET['logout'])) {
    session_destroy();
    header("Location: " . strtok($_SERVER["REQUEST_URI"], '?'));
    exit;
}

// Текущие данные пользователя для проверки
$currentIp = $_SERVER['REMOTE_ADDR'] ?? 'unknown_ip';
$currentUa = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown_ua';

// --- 2. УСТАНОВКА ПАРОЛЯ (ПРИ ПЕРВОМ ЗАПУСКЕ) ---
if (!file_exists($authFile)) {
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['new_password'])) {
        $hash = password_hash($_POST['new_password'], PASSWORD_DEFAULT);
        file_put_contents($authFile, json_encode(['hash' => $hash]));
        header("Location: " . $_SERVER['REQUEST_URI']);
        exit;
    }
    
    // Показываем форму установки пароля
    showAuthPage('Создание пароля', 'Придумайте пароль для доступа к вашему коду:', 'new_password', 'Установить пароль');
}

// Загружаем хеш пароля
$authData = json_decode(file_get_contents($authFile), true);
$savedHash = $authData['hash'] ?? '';

// --- 3. ПРОВЕРКА СЕССИИ (IP И USER-AGENT) ---
if (isset($_SESSION['auth']) && $_SESSION['auth'] === true) {
    if ($_SESSION['ip'] !== $currentIp || $_SESSION['ua'] !== $currentUa) {
        // Сессия скомпрометирована (сменился IP или устройство)
        session_destroy();
        header("Location: " . $_SERVER['REQUEST_URI']);
        exit;
    }
} else {
    // --- 4. ОБРАБОТКА ВХОДА ---
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['password'])) {
        if (password_verify($_POST['password'], $savedHash)) {
            $_SESSION['auth'] = true;
            $_SESSION['ip'] = $currentIp;
            $_SESSION['ua'] = $currentUa;
            header("Location: " . $_SERVER['REQUEST_URI']);
            exit;
        } else {
            $error = "Неверный пароль!";
        }
    }
    
    // Показываем форму входа
    showAuthPage('Вход', 'Введите пароль для доступа:', 'password', 'Войти', $error);
}

// Функция для отрисовки страницы входа/регистрации
function showAuthPage($title, $subtitle, $inputName, $btnText, $errorMsg = '') {
    ?>
    <!DOCTYPE html>
    <html lang="ru">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Code Manager - <?php echo $title; ?></title>
        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
        <style>
            body { font-family: 'Inter', sans-serif; background: #0f172a; color: #f8fafc; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
            .auth-box { background: #1e293b; padding: 40px; border-radius: 16px; box-shadow: 0 25px 50px -12px rgba(0,0,0,0.6); border: 1px solid #334155; width: 100%; max-width: 340px; text-align: center; }
            h2 { margin-top: 0; margin-bottom: 10px; }
            p { color: #94a3b8; font-size: 14px; margin-bottom: 25px; }
            input { width: 100%; padding: 14px; border: 1px solid #334155; border-radius: 8px; background: #0f172a; color: white; font-family: 'Inter', sans-serif; font-size: 15px; margin-bottom: 20px; box-sizing: border-box; outline: none; transition: border 0.2s; }
            input:focus { border-color: #818cf8; }
            button { width: 100%; padding: 14px; background: #818cf8; color: #0f172a; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 15px; transition: all 0.2s; }
            button:hover { background: #6366f1; color: white; transform: translateY(-2px); }
            .error { color: #ef4444; font-size: 14px; margin-bottom: 15px; background: rgba(239, 68, 68, 0.1); padding: 10px; border-radius: 6px; }
        </style>
    </head>
    <body>
        <div class="auth-box">
            <h2><?php echo $title; ?></h2>
            <p><?php echo $subtitle; ?></p>
            <?php if ($errorMsg): ?><div class="error"><?php echo $errorMsg; ?></div><?php endif; ?>
            <form method="POST">
                <input type="password" name="<?php echo $inputName; ?>" placeholder="Пароль..." required autofocus>
                <button type="submit"><?php echo $btnText; ?></button>
            </form>
        </div>
    </body>
    </html>
    <?php
    exit;
}

// ======================================================================
// ДАЛЕЕ ИДЕТ ОСНОВНОЙ КОД ПРИЛОЖЕНИЯ
// ======================================================================

$dataFile = 'tabs_data.json';

if (!file_exists($dataFile)) {
    file_put_contents($dataFile, json_encode(['folders' => [], 'tabs' => []]));
}

$data = json_decode(file_get_contents($dataFile), true);
if (!$data) $data = ['folders' => [], 'tabs' => []];

// АВТОМАТИЧЕСКАЯ МИГРАЦИЯ ДАННЫХ
if (!isset($data['folders']) || !isset($data['tabs'])) {
    $oldTabs = $data;
    $data = [
        'folders' => [
            'folder_project' => ['name' => '?? Мой проект', 'parentId' => null, 'created_at' => date('d.m.Y H:i')],
            'folder_default' => ['name' => '?? Исходный код', 'parentId' => 'folder_project', 'created_at' => date('d.m.Y H:i')]
        ],
        'tabs' => []
    ];
    if (is_array($oldTabs)) {
        foreach ($oldTabs as $id => $tab) {
            if (is_array($tab) && isset($tab['name'])) {
                $tab['folderId'] = 'folder_default';
                $data['tabs'][$id] = $tab;
            }
        }
    }
    file_put_contents($dataFile, json_encode($data));
}

// МИГРАЦИЯ: Добавляем время к старым датам, если его нет
$needsSave = false;
if (isset($data['folders'])) {
    foreach ($data['folders'] as $id => &$folder) {
        if (!isset($folder['created_at'])) {
            $folder['created_at'] = date('d.m.Y H:i');
            $needsSave = true;
        } elseif (strlen($folder['created_at']) <= 10) {
            $folder['created_at'] .= ' ' . date('H:i');
            $needsSave = true;
        }
    }
}
if ($needsSave) {
    file_put_contents($dataFile, json_encode($data));
}

// Обработка AJAX-запросов
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = json_decode(file_get_contents('php://input'), true);
    
    if ($input && isset($input['action'])) {
        
        // --- РАБОТА С ВКЛАДКАМИ ---
        if ($input['action'] === 'save_tab') {
            $tabId = $input['id'];
            $data['tabs'][$tabId] = [
                'name' => $input['name'],
                'content' => $input['content'],
                'folderId' => $input['folderId'],
                'last_saved' => date('d.m.Y H:i:s')
            ];
            file_put_contents($dataFile, json_encode($data));
            echo json_encode(['status' => 'success', 'last_saved' => $data['tabs'][$tabId]['last_saved']]);
            exit;
        }
        
        if ($input['action'] === 'delete_tab') {
            $tabId = $input['id'];
            if (isset($data['tabs'][$tabId])) {
                unset($data['tabs'][$tabId]);
                file_put_contents($dataFile, json_encode($data));
            }
            echo json_encode(['status' => 'success']);
            exit;
        }

        if ($input['action'] === 'rename_tab') {
            $tabId = $input['id'];
            if (isset($data['tabs'][$tabId])) {
                $data['tabs'][$tabId]['name'] = $input['name'];
                file_put_contents($dataFile, json_encode($data));
            }
            echo json_encode(['status' => 'success']);
            exit;
        }

        if ($input['action'] === 'duplicate_tab') {
            $sourceId = $input['id'];
            if (isset($data['tabs'][$sourceId])) {
                $tab = $data['tabs'][$sourceId];
                $newTabId = 'tab_' . uniqid(mt_rand(), true);
                $data['tabs'][$newTabId] = [
                    'name' => $tab['name'] . ' (Копия)',
                    'content' => $tab['content'],
                    'folderId' => $tab['folderId'],
                    'last_saved' => date('d.m.Y H:i:s')
                ];
                file_put_contents($dataFile, json_encode($data));
                echo json_encode(['status' => 'success', 'newData' => $data]);
                exit;
            }
        }

        if ($input['action'] === 'reorder_tabs') {
            $newOrder = $input['order'];
            $reorderedTabs = [];
            
            foreach ($newOrder as $tabId) {
                if (isset($data['tabs'][$tabId])) {
                    $reorderedTabs[$tabId] = $data['tabs'][$tabId];
                }
            }
            
            foreach ($data['tabs'] as $tabId => $tab) {
                if (!isset($reorderedTabs[$tabId])) {
                    $reorderedTabs[$tabId] = $tab;
                }
            }
            
            $data['tabs'] = $reorderedTabs;
            file_put_contents($dataFile, json_encode($data));
            echo json_encode(['status' => 'success']);
            exit;
        }

        // МАССОВЫЙ ИМПОРТ ФАЙЛОВ ИЗ ТЕКСТА ИЛИ ФАЙЛОВ
        if ($input['action'] === 'import_tabs') {
            $folderId = $input['folderId'];
            $files = $input['files']; 
            
            if (isset($data['folders'][$folderId])) {
                foreach ($files as $file) {
                    $existingTabId = null;
                    foreach ($data['tabs'] as $tId => $tab) {
                        if ($tab['folderId'] === $folderId && $tab['name'] === $file['name']) {
                            $existingTabId = $tId;
                            break;
                        }
                    }

                    if ($existingTabId !== null) {
                        $data['tabs'][$existingTabId]['content'] = $file['content'];
                        $data['tabs'][$existingTabId]['last_saved'] = date('d.m.Y H:i:s');
                    } else {
                        $newTabId = 'tab_' . uniqid(mt_rand(), true);
                        $data['tabs'][$newTabId] = [
                            'name' => $file['name'],
                            'content' => $file['content'],
                            'folderId' => $folderId,
                            'last_saved' => date('d.m.Y H:i:s')
                        ];
                    }
                }
                file_put_contents($dataFile, json_encode($data));
                echo json_encode(['status' => 'success', 'newData' => $data]);
            } else {
                echo json_encode(['status' => 'error']);
            }
            exit;
        }

        // ОЧИСТКА ВСЕХ ФАЙЛОВ В ПАПКЕ (СОХРАНЯЯ ВКЛАДКИ)
        if ($input['action'] === 'clear_folder_tabs') {
            $folderId = $input['id'];
            
            $targetFolderIds = [$folderId];
            function getSubFoldersClear($fid, &$data, &$targetFolderIds) {
                foreach ($data['folders'] as $cid => $folder) {
                    if (isset($folder['parentId']) && $folder['parentId'] === $fid) {
                        $targetFolderIds[] = $cid;
                        getSubFoldersClear($cid, $data, $targetFolderIds);
                    }
                }
            }
            getSubFoldersClear($folderId, $data, $targetFolderIds);

            foreach ($data['tabs'] as $tId => &$tab) {
                if (in_array($tab['folderId'], $targetFolderIds)) {
                    $tab['content'] = '';
                    $tab['last_saved'] = date('d.m.Y H:i:s');
                }
            }
            
            file_put_contents($dataFile, json_encode($data));
            echo json_encode(['status' => 'success', 'newData' => $data]);
            exit;
        }

        // --- РАБОТА С ПАПКАМИ ---
        if ($input['action'] === 'create_folder') {
            $folderId = $input['id'];
            $data['folders'][$folderId] = [
                'name' => $input['name'],
                'created_at' => date('d.m.Y H:i')
            ];
            if (isset($input['parentId']) && $input['parentId'] !== null) {
                $data['folders'][$folderId]['parentId'] = $input['parentId'];
            }
            file_put_contents($dataFile, json_encode($data));
            echo json_encode(['status' => 'success']);
            exit;
        }

        if ($input['action'] === 'rename_folder') {
            $folderId = $input['id'];
            if (isset($data['folders'][$folderId])) {
                $data['folders'][$folderId]['name'] = $input['name'];
                file_put_contents($dataFile, json_encode($data));
            }
            echo json_encode(['status' => 'success']);
            exit;
        }

        if ($input['action'] === 'move_all_tabs') {
            $sourceId = $input['sourceId'];
            $targetId = $input['targetId'];
            
            if (isset($data['folders'][$targetId])) {
                foreach ($data['tabs'] as $tId => &$tab) {
                    if ($tab['folderId'] === $sourceId) {
                        $tab['folderId'] = $targetId;
                    }
                }
                file_put_contents($dataFile, json_encode($data));
            }
            echo json_encode(['status' => 'success']);
            exit;
        }

        if ($input['action'] === 'duplicate_folder') {
            $sourceId = $input['id'];
            
            function duplicateNode($nodeId, $parentId, &$data, $isRoot = false) {
                if (!isset($data['folders'][$nodeId])) return;
                
                $originalFolder = $data['folders'][$nodeId];
                $newName = $isRoot ? $originalFolder['name'] . ' (Копия)' : $originalFolder['name'];
                $newFolderId = 'folder_' . uniqid(mt_rand(), true);
                
                $data['folders'][$newFolderId] = [
                    'name' => $newName,
                    'parentId' => $parentId,
                    'created_at' => date('d.m.Y H:i')
                ];
                
                $tabsSnapshot = $data['tabs']; 
                foreach ($tabsSnapshot as $tId => $tab) {
                    if ($tab['folderId'] === $nodeId) {
                        $newTabId = 'tab_' . uniqid(mt_rand(), true);
                        $data['tabs'][$newTabId] = [
                            'name' => $tab['name'],
                            'content' => $tab['content'],
                            'folderId' => $newFolderId,
                            'last_saved' => date('d.m.Y H:i:s')
                        ];
                    }
                }
                
                $childrenIds = [];
                foreach ($data['folders'] as $fId => $folder) {
                    if ($fId !== $newFolderId && isset($folder['parentId']) && $folder['parentId'] === $nodeId) {
                        $childrenIds[] = $fId;
                    }
                }
                
                foreach ($childrenIds as $childId) {
                    duplicateNode($childId, $newFolderId, $data, false);
                }
            }

            if (isset($data['folders'][$sourceId])) {
                $originalParent = isset($data['folders'][$sourceId]['parentId']) ? $data['folders'][$sourceId]['parentId'] : null;
                duplicateNode($sourceId, $originalParent, $data, true);
                
                file_put_contents($dataFile, json_encode($data));
                echo json_encode(['status' => 'success', 'newData' => $data]);
            } else {
                echo json_encode(['status' => 'error']);
            }
            exit;
        }

        if ($input['action'] === 'delete_folder') {
            $folderId = $input['id'];
            
            function deleteFolderRec($fid, &$data) {
                if (!isset($data['folders'][$fid])) return;
                
                foreach ($data['folders'] as $childId => $child) {
                    if (isset($child['parentId']) && $child['parentId'] === $fid) {
                        deleteFolderRec($childId, $data);
                    }
                }
                
                foreach ($data['tabs'] as $tId => $tab) {
                    if ($tab['folderId'] === $fid) {
                        unset($data['tabs'][$tId]);
                    }
                }
                
                unset($data['folders'][$fid]);
            }

            deleteFolderRec($folderId, $data);
            
            file_put_contents($dataFile, json_encode($data));
            echo json_encode(['status' => 'success']);
            exit;
        }
    }
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Code Manager Pro - Workspace</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary: #818cf8; 
            --primary-hover: #6366f1;
            --bg-page: #0f172a; 
            --bg-card: #1e293b; 
            --bg-sidebar: #131c2f;
            --text-main: #f8fafc; 
            --text-muted: #94a3b8; 
            --border: #334155; 
            --editor-bg: #0b1120; 
            --editor-text: #e2e8f0; 
            --success: #34d399; 
            --danger: #ef4444;
            --danger-hover: #dc2626;
            --warning: #f59e0b;
        }

        body { 
            font-family: 'Inter', sans-serif; 
            background: var(--bg-page); 
            margin: 0; 
            padding: 30px 20px; 
            min-height: 100vh;
            box-sizing: border-box;
            color: var(--text-main);
            display: flex;
            justify-content: center;
        }

        .workspace { 
            width: 100%;
            max-width: 1500px; 
            background: var(--bg-card); 
            border-radius: 16px; 
            box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.6); 
            overflow: hidden; 
            display: flex;
            flex-direction: row; 
            height: 88vh;
            border: 1px solid var(--border);
        }

        /* --- САЙДБАР --- */
        .sidebar { width: 300px; background: var(--bg-sidebar); border-right: 1px solid var(--border); display: flex; flex-direction: column; flex-shrink: 0; }
        .sidebar-header { padding: 18px 20px; font-weight: 600; color: var(--text-muted); border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; }
        
        .header-actions { display: flex; gap: 6px; }
        .add-folder-btn { background: transparent; color: var(--text-muted); border: none; cursor: pointer; padding: 4px; border-radius: 6px; transition: all 0.2s; display: flex; align-items: center; justify-content: center; text-decoration: none; }
        .add-folder-btn:hover { background: var(--border); color: var(--text-main); }
        
        .folder-list { flex-grow: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 4px; }
        
        .folder-item-container { padding: 8px 12px; border-radius: 8px; cursor: pointer; color: var(--text-muted); transition: all 0.2s; user-select: none; margin-bottom: 2px; display: flex; flex-direction: column; }
        .folder-item-container:hover { background: #1e293b; color: var(--text-main); }
        .folder-item-container.active { background: var(--primary); color: white; box-shadow: 0 4px 10px rgba(99, 102, 241, 0.2); }
        
        .folder-item-content { display: flex; align-items: center; gap: 8px; width: 100%; overflow: hidden; }
        .folder-name-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-grow: 1; font-weight: 500; font-size: 14px; }
        
        /* Счётчики */
        .folder-count { background: #334155; color: var(--text-muted); font-size: 11px; padding: 2px 6px; border-radius: 10px; margin-left: auto; font-weight: 600; flex-shrink: 0; }
        .folder-count.is-subfolder { background: #4f46e5; color: white; }
        .folder-item-container.active .folder-count { background: rgba(255, 255, 255, 0.2); color: white; }
        .folder-item-container.active .folder-count.is-subfolder { background: rgba(255, 255, 255, 0.35); }
        
        /* Мета-данные */
        .folder-meta { font-size: 11px; color: var(--text-muted); opacity: 0.7; margin-left: 26px; margin-top: 4px; display: flex; flex-direction: column; gap: 3px; font-weight: 400; }
        .folder-item-container.active .folder-meta { color: rgba(255, 255, 255, 0.85); opacity: 1; }

        .folder-item-content svg.icon-folder { width: 18px; height: 18px; flex-shrink: 0; }
        
        .chevron { width: 16px; height: 16px; margin-right: 2px; transition: transform 0.2s; cursor: pointer; flex-shrink: 0; opacity: 0.6; }
        .chevron:hover { opacity: 1; color: var(--text-main); }
        .chevron.open { transform: rotate(90deg); }
        .chevron-placeholder { width: 18px; display: inline-block; flex-shrink: 0; }

        /* --- ОСНОВНОЙ КОНТЕНТ --- */
        .main-area { flex-grow: 1; display: flex; flex-direction: column; min-width: 0; }
        
        .tabs-wrapper { display: flex; background: var(--bg-page); border-bottom: 1px solid var(--border); width: 100%; align-items: flex-end; }
        
        .tabs-header { 
            display: flex; padding: 16px 0 0 20px; gap: 8px; overflow-x: auto; flex-grow: 1; scroll-behavior: smooth; 
            scrollbar-width: none; 
            -ms-overflow-style: none;  
        }
        .tabs-header::-webkit-scrollbar { display: none; }
        
        .tabs-actions { padding: 16px 20px 8px 10px; background: var(--bg-page); flex-shrink: 0; display: flex; align-items: center; position: relative; z-index: 15; }
        .tabs-actions::before { content: ''; position: absolute; left: -20px; top: 0; bottom: 0; width: 20px; background: linear-gradient(to right, transparent, var(--bg-page)); pointer-events: none; }

        .tab { background: transparent; color: var(--text-muted); border: none; padding: 12px 28px 12px 20px; border-radius: 10px 10px 0 0; cursor: pointer; font-weight: 500; font-size: 14px; transition: all 0.2s ease; white-space: nowrap; user-select: none; flex-shrink: 0; position: relative; }
        .tab:hover { color: var(--text-main); background: #334155; }
        .tab.active { background: var(--bg-card); color: var(--primary); font-weight: 600; box-shadow: inset 0 3px 0 var(--primary); border-bottom: 2px solid var(--bg-card); margin-bottom: -1px; z-index: 10; }
        .tab.has-data::after { content: ''; position: absolute; top: 10px; right: 12px; width: 6px; height: 6px; background-color: var(--success); border-radius: 50%; box-shadow: 0 0 5px rgba(52, 211, 153, 0.6); }

        .tab.dragging { opacity: 0.4; background: var(--bg-card); }
        .tab.drag-over-left { box-shadow: inset 3px 0 0 0 var(--primary); background: #334155; }
        .tab.drag-over-right { box-shadow: inset -3px 0 0 0 var(--primary); background: #334155; }
        .tab.active.drag-over-left { box-shadow: inset 0 3px 0 var(--primary), inset 3px 0 0 0 var(--primary); }
        .tab.active.drag-over-right { box-shadow: inset 0 3px 0 var(--primary), inset -3px 0 0 0 var(--primary); }
        
        .add-tab-btn { background: var(--primary); color: #0f172a; border: none; width: 42px; height: 42px; border-radius: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; flex-shrink: 0; }
        .add-tab-btn svg { pointer-events: none; }
        .add-tab-btn:hover { background: var(--primary-hover); transform: translateY(-2px); color: white; }

        .tab-content { padding: 24px; display: none; flex-direction: column; flex-grow: 1; height: 100%; min-height: 0; }
        .tab-content.active { display: flex; }
        .toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; background: var(--bg-page); padding: 12px 20px; border-radius: 12px; border: 1px solid var(--border); flex-wrap: wrap; gap: 15px; flex-shrink: 0; }
        .toolbar-group { display: flex; gap: 12px; align-items: center; }
        .btn { padding: 10px 18px; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; transition: all 0.2s; display: flex; align-items: center; gap: 8px; font-family: 'Inter', sans-serif;}
        .btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none !important; }
        .btn-paste { background: #3b82f6; color: white; }
        .btn-paste:hover:not(:disabled) { background: #2563eb; transform: translateY(-2px); }
        .btn-copy { background: #8b5cf6; color: white; }
        .btn-copy:hover:not(:disabled) { background: #7c3aed; transform: translateY(-2px); }
        .btn-cancel { background: transparent; color: var(--text-main); border: 1px solid var(--border); }
        .btn-cancel:hover:not(:disabled) { background: var(--border); }
        .btn-danger { background: var(--danger); color: white; }
        .btn-danger:hover:not(:disabled) { background: var(--danger-hover); transform: translateY(-2px); }
        
        .btn-warning { background: var(--warning); color: #0f172a; }
        .btn-warning:hover:not(:disabled) { background: #d97706; color: white; transform: translateY(-2px); }

        .info-badge { background: var(--bg-card); color: var(--text-muted); padding: 8px 16px; border-radius: 20px; font-size: 13px; font-weight: 500; border: 1px solid var(--border); }
        .save-status { color: var(--success); font-size: 14px; font-weight: 600; opacity: 0; transition: all 0.3s ease; transform: translateY(5px); display: flex; align-items: center; gap: 6px; }
        .save-status.visible { opacity: 1; transform: translateY(0); }

        .editor-container { flex-grow: 1; display: flex; border-radius: 12px; overflow: hidden; border: 1px solid var(--border); background: var(--editor-bg); box-shadow: inset 0 2px 10px rgba(0,0,0,0.2); min-height: 0; }
        .line-numbers { padding: 24px 15px; background: #0d1322; border-right: 1px solid var(--border); color: #475569; text-align: right; font-family: 'Fira Code', monospace; font-size: 15px; line-height: 1.6; user-select: none; overflow: hidden; white-space: pre; min-width: 50px; box-sizing: border-box; flex-shrink: 0; }
        textarea { flex-grow: 1; width: 100%; padding: 24px; border: none; resize: none; font-family: 'Fira Code', monospace; font-size: 15px; line-height: 1.6; outline: none; background: transparent; color: var(--editor-text); white-space: pre; overflow: auto; box-sizing: border-box; }
        ::-webkit-scrollbar { width: 10px; height: 10px; }
        ::-webkit-scrollbar-track { background: var(--bg-page); }
        ::-webkit-scrollbar-thumb { background: #475569; border-radius: 5px; border: 2px solid var(--bg-page); }
        ::-webkit-scrollbar-thumb:hover { background: #64748b; }
        textarea::-webkit-scrollbar-track { background: var(--editor-bg); }
        textarea::-webkit-scrollbar-thumb { background: #334155; border: 2px solid var(--editor-bg); }
        textarea::-webkit-scrollbar-thumb:hover { background: #475569; }

        .empty-state { padding: 80px 40px; text-align: center; color: var(--text-muted); font-size: 16px; display: flex; flex-direction: column; align-items: center; gap: 15px; justify-content: center; height: 100%; }
        .empty-state svg { width: 64px; height: 64px; color: #475569; }

        /* --- КАСТОМНОЕ КОНТЕКСТНОЕ МЕНЮ --- */
        .context-menu { position: absolute; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.8); padding: 6px; display: none; z-index: 2000; min-width: 220px; }
        .context-menu.active { display: flex; flex-direction: column; gap: 2px; }
        .context-menu-item { padding: 10px 14px; border-radius: 6px; cursor: pointer; color: var(--text-main); font-size: 14px; display: flex; align-items: center; gap: 10px; transition: background 0.2s; font-weight: 500; }
        .context-menu-item svg { width: 16px; height: 16px; }
        .context-menu-item:hover { background: var(--bg-page); }
        .context-menu-item.danger { color: var(--danger); }
        .context-menu-item.danger:hover { background: var(--danger); color: white; }
        .context-menu-item.warning { color: var(--warning); }
        .context-menu-item.warning:hover { background: var(--warning); color: #0f172a; }
        .context-divider { height: 1px; background: var(--border); margin: 4px 0; }

        /* Модальные окна */
        .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; visibility: hidden; transition: all 0.2s ease; }
        .modal-overlay.visible { opacity: 1; visibility: visible; }
        .modal { background: var(--bg-card); padding: 24px; border-radius: 16px; width: 100%; max-width: 360px; border: 1px solid var(--border); box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.8); transform: translateY(20px); transition: transform 0.2s ease; display: flex; flex-direction: column; max-height: 90vh; }
        .modal.modal-large { max-width: 700px; } 
        .modal-overlay.visible .modal { transform: translateY(0); }
        .modal h3 { margin: 0 0 16px 0; color: var(--text-main); font-size: 18px; }
        .modal p { color: var(--text-muted); font-size: 14px; margin-bottom: 8px; line-height: 1.5; }
        
        .modal input[type="text"], .modal textarea, .modal select { width: 100%; padding: 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-page); color: var(--text-main); font-family: 'Inter', sans-serif; font-size: 15px; margin-bottom: 20px; box-sizing: border-box; outline: none; }
        .modal input:focus, .modal textarea:focus, .modal select:focus { border-color: var(--primary); }
        .modal select { cursor: pointer; }
        .modal select option { background: var(--bg-page); color: var(--text-main); padding: 8px; }
        .modal textarea { font-family: 'Fira Code', monospace; resize: vertical; min-height: 80px; }

        .modal-buttons { display: flex; justify-content: flex-end; gap: 10px; margin-top: 10px; }
        
        .compile-tags { display: flex; flex-wrap: wrap; gap: 8px; max-height: 120px; overflow-y: auto; padding-right: 5px; margin-bottom: 15px; }
        .compile-tag { background: #334155; color: var(--text-main); font-size: 13px; font-weight: 500; padding: 6px 12px; border-radius: 6px; cursor: pointer; transition: all 0.2s; user-select: none; border: 1px solid var(--border); }
        .compile-tag:hover { background: var(--primary); color: white; border-color: var(--primary); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3); }
        .compile-tags::-webkit-scrollbar { width: 6px; }
        .compile-tags::-webkit-scrollbar-thumb { background: #475569; border-radius: 3px; }

    </style>
</head>
<body>

<div class="workspace">
    <div class="sidebar">
        <div class="sidebar-header">
            <span>Проекты / Папки</span>
            <div class="header-actions">
                <button class="add-folder-btn" title="Создать проект" onclick="openModal('addFolder')">
                    <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
                </button>
                <a href="?logout=1" class="add-folder-btn" title="Выйти (Заблокировать)">
                    <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
                </a>
            </div>
        </div>
        <div class="folder-list" id="folderList" title="ПКМ — меню управления"></div>
    </div>

    <div class="main-area">
        <div class="tabs-wrapper">
            <div class="tabs-header" id="tabsHeader" title="ПКМ — меню управления"></div>
            <div class="tabs-actions" id="tabsActions">
                <button class="add-tab-btn" title="Создать вкладку" onclick="openModal('addTab')">
                    <svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
                </button>
            </div>
        </div>
        <div id="contentArea" style="flex-grow: 1; display: flex; flex-direction: column; min-height: 0;"></div>
    </div>
</div>

<div id="customContextMenu" class="context-menu">
    <div class="context-menu-item" id="ctxAddSubFolder" onclick="triggerAddSubFolderFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>
        Создать подпапку
    </div>
    
    <div class="context-menu-item" id="ctxCompile" onclick="triggerCompileFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/></svg>
        Собрать код (Экспорт)
    </div>
    
    <div class="context-menu-item" id="ctxImport" onclick="triggerImportFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
        Импортировать код
    </div>

    <div class="context-menu-item" id="ctxMoveTabs" onclick="triggerMoveTabsFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"/></svg>
        Перенести файлы
    </div>

    <div class="context-menu-item warning" id="ctxClearTabs" onclick="triggerClearFolderFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M3 12l6.414 6.414a2 2 0 001.414.586H19a2 2 0 002-2V7a2 2 0 00-2-2h-8.172a2 2 0 00-1.414.586L3 12z"/></svg>
        Очистить файлы
    </div>
    
    <div class="context-divider" id="ctxDivider"></div>

    <div class="context-menu-item" onclick="triggerRenameFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/></svg>
        Переименовать
    </div>
    <div class="context-menu-item" onclick="triggerDuplicateFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
        Дублировать
    </div>
    <div class="context-menu-item danger" onclick="triggerDeleteFromMenu()">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
        Удалить
    </div>
</div>

<div id="modalInput" class="modal-overlay">
    <div class="modal">
        <h3 id="modalInputTitle">Действие</h3>
        <input type="text" id="modalInputField" autocomplete="off">
        <div class="modal-buttons">
            <button class="btn btn-cancel" onclick="closeModal('input')">Отмена</button>
            <button class="btn btn-paste" id="modalInputConfirmBtn">Сохранить</button>
        </div>
    </div>
</div>

<div id="modalDelete" class="modal-overlay">
    <div class="modal">
        <h3 id="modalDeleteTitle">Удалить</h3>
        <p id="modalDeleteText">Вы уверены?</p>
        <div class="modal-buttons">
            <button class="btn btn-cancel" onclick="closeModal('delete')">Отмена</button>
            <button class="btn btn-danger" onclick="confirmDelete()">Удалить</button>
        </div>
    </div>
</div>

<div id="modalClearFolder" class="modal-overlay">
    <div class="modal">
        <h3 id="modalClearTitle">Очистка файлов</h3>
        <p id="modalClearText">Вы уверены?</p>
        <div class="modal-buttons">
            <button class="btn btn-cancel" onclick="closeModal('clear')">Отмена</button>
            <button class="btn btn-warning" onclick="confirmClearFolder()">Очистить</button>
        </div>
    </div>
</div>

<div id="modalMoveTabs" class="modal-overlay">
    <div class="modal">
        <h3 id="modalMoveTitle">Перенести файлы</h3>
        <p>Выберите папку, в которую нужно перенести все вкладки:</p>
        <select id="moveTargetFolder"></select>
        <div class="modal-buttons">
            <button class="btn btn-cancel" onclick="closeModal('moveTabs')">Отмена</button>
            <button class="btn btn-paste" onclick="confirmMoveTabs()">Перенести</button>
        </div>
    </div>
</div>

<div id="modalCompile" class="modal-overlay">
    <div class="modal modal-large">
        <h3 id="modalCompileTitle" style="margin-bottom: 5px;">Сборка кода</h3>
        
        <div id="compileStats" style="font-size: 13px; color: var(--text-muted); margin-bottom: 16px; font-family: 'Fira Code', monospace;">
            Файлов: <span id="compileFileCount" style="color: var(--primary); font-weight: 600;">0</span> &nbsp;|&nbsp; 
            Итого строк: <span id="compileLineCount" style="color: var(--primary); font-weight: 600;">0</span>
        </div>
        
        <p>Текст по своему усмотрению (будет добавлен в самый конец):</p>
        <textarea id="compileCustomText" rows="3" placeholder="Напишите ваш текст здесь..."></textarea>
        
        <p style="margin-bottom: 8px;">Файлы в сборке (нажмите для прокрутки к коду):</p>
        <div id="compileTags" class="compile-tags"></div>
        
        <textarea id="compileResult" wrap="off" spellcheck="false" style="height: 300px; background: #0b1120; margin-bottom: 0;" readonly></textarea>
        
        <div class="modal-buttons">
            <button class="btn btn-cancel" onclick="closeModal('compile')">Закрыть</button>
            <button class="btn btn-copy" id="btnCopyCompile" onclick="copyCompiledResult()">Скопировать</button>
        </div>
    </div>
</div>

<div id="modalImport" class="modal-overlay">
    <div class="modal modal-large">
        <h3 id="modalImportTitle">Импорт файлов</h3>
        
        <p style="margin-bottom: 8px; font-weight: 500;">Вариант 1: Выберите файлы с устройства</p>
        <input type="file" id="importFilesInput" multiple style="padding: 10px; cursor: pointer; border: 1px dashed var(--border); background: var(--bg-page); margin-bottom: 15px;">
        
        <p style="margin-bottom: 8px; font-weight: 500;">Вариант 2: Вставьте текст со сборкой</p>
        <textarea id="importText" wrap="off" spellcheck="false" style="height: 220px; background: #0b1120; margin-bottom: 0;" placeholder="Вот мой код file.kt:\n&#34;\n// код здесь\n&#34;"></textarea>
        
        <div id="importStatus" style="color: var(--primary); font-size: 14px; margin-top: 10px; display: none; font-weight: 500;">? Выполняется импорт, подождите...</div>

        <div class="modal-buttons" style="margin-top: 20px;">
            <button class="btn btn-cancel" onclick="closeModal('import')" id="btnCancelImport">Отмена</button>
            <button class="btn btn-paste" id="btnConfirmImport" onclick="confirmImport()">Импортировать</button>
        </div>
    </div>
</div>

<script>
    let appData = <?php echo json_encode($data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); ?>;
    let activeFolderId = null;
    let activeTabId = null;
    let saveTimeout = null;
    let draggedTabId = null; 
    let expandedFolders = new Set(); 
    
    let currentInputMode = null; 
    let currentTarget = null; 

    // Иконки SVG
    const iconFolder = `<svg class="icon-folder" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>`;
    const iconChevron = `<svg class="chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>`;
    const iconPaste = `<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>`;
    const iconCopy = `<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>`;
    const iconCheck = `<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"/></svg>`;

    function isRootFolder(id) {
        return appData.folders[id] && !appData.folders[id].parentId;
    }

    function getCurrentDateTime() {
        const d = new Date();
        const pad = (n) => n.toString().padStart(2, '0');
        return `${pad(d.getDate())}.${pad(d.getMonth()+1)}.${d.getFullYear()} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
    }

    function init() {
        const savedExpanded = localStorage.getItem('expandedFolders');
        if (savedExpanded) {
            JSON.parse(savedExpanded).forEach(id => expandedFolders.add(id));
        }

        const folderIds = Object.keys(appData.folders);
        const savedFolderId = localStorage.getItem('activeFolderId');
        
        if (savedFolderId && appData.folders[savedFolderId]) activeFolderId = savedFolderId;
        else if (folderIds.length > 0) { activeFolderId = folderIds[0]; localStorage.setItem('activeFolderId', activeFolderId); }

        const savedTabId = localStorage.getItem('activeTabId');
        if (savedTabId && appData.tabs[savedTabId] && appData.tabs[savedTabId].folderId === activeFolderId) activeTabId = savedTabId;
        else selectFirstTabInFolder();

        initHorizontalScroll();
        renderSidebar();
        renderTabs();
        renderContent();
    }

    function initHorizontalScroll() {
        const tabsHeader = document.getElementById('tabsHeader');
        tabsHeader.addEventListener('wheel', (e) => {
            if (e.deltaY !== 0) {
                e.preventDefault(); 
                tabsHeader.scrollLeft += (e.deltaY * 1.5); 
            }
        });
    }

    function selectFirstTabInFolder() {
        activeTabId = null;
        for (const [id, tab] of Object.entries(appData.tabs)) {
            if (tab.folderId === activeFolderId) { activeTabId = id; break; }
        }
        if (activeTabId) localStorage.setItem('activeTabId', activeTabId);
        else localStorage.removeItem('activeTabId');
    }

    // --- РЕНДЕР ДЕРЕВА ПАПОК ---
    function renderSidebar() {
        const folderList = document.getElementById('folderList');
        folderList.innerHTML = '';
        
        const selfStats = {};
        for (const [id, tab] of Object.entries(appData.tabs)) {
            const lines = tab.content ? (tab.content === "" ? 0 : tab.content.split('\n').length) : 0;
            if (!selfStats[tab.folderId]) selfStats[tab.folderId] = { files: 0, lines: 0 };
            selfStats[tab.folderId].files++;
            selfStats[tab.folderId].lines += lines;
        }
        
        const tree = { root: [] };
        for (const [id, folder] of Object.entries(appData.folders)) {
            if (!folder.parentId || !appData.folders[folder.parentId]) {
                if(!tree.root) tree.root = [];
                tree.root.push(id);
            } else {
                if(!tree[folder.parentId]) tree[folder.parentId] = [];
                tree[folder.parentId].push(id);
            }
        }

        const totalStats = {};
        function computeStats(folderId) {
            let files = selfStats[folderId] ? selfStats[folderId].files : 0;
            let lines = selfStats[folderId] ? selfStats[folderId].lines : 0;
            let subfolders = 0;
            
            const children = tree[folderId] || [];
            subfolders += children.length; 
            
            for (const child of children) {
                const childStats = computeStats(child);
                files += childStats.files;
                lines += childStats.lines;
                subfolders += childStats.subfolders; 
            }
            totalStats[folderId] = { files, lines, subfolders };
            return totalStats[folderId];
        }
        tree.root.forEach(id => computeStats(id));

        if (tree.root.length === 0) {
            folderList.innerHTML = '<div style="text-align:center; padding:20px; color:#64748b; font-size:13px;">Нет папок.</div>';
            return;
        }

        function drawNode(folderId, depth) {
            const folder = appData.folders[folderId];
            const children = tree[folderId] || [];
            const hasChildren = children.length > 0;
            const isExpanded = expandedFolders.has(folderId);
            const isRoot = depth === 0;
            
            const stats = totalStats[folderId] || {files: 0, lines: 0, subfolders: 0};
            
            const div = document.createElement('div');
            div.className = `folder-item-container ${folderId === activeFolderId ? 'active' : ''}`;
            div.style.paddingLeft = `${12 + depth * 16}px`; 
            
            let chevronHtml = hasChildren 
                ? `<svg class="chevron ${isExpanded ? 'open' : ''}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>` 
                : `<span class="chevron-placeholder"></span>`;
            
            let badgeHtml = '';
            if (isRoot) {
                if (stats.subfolders > 0) {
                    badgeHtml = `<span class="folder-count is-subfolder" title="Количество подпапок">${stats.subfolders}</span>`;
                }
            } else {
                if (stats.files > 0) {
                    badgeHtml = `<span class="folder-count" title="Количество файлов">${stats.files}</span>`;
                }
            }
            
            let metaItems = [];
            if (folder.created_at) {
                metaItems.push(`<span>?? ${folder.created_at}</span>`);
            }
            if (depth > 0 && stats.lines > 0) {
                metaItems.push(`<span style="font-family: 'Fira Code', monospace;">?? Строк: ${stats.lines}</span>`);
            }
            
            let metaHtml = '';
            if (metaItems.length > 0) {
                metaHtml = `<div class="folder-meta">${metaItems.join('')}</div>`;
            }
            
            div.innerHTML = `
                <div class="folder-item-content">
                    ${chevronHtml}
                    ${iconFolder} 
                    <span class="folder-name-text">${folder.name}</span>
                    ${badgeHtml}
                </div>
                ${metaHtml}
            `;
            
            const chevronEl = div.querySelector('.chevron');
            if (chevronEl) {
                chevronEl.addEventListener('click', (e) => {
                    e.stopPropagation(); 
                    if (isExpanded) expandedFolders.delete(folderId);
                    else expandedFolders.add(folderId);
                    
                    localStorage.setItem('expandedFolders', JSON.stringify([...expandedFolders]));
                    renderSidebar();
                });
            }
            
            div.addEventListener('click', () => switchFolder(folderId));
            div.addEventListener('contextmenu', (e) => showContextMenu(e, 'folder', folderId, folder.name));
            
            folderList.appendChild(div);
            
            if (isExpanded && hasChildren) {
                children.forEach(childId => drawNode(childId, depth + 1));
            }
        }

        tree.root.forEach(id => drawNode(id, 0));
    }

    function renderTabs() {
        const header = document.getElementById('tabsHeader');
        const actions = document.getElementById('tabsActions');
        header.innerHTML = '';
        
        if (!activeFolderId) {
            if(actions) actions.style.display = 'none';
            return;
        }

        if (isRootFolder(activeFolderId)) {
            if (actions) actions.style.display = 'none';
        } else {
            if (actions) actions.style.display = 'flex';
        }

        for (const [id, tab] of Object.entries(appData.tabs)) {
            if (tab.folderId !== activeFolderId) continue;
            const btn = document.createElement('button');
            btn.type = 'button';
            btn.className = `tab ${id === activeTabId ? 'active' : ''}`;
            
            if (tab.content && tab.content.trim() !== '') {
                btn.classList.add('has-data');
            }

            btn.innerText = tab.name;
            btn.dataset.id = id;
            
            btn.draggable = true;
            btn.addEventListener('dragstart', handleDragStart);
            btn.addEventListener('dragover', handleDragOver);
            btn.addEventListener('dragleave', handleDragLeave);
            btn.addEventListener('drop', handleDrop);
            btn.addEventListener('dragend', handleDragEnd);

            btn.addEventListener('click', () => switchTab(id));
            btn.addEventListener('contextmenu', (e) => showContextMenu(e, 'tab', id, tab.name));
            header.appendChild(btn);
        }
        
        setTimeout(() => {
            const activeTab = header.querySelector('.tab.active');
            if (activeTab) {
                activeTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
            }
        }, 50);
    }

    // --- ЛОГИКА ПЕРЕТАСКИВАНИЯ (DRAG & DROP) ---
    function handleDragStart(e) { draggedTabId = this.dataset.id; e.dataTransfer.effectAllowed = 'move'; this.classList.add('dragging'); }
    function handleDragOver(e) {
        e.preventDefault(); 
        
        const container = document.getElementById('tabsHeader');
        const containerRect = container.getBoundingClientRect();
        const scrollThreshold = 50; 
        const scrollSpeed = 15;

        if (e.clientX < containerRect.left + scrollThreshold) {
            container.scrollLeft -= scrollSpeed;
        } else if (e.clientX > containerRect.right - scrollThreshold) {
            container.scrollLeft += scrollSpeed;
        }

        if (!draggedTabId || draggedTabId === this.dataset.id) return;
        const rect = this.getBoundingClientRect();
        if (e.clientX < (rect.left + rect.width / 2)) {
            this.classList.add('drag-over-left'); this.classList.remove('drag-over-right');
        } else {
            this.classList.add('drag-over-right'); this.classList.remove('drag-over-left');
        }
    }
    function handleDragLeave(e) { this.classList.remove('drag-over-left', 'drag-over-right'); }
    function handleDragEnd(e) { this.classList.remove('dragging'); document.querySelectorAll('.tab').forEach(t => t.classList.remove('drag-over-left', 'drag-over-right')); }
    function handleDrop(e) {
        e.preventDefault(); this.classList.remove('drag-over-left', 'drag-over-right');
        const targetId = this.dataset.id;
        if (!draggedTabId || draggedTabId === targetId) return;
        const rect = this.getBoundingClientRect();
        reorderTabs(draggedTabId, targetId, e.clientX > (rect.left + rect.width / 2));
        draggedTabId = null;
    }

    function reorderTabs(draggedId, targetId, insertAfter) {
        const tabsArray = Object.entries(appData.tabs);
        let folderTabs = tabsArray.filter(([id, tab]) => tab.folderId === activeFolderId);
        
        const draggedIndex = folderTabs.findIndex(([id]) => id === draggedId);
        if(draggedIndex === -1) return;
        const [draggedItem] = folderTabs.splice(draggedIndex, 1);
        
        const targetIndex = folderTabs.findIndex(([id]) => id === targetId);
        folderTabs.splice(insertAfter ? targetIndex + 1 : targetIndex, 0, draggedItem);
        
        const newTabsObj = {};
        folderTabs.forEach(([id, tab]) => { newTabsObj[id] = tab; });
        tabsArray.forEach(([id, tab]) => { if (tab.folderId !== activeFolderId) newTabsObj[id] = tab; });
        
        appData.tabs = newTabsObj;
        renderTabs(); 
        
        fetch(window.location.href, {
            method: 'POST', headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({ action: 'reorder_tabs', folderId: activeFolderId, order: folderTabs.map(([id]) => id) })
        });
    }

    function renderContent() {
        const contentArea = document.getElementById('contentArea');
        if (!activeFolderId) { contentArea.innerHTML = `<div class="empty-state">${iconFolder}Создайте проект слева.</div>`; return; }
        
        if (isRootFolder(activeFolderId) && (!activeTabId || !appData.tabs[activeTabId] || appData.tabs[activeTabId].folderId !== activeFolderId)) {
            contentArea.innerHTML = `
                <div class="empty-state">
                    ${iconFolder}
                    <b style="font-size: 18px;">Проект: ${appData.folders[activeFolderId].name}</b>
                    <span style="font-size:14px; margin-top:5px; color: var(--text-muted);">
                        Создайте подпапку через меню (ПКМ) для добавления файлов.
                    </span>
                </div>`;
            return;
        }

        if (!activeTabId || !appData.tabs[activeTabId]) { contentArea.innerHTML = `<div class="empty-state">Создайте или выберите вкладку.</div>`; return; }

        const tab = appData.tabs[activeTabId];
        const lastSavedText = tab.last_saved ? `Сохранено: ${tab.last_saved}` : 'Новый файл';
        
        contentArea.innerHTML = `
            <div class="tab-content active">
                <div class="toolbar">
                    <div class="toolbar-group">
                        <button class="btn btn-paste" onclick="pasteCode()">${iconPaste} Вставить</button>
                        <button class="btn btn-copy" onclick="copyCode()">${iconCopy} Копировать</button>
                    </div>
                    <div class="toolbar-group">
                        <span id="saveStatus" class="save-status">${iconCheck} Сохранено</span>
                        <span class="info-badge" id="dateBadge">${lastSavedText}</span>
                        <span class="info-badge">Строк: <span id="lineCount" style="font-weight: 600; color: var(--primary);">0</span></span>
                    </div>
                </div>
                <div class="editor-container">
                    <div class="line-numbers" id="lineNumbers">1</div>
                    <textarea id="codeEditor" wrap="off" spellcheck="false" placeholder="// Вставьте ваш код сюда..."></textarea>
                </div>
            </div>
        `;

        const editor = document.getElementById('codeEditor');
        const lineNums = document.getElementById('lineNumbers');
        editor.value = tab.content;
        
        editor.addEventListener('input', () => { 
            updateLineCount(); 
            triggerAutoSave(); 

            const activeTabEl = document.querySelector('.tab.active');
            if (activeTabEl) {
                if (editor.value.trim() !== '') {
                    activeTabEl.classList.add('has-data');
                } else {
                    activeTabEl.classList.remove('has-data');
                }
            }
        });
        
        editor.addEventListener('scroll', () => { lineNums.scrollTop = editor.scrollTop; });

        updateLineCount();
    }

    function switchFolder(id) {
        if (activeFolderId === id) return;
        activeFolderId = id; localStorage.setItem('activeFolderId', id);
        selectFirstTabInFolder(); renderSidebar(); renderTabs(); renderContent();
    }
    
    function switchTab(id) {
        if (activeTabId === id) return;
        activeTabId = id; localStorage.setItem('activeTabId', id);
        renderTabs(); renderContent();
    }

    // --- КОНТЕКСТНОЕ МЕНЮ ---
    function showContextMenu(e, type, id, name) {
        e.preventDefault();
        currentTarget = { type, id, name };
        const menu = document.getElementById('customContextMenu');
        
        document.getElementById('ctxAddSubFolder').style.display = type === 'folder' ? 'flex' : 'none';
        
        let hasFiles = false;
        if (type === 'folder') {
            let targetFolderIds = [id];
            function getChildFolders(fid) {
                for(let cid in appData.folders) {
                    if(appData.folders[cid].parentId === fid) {
                        targetFolderIds.push(cid);
                        getChildFolders(cid);
                    }
                }
            }
            getChildFolders(id);

            for (const tId in appData.tabs) {
                if (targetFolderIds.includes(appData.tabs[tId].folderId)) {
                    hasFiles = true;
                    break;
                }
            }
        }
        
        document.getElementById('ctxCompile').style.display = (type === 'folder' && hasFiles) ? 'flex' : 'none';
        
        document.getElementById('ctxImport').style.display = (type === 'folder' && !isRootFolder(id)) ? 'flex' : 'none';
        
        let hasFilesStrict = false;
        if (type === 'folder') {
            for (const tId in appData.tabs) {
                if (appData.tabs[tId].folderId === id) {
                    hasFilesStrict = true;
                    break;
                }
            }
        }
        document.getElementById('ctxMoveTabs').style.display = (type === 'folder' && hasFilesStrict) ? 'flex' : 'none';
        document.getElementById('ctxClearTabs').style.display = (type === 'folder' && hasFiles) ? 'flex' : 'none';
        
        document.getElementById('ctxDivider').style.display = type === 'folder' ? 'block' : 'none';

        menu.style.left = `${e.pageX}px`; menu.style.top = `${e.pageY}px`;
        menu.classList.add('active');
    }

    document.addEventListener('click', (e) => {
        const menu = document.getElementById('customContextMenu');
        if (menu.classList.contains('active')) menu.classList.remove('active');
    });

    function triggerAddSubFolderFromMenu() { openModal('addSubFolder', currentTarget); }
    function triggerRenameFromMenu() { if(currentTarget.type === 'folder') openModal('renameFolder', currentTarget); else openModal('renameTab', currentTarget); }
    function triggerDeleteFromMenu() { if(currentTarget.type === 'folder') openModal('deleteFolder', currentTarget); else openModal('deleteTab', currentTarget); }
    
    function triggerClearFolderFromMenu() {
        document.getElementById('modalClearTitle').innerText = 'Очистка файлов';
        document.getElementById('modalClearText').innerHTML = `Вы уверены, что хотите удалить текст из всех файлов в папке <b>"${currentTarget.name}"</b>? <br><br><span style="color:var(--danger)">Сами файлы останутся, но их содержимое будет безвозвратно удалено!</span>`;
        document.getElementById('modalClearFolder').classList.add('visible');
    }

    function confirmClearFolder() {
        const targetId = currentTarget.id;
        
        fetch(window.location.href, { 
            method: 'POST', 
            headers: {'Content-Type': 'application/json'}, 
            body: JSON.stringify({ action: 'clear_folder_tabs', id: targetId }) 
        })
        .then(res => res.json())
        .then(data => {
            if (data.status === 'success') {
                appData = data.newData; 
                closeModal('clear');
                renderSidebar(); 
                renderTabs(); 
                renderContent();
            }
        });
    }

    function triggerDuplicateFromMenu() {
        const targetId = currentTarget.id;
        const action = currentTarget.type === 'folder' ? 'duplicate_folder' : 'duplicate_tab';
        
        fetch(window.location.href, { 
            method: 'POST', 
            headers: {'Content-Type': 'application/json'}, 
            body: JSON.stringify({ action: action, id: targetId }) 
        })
        .then(res => res.json())
        .then(data => {
            if (data.status === 'success') {
                appData = data.newData; 
                if (currentTarget.type === 'folder') {
                    const parentId = appData.folders[targetId]?.parentId;
                    if (parentId) {
                        expandedFolders.add(parentId);
                        localStorage.setItem('expandedFolders', JSON.stringify([...expandedFolders]));
                    }
                }
                renderSidebar(); renderTabs(); renderContent();
            }
        });
    }

    function triggerMoveTabsFromMenu() {
        const sourceId = currentTarget.id;
        const select = document.getElementById('moveTargetFolder');
        select.innerHTML = '';
        
        const tree = { root: [] };
        for (const [id, folder] of Object.entries(appData.folders)) {
            if (!folder.parentId || !appData.folders[folder.parentId]) {
                if(!tree.root) tree.root = [];
                tree.root.push(id);
            } else {
                if(!tree[folder.parentId]) tree[folder.parentId] = [];
                tree[folder.parentId].push(id);
            }
        }

        let hasOptions = false;
        function addOption(folderId, depth) {
            if (folderId !== sourceId && !isRootFolder(folderId)) {
                const folder = appData.folders[folderId];
                const option = document.createElement('option');
                option.value = folderId;
                option.innerHTML = '&nbsp;'.repeat(depth * 4) + '?? ' + folder.name;
                select.appendChild(option);
                hasOptions = true;
            }
            const children = tree[folderId] || [];
            children.forEach(childId => addOption(childId, depth + 1));
        }

        tree.root.forEach(id => addOption(id, 0));

        if (!hasOptions) {
            alert("Нет доступных подпапок для переноса.");
            return;
        }

        document.getElementById('modalMoveTitle').innerText = `Перенос из "${currentTarget.name}"`;
        document.getElementById('modalMoveTabs').classList.add('visible');
    }

    // --- ПАРСИНГ И ИМПОРТ КОДА ---
    function triggerImportFromMenu() {
        document.getElementById('modalImportTitle').innerText = `Импорт файлов в "${currentTarget.name}"`;
        document.getElementById('importText').value = '';
        document.getElementById('importFilesInput').value = '';
        document.getElementById('importStatus').style.display = 'none';
        
        const btnConfirm = document.getElementById('btnConfirmImport');
        const btnCancel = document.getElementById('btnCancelImport');
        btnConfirm.disabled = false;
        btnCancel.disabled = false;
        btnConfirm.innerText = 'Импортировать';
        
        document.getElementById('modalImport').classList.add('visible');
        setTimeout(() => document.getElementById('importText').focus(), 100);
    }

    function parseImportTextSafely(text) {
        const regex = /Вот мой код\s+(.+?):/gi;
        let match;
        const headers = [];
        
        while ((match = regex.exec(text)) !== null) {
            headers.push({ name: match[1].trim(), index: match.index, end: match.index + match[0].length });
        }

        const files = [];
        for (let i = 0; i < headers.length; i++) {
            const current = headers[i];
            const nextIndex = (i + 1 < headers.length) ? headers[i + 1].index : text.length;
            const block = text.substring(current.end, nextIndex);
            
            const firstQuote = block.indexOf('"');
            if (firstQuote === -1) continue;
            
            let lastQuote = -1;
            
            if (i < headers.length - 1) {
                const sepIndex = block.lastIndexOf('====');
                lastQuote = sepIndex !== -1 ? block.lastIndexOf('"', sepIndex) : block.lastIndexOf('"');
            } else {
                const marker = block.indexOf('\n"\n\n\n', firstQuote + 1);
                if (marker !== -1) {
                    lastQuote = marker + 1;
                } else {
                    let cand1 = block.lastIndexOf('\n"\n');
                    let cand2 = block.lastIndexOf('\n"');
                    
                    if (cand1 !== -1 && cand1 > firstQuote) {
                        lastQuote = cand1 + 1;
                    } else if (cand2 !== -1 && cand2 > firstQuote) {
                        lastQuote = cand2 + 1;
                    } else {
                        lastQuote = block.lastIndexOf('"');
                    }
                }
            }
            
            if (firstQuote !== -1 && lastQuote !== -1 && firstQuote < lastQuote) {
                let content = block.substring(firstQuote + 1, lastQuote);
                content = content.replace(/^\r?\n/, '').replace(/\r?\n$/, '');
                files.push({ name: current.name, content: content });
            }
        }
        return files;
    }

    async function confirmImport() {
        const text = document.getElementById('importText').value;
        const filesFromText = parseImportTextSafely(text);
        
        const fileInput = document.getElementById('importFilesInput');
        const uploadedFiles = [];
        
        if (fileInput.files.length > 0) {
            const readPromises = Array.from(fileInput.files).map(file => {
                return new Promise((resolve, reject) => {
                    const reader = new FileReader();
                    reader.onload = e => resolve({ name: file.name, content: e.target.result });
                    reader.onerror = e => reject(e);
                    reader.readAsText(file);
                });
            });
            try {
                const results = await Promise.all(readPromises);
                uploadedFiles.push(...results);
            } catch (e) {
                alert("Ошибка при чтении файлов.");
                return;
            }
        }
        
        const files = [...filesFromText, ...uploadedFiles];
        
        if (files.length === 0) {
            alert("Не удалось найти файлы. Выберите файлы с устройства или вставьте корректный текст со сборкой.");
            return;
        }
        
        const targetFolderId = currentTarget.id;
        
        const btnConfirm = document.getElementById('btnConfirmImport');
        const btnCancel = document.getElementById('btnCancelImport');
        const statusText = document.getElementById('importStatus');
        
        btnConfirm.disabled = true;
        btnCancel.disabled = true;
        btnConfirm.innerText = 'Загрузка...';
        statusText.style.display = 'block';
        statusText.innerText = `? Импорт файлов (${files.length} шт.), подождите...`;
        
        fetch(window.location.href, { 
            method: 'POST', 
            headers: {'Content-Type': 'application/json'}, 
            body: JSON.stringify({ action: 'import_tabs', folderId: targetFolderId, files: files }) 
        })
        .then(res => res.json())
        .then(data => {
            btnConfirm.disabled = false;
            btnCancel.disabled = false;
            btnConfirm.innerText = 'Импортировать';
            statusText.style.display = 'none';

            if (data.status === 'success') {
                appData = data.newData; 
                expandedFolders.add(targetFolderId);
                localStorage.setItem('expandedFolders', JSON.stringify([...expandedFolders]));
                closeModal('import');
                
                activeFolderId = targetFolderId;
                localStorage.setItem('activeFolderId', targetFolderId);
                selectFirstTabInFolder();
                renderSidebar();
                renderTabs();
                renderContent();
            } else {
                alert("Ошибка при сохранении файлов.");
            }
        })
        .catch(err => {
            btnConfirm.disabled = false;
            btnCancel.disabled = false;
            btnConfirm.innerText = 'Импортировать';
            statusText.style.display = 'none';
            alert("Произошла ошибка при отправке запроса.");
        });
    }

    // --- СБОРКА КОДА ---
    function triggerCompileFromMenu() {
        document.getElementById('modalCompileTitle').innerText = `Сборка кода: ${currentTarget.name}`;
        document.getElementById('compileCustomText').value = '';
        updateCompiledResult();
        document.getElementById('modalCompile').classList.add('visible');
        setTimeout(() => document.getElementById('compileCustomText').focus(), 100);
    }

    function updateCompiledResult() {
        const folderId = currentTarget.id;
        let result = '';
        
        let targetFolderIds = [folderId];
        function getChildFolders(fid) {
            for(let cid in appData.folders) {
                if(appData.folders[cid].parentId === fid) {
                    targetFolderIds.push(cid);
                    getChildFolders(cid);
                }
            }
        }
        getChildFolders(folderId);

        let tabs = [];
        for (let tid in appData.tabs) {
            if (targetFolderIds.includes(appData.tabs[tid].folderId)) {
                tabs.push(appData.tabs[tid]);
            }
        }

        const tagsContainer = document.getElementById('compileTags');
        tagsContainer.innerHTML = '';

        tabs.forEach((tab, index) => {
            const headerText = `Вот мой код ${tab.name}:`;
            
            result += `${headerText}\n"\n${tab.content || ''}\n"\n`;
            if (index < tabs.length - 1) { 
                result += `\n================================================\n\n`;
            }

            const tagEl = document.createElement('div');
            tagEl.className = 'compile-tag';
            tagEl.innerText = tab.name;
            tagEl.onclick = () => {
                const textarea = document.getElementById('compileResult');
                const pos = textarea.value.indexOf(headerText);
                if (pos !== -1) {
                    const textBefore = textarea.value.substring(0, pos);
                    const linesBefore = textBefore.split('\n').length;
                    const lineHeight = 24; 
                    
                    textarea.focus();
                    textarea.setSelectionRange(pos, pos + headerText.length);
                    textarea.scrollTop = (linesBefore - 1) * lineHeight;
                }
            };
            tagsContainer.appendChild(tagEl);
        });

        const customText = document.getElementById('compileCustomText').value;
        if (customText.trim() !== '') {
            result += `\n\n${customText}`;
        }

        document.getElementById('compileResult').value = result;
        
        document.getElementById('compileFileCount').innerText = tabs.length;
        document.getElementById('compileLineCount').innerText = result ? result.split('\n').length : 0;
        
        const btn = document.getElementById('btnCopyCompile');
        btn.innerHTML = `${iconCopy} Скопировать`;
        btn.style.background = '';
    }

    document.getElementById('compileCustomText').addEventListener('input', updateCompiledResult);

    async function copyCompiledResult() {
        const text = document.getElementById('compileResult').value;
        try {
            await navigator.clipboard.writeText(text);
            const btn = document.getElementById('btnCopyCompile');
            btn.innerHTML = `${iconCheck} Скопировано`;
            btn.style.background = 'var(--success)';
        } catch (e) {
            alert('Ошибка копирования. Используйте Ctrl+C.');
        }
    }

    // --- МОДАЛЬНЫЕ ОКНА ---
    function openModal(mode, data = null) {
        currentInputMode = mode;
        const inputField = document.getElementById('modalInputField');
        const inputModal = document.getElementById('modalInput');
        
        if (mode === 'addFolder') {
            document.getElementById('modalInputTitle').innerText = 'Новый проект (корневая папка)';
            inputField.value = ''; inputField.placeholder = 'Имя проекта...';
            document.getElementById('modalInputConfirmBtn').innerText = 'Создать';
            inputModal.classList.add('visible');
            setTimeout(() => inputField.focus(), 100);
        } 
        else if (mode === 'addSubFolder') {
            document.getElementById('modalInputTitle').innerText = `Подпапка для "${data.name}"`;
            inputField.value = ''; inputField.placeholder = 'Имя подпапки...';
            document.getElementById('modalInputConfirmBtn').innerText = 'Создать';
            inputModal.classList.add('visible');
            setTimeout(() => inputField.focus(), 100);
        }
        else if (mode === 'addTab') {
            document.getElementById('modalInputTitle').innerText = 'Новая вкладка';
            inputField.value = ''; inputField.placeholder = 'Имя файла...';
            document.getElementById('modalInputConfirmBtn').innerText = 'Создать';
            inputModal.classList.add('visible');
            setTimeout(() => inputField.focus(), 100);
        }
        else if (mode === 'renameFolder' || mode === 'renameTab') {
            document.getElementById('modalInputTitle').innerText = 'Переименовать';
            inputField.value = data.name;
            document.getElementById('modalInputConfirmBtn').innerText = 'Сохранить';
            inputModal.classList.add('visible');
            setTimeout(() => { inputField.focus(); inputField.select(); }, 100);
        }
        else if (mode === 'deleteFolder') {
            currentTarget = data;
            document.getElementById('modalDeleteTitle').innerText = 'Удаление папки';
            document.getElementById('modalDeleteText').innerHTML = `Удалить папку <b>"${data.name}"</b>? <br><br><span style="color:var(--danger)">Все подпапки и вкладки внутри будут удалены навсегда!</span>`;
            document.getElementById('modalDelete').classList.add('visible');
        }
        else if (mode === 'deleteTab') {
            currentTarget = data;
            document.getElementById('modalDeleteTitle').innerText = 'Удаление вкладки';
            document.getElementById('modalDeleteText').innerHTML = `Удалить вкладку <b>"${data.name}"</b>?`;
            document.getElementById('modalDelete').classList.add('visible');
        }
    }

    function closeModal(type) {
        if (type === 'input') document.getElementById('modalInput').classList.remove('visible');
        if (type === 'delete') document.getElementById('modalDelete').classList.remove('visible');
        if (type === 'moveTabs') document.getElementById('modalMoveTabs').classList.remove('visible');
        if (type === 'compile') document.getElementById('modalCompile').classList.remove('visible');
        if (type === 'import') document.getElementById('modalImport').classList.remove('visible');
        if (type === 'clear') document.getElementById('modalClearFolder').classList.remove('visible');
    }

    document.getElementById('modalInputConfirmBtn').addEventListener('click', confirmInput);
    document.getElementById('modalInputField').addEventListener('keypress', function(e) { if (e.key === 'Enter') confirmInput(); });

    function confirmInput() {
        let name = document.getElementById('modalInputField').value.trim();
        if (name === "") return; 
        closeModal('input');

        const today = getCurrentDateTime();

        if (currentInputMode === 'addFolder') {
            const newId = 'folder_' + Date.now();
            appData.folders[newId] = { name: name, parentId: null, created_at: today };
            activeFolderId = newId; localStorage.setItem('activeFolderId', newId);
            selectFirstTabInFolder();
            fetch(window.location.href, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ action: 'create_folder', id: newId, name: name }) });
        } 
        else if (currentInputMode === 'addSubFolder') {
            const newId = 'folder_' + Date.now();
            const parentId = currentTarget.id;
            appData.folders[newId] = { name: name, parentId: parentId, created_at: today };
            
            expandedFolders.add(parentId);
            localStorage.setItem('expandedFolders', JSON.stringify([...expandedFolders]));
            
            activeFolderId = newId; localStorage.setItem('activeFolderId', newId);
            selectFirstTabInFolder();
            fetch(window.location.href, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ action: 'create_folder', id: newId, name: name, parentId: parentId }) });
        }
        else if (currentInputMode === 'addTab') {
            const newId = 'tab_' + Date.now();
            appData.tabs[newId] = { name: name, content: '', folderId: activeFolderId, last_saved: null };
            activeTabId = newId; localStorage.setItem('activeTabId', newId);
            saveData(newId);
        }
        else if (currentInputMode === 'renameFolder') {
            if (name !== currentTarget.name) {
                appData.folders[currentTarget.id].name = name;
                fetch(window.location.href, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ action: 'rename_folder', id: currentTarget.id, name: name }) });
            }
        }
        else if (currentInputMode === 'renameTab') {
            if (name !== currentTarget.name) {
                appData.tabs[currentTarget.id].name = name;
                fetch(window.location.href, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ action: 'rename_tab', id: currentTarget.id, name: name }) });
            }
        }

        renderSidebar(); renderTabs(); renderContent();
    }

    function confirmMoveTabs() {
        const sourceId = currentTarget.id;
        const targetId = document.getElementById('moveTargetFolder').value;
        
        if (!targetId) return;

        let moved = false;
        for (const tId in appData.tabs) {
            if (appData.tabs[tId].folderId === sourceId) {
                appData.tabs[tId].folderId = targetId;
                moved = true;
            }
        }

        closeModal('moveTabs');
        
        if (moved) {
            fetch(window.location.href, { 
                method: 'POST', 
                headers: {'Content-Type': 'application/json'}, 
                body: JSON.stringify({ action: 'move_all_tabs', sourceId: sourceId, targetId: targetId }) 
            });
            switchFolder(targetId);
        }
    }

    function deleteFolderRecursivelyClient(fid) {
        if (!appData.folders[fid]) return;
        for (const childId in appData.folders) {
            if (appData.folders[childId].parentId === fid) {
                deleteFolderRecursivelyClient(childId);
            }
        }
        for (const tId in appData.tabs) {
            if (appData.tabs[tId].folderId === fid) {
                delete appData.tabs[tId];
            }
        }
        delete appData.folders[fid];
        expandedFolders.delete(fid);
    }

    function confirmDelete() {
        const targetId = currentTarget.id;
        
        if (currentTarget.type === 'folder') {
            deleteFolderRecursivelyClient(targetId);
            localStorage.setItem('expandedFolders', JSON.stringify([...expandedFolders]));

            if (!appData.folders[activeFolderId]) {
                const remaining = Object.keys(appData.folders);
                activeFolderId = remaining.length > 0 ? remaining[0] : null;
                if(activeFolderId) localStorage.setItem('activeFolderId', activeFolderId); else localStorage.removeItem('activeFolderId');
                selectFirstTabInFolder();
            }
            
            fetch(window.location.href, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ action: 'delete_folder', id: targetId }) });
        } 
        else if (currentTarget.type === 'tab') {
            delete appData.tabs[targetId];
            if (activeTabId === targetId) selectFirstTabInFolder();
            fetch(window.location.href, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ action: 'delete_tab', id: targetId }) });
        }

        closeModal('delete'); renderSidebar(); renderTabs(); renderContent();
    }

    document.getElementById('modalInput').addEventListener('click', function(e) { if (e.target === this) closeModal('input'); });
    document.getElementById('modalDelete').addEventListener('click', function(e) { if (e.target === this) closeModal('delete'); });
    document.getElementById('modalMoveTabs').addEventListener('click', function(e) { if (e.target === this) closeModal('moveTabs'); });
    document.getElementById('modalCompile').addEventListener('click', function(e) { if (e.target === this) closeModal('compile'); });
    document.getElementById('modalImport').addEventListener('click', function(e) { if (e.target === this) closeModal('import'); });
    document.getElementById('modalClearFolder').addEventListener('click', function(e) { if (e.target === this) closeModal('clear'); });

    // --- ФУНКЦИИ РЕДАКТОРА ---
    function updateLineCount() {
        const editor = document.getElementById('codeEditor');
        const lineNums = document.getElementById('lineNumbers');
        if (!editor) return;
        const text = editor.value;
        const lines = text === "" ? 0 : text.split('\n').length;
        document.getElementById('lineCount').innerText = lines;
        if (lineNums) {
            const displayLines = lines === 0 ? 1 : lines;
            lineNums.innerText = Array.from({length: displayLines}, (_, i) => i + 1).join('\n');
        }
    }

    async function pasteCode() {
        try { document.getElementById('codeEditor').value = await navigator.clipboard.readText(); updateLineCount(); saveData(activeTabId); } 
        catch (err) { alert('Используйте Ctrl+V (или Cmd+V). Автосохранение сработает мгновенно.'); }
    }

    async function copyCode() {
        try {
            await navigator.clipboard.writeText(document.getElementById('codeEditor').value);
            const btn = document.querySelector('.btn-copy'); const originalHTML = btn.innerHTML;
            btn.innerHTML = `${iconCheck} Скопировано`; btn.style.background = 'var(--success)';
            setTimeout(() => { btn.innerHTML = originalHTML; btn.style.background = ''; }, 2000);
        } catch (err) { alert('Используйте Ctrl+C (или Cmd+C).'); }
    }

    function triggerAutoSave() { clearTimeout(saveTimeout); saveTimeout = setTimeout(() => { saveData(activeTabId); }, 1000); }

    function saveData(tabIdToSave) {
        if (!tabIdToSave || !appData.tabs[tabIdToSave]) return;
        const editor = document.getElementById('codeEditor');
        const content = editor ? editor.value : appData.tabs[tabIdToSave].content;
        const tab = appData.tabs[tabIdToSave];

        fetch(window.location.href, {
            method: 'POST', headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: 'save_tab', id: tabIdToSave, name: tab.name, content: content, folderId: tab.folderId })
        }).then(res => res.json()).then(data => {
            if (data.status === 'success') {
                appData.tabs[tabIdToSave].content = content; appData.tabs[tabIdToSave].last_saved = data.last_saved;
                if (tabIdToSave === activeTabId) {
                    const badge = document.getElementById('dateBadge');
                    if(badge) badge.innerText = `Сохранено: ${data.last_saved}`;
                    const statusEl = document.getElementById('saveStatus');
                    statusEl.classList.add('visible'); setTimeout(() => statusEl.classList.remove('visible'), 2000);
                    renderSidebar(); 
                }
            }
        });
    }

    init();
</script>
</body>
</html>
