import os
import sys
from flask import Flask, render_template_string, send_from_directory, abort, jsonify, request, redirect, url_for 

# --------------------------------------------------------------------------------------
# 1. SETUP & CONFIGURATION (კონფიგურაცია)
# --------------------------------------------------------------------------------------

# BASE_DIR: დირექტორია, რომლის დათვალიერებაც გვსურს.
# ის დაყენებულია იმ ფოლდერზე, სადაც app.py გაშვებულია.
BASE_DIR = os.path.abspath(os.path.dirname(__file__))

# Flask აპლიკაციის ინიციალიზაცია
app = Flask(__name__)

# --------------------------------------------------------------------------------------
# 2. EMBEDDED HTML/JINJA2 TEMPLATE (UI/UX)
# --------------------------------------------------------------------------------------

# ვიყენებთ ერთ ჩაშენებულ Jinja2 შაბლონს.
# Tailwind CSS CDN გამოიყენება ლამაზი, მინიმალისტური და რესპონსული დიზაინისთვის.
HTML_TEMPLATE = """
<!doctype html>
<html lang="ka">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ფაილების მინიმალისტური ბრაუზერი</title>
    <!-- Tailwind CSS CDN -->
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');
        body {
            font-family: 'Inter', sans-serif;
            background-color: #f7f7f9;
        }
        /* ეს წესები ახლა ძირითადად გამოიყენება ფერების განსაზღვრისთვის, მაგრამ SVG-ებში fill პირდაპირაა მითითებული */
        .icon-file { color: #3b82f6; } /* ლურჯი ფაილებისთვის */
        .icon-folder { color: #fbbf24; } /* ყვითელი ფოლდერებისთვის */
        
        /* Sidebar Styling */
        #file-tree-sidebar {
            width: 300px;
            min-width: 300px;
            max-width: 100%;
            height: 100vh;
            overflow-y: auto;
            position: fixed;
            top: 0;
            left: 0;
            z-index: 10;
        }

        /* Main Content Styling */
        #main-content-container {
            margin-left: 300px; /* Offset for the fixed sidebar */
            min-height: 100vh;
        }

        /* Tree View Styling */
        .tree-node {
            padding: 4px 8px; /* გაზრდილი padding */
            margin-left: 0;
            font-size: 0.9rem;
            cursor: pointer;
            display: flex;
            align-items: center;
            transition: background-color 0.1s;
            border-radius: 4px;
        }
        .tree-node:hover:not(.active) {
            background-color: #e5e7eb; /* Gray-200 */
        }
        .tree-node.active {
            background-color: #bfdbfe; /* Blue-200 for active path */
            font-weight: 600;
        }
        
        /* Style for the SVG toggle icon (ხატულის სტილი) */
        .toggle-icon {
            margin-right: 5px;
            transition: transform 0.2s;
            min-width: 12px; 
            flex-shrink: 0; 
        }
        .toggle-icon.expanded {
            transform: rotate(90deg); /* Rotate for "expanded" state (წამომართული) */
        }
        .toggle-icon.hidden {
            visibility: hidden; /* Hide for leaf nodes (ცარიელი ფოლდერები) */
        }
        /* Adjust spacing for nodes without visible icon */
        .tree-node > .toggle-icon.hidden + .icon-folder {
            margin-left: 17px; /* Compensate for the hidden icon's space */
        }

        /* Responsive adjustments for mobile */
        @media (max-width: 768px) {
            #file-tree-sidebar {
                width: 100%;
                height: auto;
                position: static;
                border-bottom: 1px solid #ddd;
                overflow: hidden;
            }
            #main-content-container {
                margin-left: 0;
                padding-top: 1rem;
            }
            .mobile-hide {
                display: none;
            }
        }
    </style>
</head>
<body class="bg-gray-50 text-gray-800 antialiased">

    <!-- 1. Collapsible Tree Sidebar (ჩამკეცი ხის ნავიგაცია) -->
    <aside id="file-tree-sidebar" class="bg-white border-r border-gray-200 p-4 shadow-xl hidden md:block">
        <h2 class="text-xl font-bold text-gray-700 mb-4 flex items-center">
            <!-- FIX: viewBox (CamelCase) and fixed fill color -->
            <svg class="w-6 h-6 mr-2 icon-folder" fill="#fbbf24" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"></path></svg>
            ნავიგაცია
        </h2>
        <div id="tree-root" class="text-gray-700 text-sm">
            <!-- Root Folder (ძირითადი ფოლდერი) -->
            <div id="root-node" 
                 data-path="" 
                 data-name="{{ base_dir_name }}"
                 class="tree-node p-2 ml-0" 
                 style="font-size: 1rem;">
                
                <!-- Toggle Icon (ბულეტის ხატულა) - FIX: Fixed fill color and viewBox -->
                <svg id="root-toggle-icon" class="toggle-icon w-3 h-3" fill="#1f2937" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
                    <path d="M3 5l7 7-7 7V5z"></path>
                </svg>
                
                <!-- Folder Icon - FIX: Fixed fill color and viewBox -->
                <svg class="w-5 h-5 mr-2 icon-folder flex-shrink-0" fill="#fbbf24" viewBox="0 0 20 20"><path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"></path></svg>
                
                <a href="/" class="flex-grow truncate">{{ base_dir_name }} (Root)</a>
            </div>
            <!-- Child Container for Root -->
            <ul id="tree-children-root" data-path="" class="pl-2"></ul>
        </div>
    </aside>

    <!-- 2. Main Content Area (მთავარი შიგთავსი) -->
    <div id="main-content-container" class="p-4 sm:p-8">

        <!-- Display the current path in a subtle way, for context (მიმდინარე ბილიკი) -->
        <div class="mb-4 text-sm text-gray-500">
            მიმდინარე ბილიკი: 
            <span id="current-path-display" class="font-mono text-blue-600">{{ base_dir_name }}/{{ current_path or '' }}</span>
        </div>

        <!-- Search Bar (საძიებო ველი) -->
        <div class="mb-8 relative">
            <input type="text" id="file-search-input" placeholder="🔍 გლობალური ძიება ყველა საქაღალდეში..." 
                   class="w-full p-4 text-lg border-2 border-blue-200 rounded-xl focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition duration-150 shadow-lg">
            <div id="search-loading-indicator" class="absolute right-4 top-1/2 transform -translate-y-1/2 hidden">
                <!-- SVG Loader (სიმარტივისთვის) -->
                <svg class="animate-spin h-5 w-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
            </div>
        </div>
        <!-- End Search Bar -->

        {% if error %}
            <!-- შეცდომის შეტყობინება -->
            <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-xl mb-6 shadow-md" role="alert">
                <p class="font-bold">შეცდომა:</p>
                <p class="text-sm">{{ error }}</p>
            </div>
        {% endif %}

        <!-- Content Containers -->
        <div id="content-display" class="bg-white rounded-xl shadow-xl overflow-hidden">
            
            <!-- Jinja2 Macro ფაილების სიის რენდერისთვის -->
            {% macro render_list(items, is_search=False) %}
                {% if items %}
                    <ul class="divide-y divide-gray-100">
                    {% for item in items %}
                        <li class="p-4 file-list-item flex justify-between items-center hover:bg-gray-50" data-name="{{ item.name }}">
                            {% if item.is_dir %}
                                <!-- ფოლდერის ლინკი (შემდეგ დონეზე გადასვლა) -->
                                <a href="/{{ item.path }}" class="flex items-center flex-grow text-gray-700 font-semibold min-w-0">
                                    <!-- FIX: Fixed fill color and viewBox -->
                                    <svg class="w-6 h-6 mr-3 icon-folder flex-shrink-0" fill="#fbbf24" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"></path></svg>
                                    <span class="truncate">{{ item.name }}</span>
                                    {% if is_search %}
                                        <!-- ბილიკის ჩვენება ძიებისას -->
                                        <span class="ml-4 text-xs text-gray-400 font-mono hidden sm:inline-block truncate">
                                            ({{ item.path | replace(item.name, '') | trim("/") }})
                                        </span>
                                    {% endif %}
                                </a>
                                <span class="text-xs text-gray-400 font-medium ml-4 flex-shrink-0">დირექტორია</span>
                            {% else %}
                                <!-- ფაილის ინფორმაცია და გადმოწერის ღილაკი -->
                                <div class="flex items-center flex-grow min-w-0"> <!-- Add min-w-0 to allow shrinking -->
                                    <!-- FIX: Fixed fill color and viewBox -->
                                    <svg class="w-6 h-6 mr-3 icon-file flex-shrink-0" fill="#3b82f6" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 2a1 1 0 000 2h8a1 1 0 000-2H6z" clip-rule="evenodd"></path></svg>
                                    
                                    <div class="flex flex-col flex-grow min-w-0"> <!-- Flex column for name and path/size details -->
                                        <span class="text-gray-600 font-semibold truncate">{{ item.name }}</span> <!-- Add truncate here -->
                                        {% if is_search %}
                                            <!-- ბილიკის ჩვენება ძიებისას -->
                                            <span class="text-xs text-gray-400 font-mono mt-0.5 truncate">
                                                ({{ item.path | replace(item.name, '') | trim("/") }})
                                            </span>
                                        {% else %}
                                            <!-- ფაილის ზომის ჩვენება მობილურზე (ძიების გარეშე) -->
                                            <span class="text-xs text-gray-400 font-mono mt-0.5 md:hidden">
                                                {{ "{:,.2f}".format(item.size / (1024 * 1024)) | replace(",", " ") }} MB
                                            </span>
                                        {% endif %}
                                    </div>
                                </div>
                                
                                <!-- Action block (Size on desktop, Download button always visible) -->
                                <div class="flex items-center flex-shrink-0">
                                    <!-- ფაილის ზომა დესკტოპზე -->
                                    <span class="text-xs text-gray-400 font-mono ml-4 hidden md:inline-block">
                                        {{ "{:,.2f}".format(item.size / (1024 * 1024)) | replace(",", " ") }} MB
                                    </span>
                                    <a href="/download/{{ item.path }}" class="ml-4 bg-blue-500 hover:bg-blue-600 text-white text-xs font-semibold py-1 px-3 rounded-full transition duration-150 shadow-md flex items-center flex-shrink-0">
                                        <!-- FIX: viewBox (CamelCase) -->
                                        <svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><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"></path></svg>
                                        გადმოწერა
                                    </a>
                                </div>
                            {% endif %}
                        </li>
                    {% endfor %}
                    </ul>
                {% else %}
                    <!-- ცარიელი შედეგის შეტყობინება -->
                    <div class="p-8 text-center text-gray-500">
                        <p class="text-xl font-semibold" id="empty-message-title">ფაილები არ მოიძებნა</p>
                        <p class="mt-2 text-sm" id="empty-message-details">დირექტორია <code class="bg-gray-100 p-1 rounded text-blue-500">{{ current_path or base_dir_name }}</code> ცარიელია ან მიუწვდომელია.</p>
                    </div>
                {% endif %}
            {% endmacro %}
            
            <!-- 2.1. Current Directory View (ნორმალური ხედი) -->
            <div id="current-directory-view">
                {{ render_list(files_and_folders) }}
            </div>

            <!-- 2.2. Global Search Results View (ძიების შედეგების ხედი) - Initially hidden -->
            <div id="search-results-view" class="hidden">
                <!-- Search results will be injected here by JavaScript -->
            </div>

        </div>

        <footer class="mt-12 text-center text-gray-400 text-sm">
            <p>შექმნილია Python Flask-ით</p>
        </footer>
    </div>

    <script>
        // JavaScript for the dynamic, expandable file tree (დინამიური ხის სტრუქტურა)
        const BASE_DIR_NAME = '{{ base_dir_name }}';
        const TREE_ROOT = document.getElementById('tree-root');
        const SEARCH_INPUT = document.getElementById('file-search-input');
        const CURRENT_DIR_VIEW = document.getElementById('current-directory-view');
        const SEARCH_RESULTS_VIEW = document.getElementById('search-results-view');
        const LOADING_INDICATOR = document.getElementById('search-loading-indicator');
        const CURRENT_PATH_DISPLAY = document.getElementById('current-path-display');
        
        // CURRENT_PATH: Array of segments (მიმდინარე ბილიკის სეგმენტები)
        const CURRENT_PATH = '{{ current_path }}'.split('/').filter(p => p.length > 0);
        
        // API URLs
        const API_URL_STRUCTURE = '/api/structure'; 
        const API_URL_SEARCH = '/api/search'; 
        
        // Debounce timer for search
        let searchTimer;

        // -------------------------------------------------------------------------
        // 1. DATA FETCHING (მონაცემების მოტანა)
        // -------------------------------------------------------------------------

        async function fetchDirectoryStructure(path) {
            try {
                const url = path ? `${API_URL_STRUCTURE}/${path}` : API_URL_STRUCTURE + '/';
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(`Failed to fetch: ${response.statusText}`);
                }
                return await response.json();
            } catch (error) {
                console.error("Error loading directory structure:", error);
                return [];
            }
        }

        // -------------------------------------------------------------------------
        // 2. TREE VIEW LOGIC (ხის ნავიგაციის ლოგიკა)
        // -------------------------------------------------------------------------

        function toggleExpansion(event, nodeDiv, childUl) {
            event.stopPropagation();
            
            const path = nodeDiv.dataset.path;
            const toggleIcon = nodeDiv.querySelector('.toggle-icon');

            if (toggleIcon.classList.contains('hidden')) {
                return;
            }

            if (childUl.classList.contains('hidden')) {
                childUl.classList.remove('hidden');
                toggleIcon.classList.add('expanded');
                if (childUl.dataset.loaded !== 'true') {
                    if (!nodeDiv.dataset.loading) {
                        nodeDiv.dataset.loading = 'true';
                        loadAndRenderChildren(path, childUl).finally(() => {
                            nodeDiv.dataset.loading = 'false';
                        });
                    }
                }
            } else {
                childUl.classList.add('hidden');
                toggleIcon.classList.remove('expanded');
            }
        }

        async function loadAndRenderChildren(path, parentUlElement) {
            if (parentUlElement.dataset.loaded === 'true') {
                return;
            }
            
            parentUlElement.innerHTML = '';
            
            const data = await fetchDirectoryStructure(path);
            const folders = data.filter(item => item.is_dir);
            
            const parentNode = parentUlElement.previousElementSibling;
            if (folders.length === 0) {
                if (parentNode && parentNode.classList.contains('tree-node')) {
                     parentNode.querySelector('.toggle-icon')?.classList.add('hidden');
                }
                return; 
            }
            parentUlElement.dataset.loaded = 'true';

            if (parentNode) {
                 parentNode.querySelector('.toggle-icon')?.classList.remove('hidden');
            }

            folders.forEach(item => {
                const li = document.createElement('li');
                li.classList.add('relative');
                
                const nodeDiv = document.createElement('div');
                nodeDiv.classList.add('tree-node');
                
                const depth = item.path.split('/').filter(p => p.length > 0).length;
                nodeDiv.style.paddingLeft = `${depth * 10 + 8}px`; 
                nodeDiv.dataset.path = item.path;
                nodeDiv.dataset.name = item.name;
                
                // FIX 1: Use createElementNS for SVG and explicitly set fill color for triangle (toggle)
                const toggleIcon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                toggleIcon.classList.add('toggle-icon', 'w-3', 'h-3');
                toggleIcon.setAttribute('fill', '#1f2937'); // Fixed color
                toggleIcon.setAttribute('viewBox', '0 0 20 20'); // Correct casing
                toggleIcon.innerHTML = '<path d="M3 5l7 7-7 7V5z"></path>';
                
                // FIX 2: Use createElementNS for SVG and explicitly set fill color for folder icon
                const folderIcon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                folderIcon.classList.add('w-5', 'h-5', 'mr-2', 'icon-folder', 'flex-shrink-0');
                folderIcon.setAttribute('fill', '#fbbf24'); // Fixed yellow color
                folderIcon.setAttribute('viewBox', '0 0 20 20'); // Correct casing
                folderIcon.innerHTML = '<path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"></path>';

                const link = document.createElement('a');
                link.textContent = item.name;
                link.href = '/' + item.path;
                link.classList.add('flex-grow', 'truncate');
                
                nodeDiv.appendChild(toggleIcon);
                nodeDiv.appendChild(folderIcon);
                nodeDiv.appendChild(link);
                
                const childUl = document.createElement('ul');
                childUl.classList.add('pl-2', 'hidden');
                
                const currentPathStr = CURRENT_PATH.join('/');
                const isAncestor = currentPathStr.startsWith(item.path + '/');
                const isActive = currentPathStr === item.path;
                
                if (isActive) {
                    nodeDiv.classList.add('active');
                }
                
                if (isAncestor || isActive) {
                    toggleIcon.classList.add('expanded');
                    childUl.classList.remove('hidden');
                    
                    if (isAncestor) {
                         loadAndRenderChildren(item.path, childUl);
                    } else if (isActive) {
                         loadAndRenderChildren(item.path, childUl);
                    }
                } else {
                    checkIfFolderHasSubfolders(item.path, toggleIcon);
                }

                toggleIcon.addEventListener('click', (e) => toggleExpansion(e, nodeDiv, childUl));
                
                nodeDiv.addEventListener('click', (e) => {
                    if (e.target.tagName !== 'A') {
                        toggleExpansion(e, nodeDiv, childUl);
                    }
                });

                li.appendChild(nodeDiv);
                li.appendChild(childUl);
                parentUlElement.appendChild(li);
            });
        }
        
        async function checkIfFolderHasSubfolders(path, toggleIcon) {
            const data = await fetchDirectoryStructure(path);
            const hasFolders = data.some(item => item.is_dir);
            if (!hasFolders) {
                toggleIcon.classList.add('hidden');
            }
        }

        // -------------------------------------------------------------------------
        // 3. GLOBAL SEARCH LOGIC (გლობალური ძიების ლოგიკა)
        // -------------------------------------------------------------------------

        function renderSearchResults(results, query) {
            let html = '';

            if (results.length === 0) {
                html = `
                    <div class="p-8 text-center text-gray-500">
                        <p class="text-xl font-semibold">შედეგები ვერ მოიძებნა</p>
                        <p class="mt-2 text-sm">ვერაფერი მოიძებნა, რაც შეესაბამება: <code class="bg-gray-100 p-1 rounded text-blue-500">${query}</code></p>
                    </div>
                `;
                SEARCH_RESULTS_VIEW.innerHTML = html;
                return;
            }

            // Start of UL list for results
            html += '<ul class="divide-y divide-gray-100">';
            
            results.forEach(item => {
                const isDir = item.is_dir;
                const pathSegments = item.path.split('/').filter(s => s.length > 0);
                const parentPath = pathSegments.slice(0, -1).join('/'); // Path excluding the item itself
                const fileSize = isDir ? 'დირექტორია' : `${(item.size / (1024 * 1024)).toLocaleString(undefined, { maximumFractionDigits: 2 })} MB`;
                
                // FIX: Use fixed fill color and correct viewBox casing for search results
                const icon = isDir 
                    ? `<svg class="w-6 h-6 mr-3 icon-folder flex-shrink-0" fill="#fbbf24" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"></path></svg>`
                    : `<svg class="w-6 h-6 mr-3 icon-file flex-shrink-0" fill="#3b82f6" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 2a1 1 0 000 2h8a1 1 0 000-2H6z" clip-rule="evenodd"></path></svg>`;

                const downloadLink = !isDir
                    ? `<a href="/download/${item.path}" class="ml-4 bg-blue-500 hover:bg-blue-600 text-white text-xs font-semibold py-1 px-3 rounded-full transition duration-150 shadow-md flex items-center flex-shrink-0">
                            <!-- FIX: viewBox (CamelCase) for download icon -->
                            <svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><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"></path></svg>
                            გადმოწერა
                       </a>`
                    : '';

                // Modify the structure to enforce truncation and prevent overflow
                html += `
                    <li class="p-4 flex justify-between items-center hover:bg-gray-50">
                        <!-- Left Block: Icon + Name/Path (Flex-grow, min-w-0) -->
                        <a href="/${item.path}" class="flex items-center flex-grow min-w-0 text-gray-700">
                            ${icon}
                            <div class="flex flex-col min-w-0">
                                <span class="font-semibold truncate">${item.name}</span> 
                                <span class="text-xs text-gray-500 font-mono truncate">${BASE_DIR_NAME}/${parentPath}</span>
                                
                                <!-- File Size/Dir Status on Mobile -->
                                ${!isDir 
                                    ? `<span class="text-xs text-gray-400 font-mono mt-0.5 md:hidden">${fileSize}</span>`
                                    : `<span class="text-xs text-gray-400 font-medium mt-0.5 md:hidden">დირექტორია</span>`}
                            </div>
                        </a>
                        
                        <!-- Right Block: Action (Size/Status on desktop, Download button always visible) -->
                        <div class="flex items-center flex-shrink-0">
                            <!-- File Size/Dir Status on Desktop -->
                            ${!isDir 
                                ? `<span class="text-xs text-gray-400 font-mono ml-4 hidden md:inline-block">${fileSize}</span>`
                                : `<span class="text-xs text-gray-400 font-medium ml-4 hidden md:inline-block">დირექტორია</span>`}
                            
                            ${downloadLink}
                        </div>
                    </li>
                `;
            });
            
            html += '</ul>';
            SEARCH_RESULTS_VIEW.innerHTML = html;
        }

        async function performGlobalSearch(query) {
            query = query.trim();
            
            // Hide current view and show results container
            CURRENT_DIR_VIEW.classList.add('hidden');
            SEARCH_RESULTS_VIEW.classList.remove('hidden');
            CURRENT_PATH_DISPLAY.innerHTML = `${BASE_DIR_NAME}/<span class="text-red-500">ძიება: ${query}</span>`;
            
            if (query.length === 0) {
                // Return to normal view if query is empty
                CURRENT_DIR_VIEW.classList.remove('hidden');
                SEARCH_RESULTS_VIEW.classList.add('hidden');
                CURRENT_PATH_DISPLAY.innerHTML = `{{ base_dir_name }}/{{ current_path or '' }}`;
                return;
            }
            
            // Show loading indicator
            LOADING_INDICATOR.classList.remove('hidden');
            SEARCH_RESULTS_VIEW.innerHTML = ''; // Clear old results

            try {
                const response = await fetch(`${API_URL_SEARCH}?q=${encodeURIComponent(query)}`);
                if (!response.ok) {
                    throw new Error('Server search failed');
                }
                const results = await response.json();
                renderSearchResults(results, query);

            } catch (error) {
                console.error("Global search error:", error);
                SEARCH_RESULTS_VIEW.innerHTML = `
                    <div class="p-8 text-center bg-red-100 text-red-700">
                        <p class="font-bold">შეცდომა ძიებისას</p>
                        <p class="text-sm">სერვერმა დააბრუნა შეცდომა. სცადეთ მოგვიანებით.</p>
                    </div>
                `;
            } finally {
                LOADING_INDICATOR.classList.add('hidden');
            }
        }

        function setupGlobalSearch() {
            SEARCH_INPUT.addEventListener('input', function() {
                clearTimeout(searchTimer);
                const query = this.value;

                // Debounce to prevent excessive requests while typing
                searchTimer = setTimeout(() => {
                    performGlobalSearch(query);
                }, 300); // Wait 300ms after last keypress
            });
        }
        
        // -------------------------------------------------------------------------
        // 4. INITIALIZATION (ინიციალიზაცია)
        // -------------------------------------------------------------------------
        
        window.onload = function() {
            const rootUl = document.getElementById('tree-children-root');
            rootUl.classList.remove('hidden');
            
            const rootNode = document.getElementById('root-node');
            const rootToggleIcon = document.getElementById('root-toggle-icon');

            if (CURRENT_PATH.length === 0) {
                 rootNode.classList.add('active');
            }
            
            checkIfFolderHasSubfolders('', rootToggleIcon);
            rootToggleIcon?.classList.add('expanded');
            
            loadAndRenderChildren('', rootUl);
            
            document.getElementById('file-tree-sidebar').classList.remove('hidden');

            // Initialize Global Search Functionality
            setupGlobalSearch();
        };

    </script>
</body>
</html>
"""

# --------------------------------------------------------------------------------------
# 3. HELPER FUNCTION (დამხმარე ფუნქცია)
# --------------------------------------------------------------------------------------

def get_current_directory_content(path=''):
    """
    ჩამოთვლის მიმდინარე დირექტორიის შიგთავსს BASE_DIR-ის მიმართ.
    """
    # უსაფრთხო ბილიკის შექმნა
    full_path = os.path.join(BASE_DIR, path)

    # უსაფრთხოების შემოწმება: დარწმუნდით, რომ ბილიკი არ გადის BASE_DIR-ის ფარგლებს
    if not os.path.abspath(full_path).startswith(BASE_DIR):
        # 403 Forbidden
        return [], "უსაფრთხოების შეცდომა: ბილიკი არ არის დაშვებული.", ""

    # FIX: თუ ბილიკი ფაილზე მიუთითებს, არ დააბრუნოთ შეცდომა, არამედ მიეცით ცარიელი სია, 
    # რადგან index() ფუნქცია ახლა აკეთებს გადამისამართებას.
    if not os.path.exists(full_path) or not os.path.isdir(full_path):
        # ეს შეცდომა გამოჩნდება, თუ ფოლდერი არ არსებობს
        return [], "დირექტორია ვერ მოიძებნა.", ""

    items = []
    try:
        # მიმდინარე დირექტორიის შიგთავსის ჩამოთვლა
        for entry in os.listdir(full_path):
            # გამოტოვება: ფარული ფაილები და სისტემური ფოლდერები
            if entry.startswith('.') or entry in ['__pycache__', 'venv']:
                continue

            # ბილიკების ფორმატირება URL-ებისთვის (slash-ის გამოყენებით)
            entry_path = os.path.join(path, entry).replace('\\', '/')
            full_entry_path = os.path.join(BASE_DIR, entry_path)

            item = {
                'name': entry,
                'path': entry_path,
                'is_dir': os.path.isdir(full_entry_path)
            }

            if not item['is_dir']:
                # ფაილის ზომის დამატება
                item['size'] = os.path.getsize(full_entry_path)

            items.append(item)

        # დახარისხება: ჯერ ფოლდერები, შემდეგ ფაილები
        items.sort(key=lambda x: (not x['is_dir'], x['name'].lower()))

    except Exception as e:
        # წვდომის შეცდომის დამუშავება
        return [], f"დირექტორიაზე წვდომის შეცდომა: {e}", ""

    # მშობელი ბილიკის გამოთვლა (სწორი ნავიგაციისთვის)
    parent_path = '/'.join(path.split('/')[:-1]) if path else ''

    return items, None, parent_path

def recursive_search_directory(search_term=""):
    """
    რეკურსიულად ეძებს მთლიან BASE_DIR-ში ფაილებსა და ფოლდერებს, რომლებიც ემთხვევა საძიებო ტერმინს.
    """
    search_term = search_term.lower()
    results = []

    # os.walk არის ყველაზე ეფექტური მეთოდი რეკურსიული ძიებისთვის
    for root, dirs, files in os.walk(BASE_DIR):
        # გამოტოვება: ფარული ფაილები და სისტემური ფოლდერები
        dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['__pycache__', 'venv']]
        
        # გამოთვლა: ბილიკი BASE_DIR-თან მიმართებაში
        relative_root = os.path.relpath(root, BASE_DIR).replace('\\', '/')
        if relative_root == '.':
            relative_root = ""
        
        # Check folders (dirs) and files
        for name in dirs + files:
            if search_term in name.lower():
                is_dir = name in dirs
                path = os.path.join(relative_root, name).replace('\\', '/')
                full_path = os.path.join(root, name)
                
                item = {
                    'name': name,
                    'path': path,
                    'is_dir': is_dir,
                    'size': 0
                }
                
                if not is_dir and os.path.exists(full_path):
                    # ფაილის ზომის დამატება
                    item['size'] = os.path.getsize(full_path)
                
                results.append(item)
    
    # დახარისხება: ჯერ ფოლდერები, შემდეგ ფაილები
    results.sort(key=lambda x: (not x['is_dir'], x['name'].lower()))
    return results

# --------------------------------------------------------------------------------------
# 4. FLASK ROUTES (Flask როუტები)
# --------------------------------------------------------------------------------------

@app.route('/', defaults={'req_path': ''})
@app.route('/<path:req_path>')
def index(req_path):
    """
    მთავარი როუტი დირექტორიების დასათვალიერებლად.
    """
    # URL ბილიკის ნორმალიზება
    current_path = req_path.replace('\\', '/').strip('/')
    
    full_path_check = os.path.join(BASE_DIR, current_path)

    # FIX: თუ მომხმარებელი შედის ფაილის ბილიკზე, გადამისამართება გადმოწერის როუტზე
    if os.path.isfile(full_path_check) and os.path.abspath(full_path_check).startswith(BASE_DIR):
        return redirect(url_for('download_file', filename=current_path))

    # მიმდინარე დირექტორიის შიგთავსის მიღება
    files_and_folders, error, _ = get_current_directory_content(current_path)

    # საბაზისო დირექტორიის სახელის ჩვენება
    base_dir_name = os.path.basename(BASE_DIR) or "Root"

    return render_template_string(
        HTML_TEMPLATE,
        files_and_folders=files_and_folders,
        current_path=current_path,
        error=error,
        base_dir_name=base_dir_name
    )

# --- API Route for Dynamic Tree View ---
@app.route('/api/structure/', defaults={'req_path': ''})
@app.route('/api/structure/<path:req_path>')
def api_structure(req_path):
    """
    აბრუნებს დირექტორიის შიგთავსს JSON ფორმატში Tree View-სთვის.
    """
    current_path = req_path.replace('\\', '/').strip('/')
    files_and_folders, error, _ = get_current_directory_content(current_path)

    if error:
        return jsonify({'error': error}), 400

    tree_nodes = [
        {'name': item['name'], 'path': item['path'], 'is_dir': item['is_dir']}
        for item in files_and_folders
    ]

    return jsonify(tree_nodes)

# --- Global Search API Route (გლობალური ძიების API) ---
@app.route('/api/search')
def api_search():
    """
    ასრულებს რეკურსიულ ძიებას მთელ BASE_DIR-ში და აბრუნებს შედეგებს JSON-ად.
    """
    query = request.args.get('q', '')
    if not query:
        return jsonify([])
    
    # უსაფრთხოების შემოწმება: ძებნის ტერმინის ნორმალიზება
    query = query.strip()
    
    results = recursive_search_directory(query)
    
    return jsonify(results)
# -------------------------------------------

@app.route('/download/<path:filename>')
def download_file(filename):
    """
    როუტი ფაილის უსაფრთხოდ გადმოსაწერად.
    """
    # ფაილის ბილიკის ნორმალიზება
    safe_filename = filename.replace('\\', '/').strip('/')
    full_path = os.path.join(BASE_DIR, safe_filename)

    # უსაფრთხოების შემოწმება (Directory Traversal Prevention)
    if not os.path.abspath(full_path).startswith(BASE_DIR):
        abort(403) # აკრძალული

    # დარწმუნდით, რომ ეს არის ფაილი
    if not os.path.isfile(full_path):
        # თუ ფაილი არ არის, შესაძლოა ეს იყო ფოლდერი ან არარსებული ბილიკი
        abort(404) # ვერ მოიძებნა

    try:
        # send_from_directory უსაფრთხოდ ემსახურება ფაილებს BASE_DIR-დან
        return send_from_directory(
            directory=BASE_DIR,
            path=safe_filename,
            as_attachment=True
        )
    except FileNotFoundError:
        abort(404)
    except Exception:
        abort(500) # შიდა სერვერის შეცდომა

# --------------------------------------------------------------------------------------
# 5. RUN APP (აპლიკაციის გაშვება)
# --------------------------------------------------------------------------------------

if __name__ == '__main__':
    # Flask-ის გაშვება
    # დარწმუნდით, რომ გაქვთ დაყენებული Flask: pip install Flask
    app.run(debug=True)
