/**
 * File management operations (create, rename, delete)
 * Plain functions, no module wrapper
 */

/**
 * Resolve a node in fileTree by filePath
 * @param {string} filePath - Path like 'subdir/file.md' or ''
 * @returns {Object|null} The node object or null if not found
 */
function resolveNode(filePath) {
    if (!filePath) return fileTree;
    const parts = filePath.split('/');
    let node = fileTree;
    for (const part of parts) {
        if (!node.entries || !node.entries[part]) return null;
        node = node.entries[part];
    }
    return node;
}

/**
 * Resolve the parent directory handle for a given file path
 * @param {string} filePath - Full path like 'subdir/file.md'
 * @returns {FileSystemDirectoryHandle|null} Parent directory handle or null
 */
function resolveParentDirHandle(filePath) {
    const parts = filePath.split('/');
    if (parts.length === 1) return directoryHandle;
    let node = fileTree;
    for (let i = 0; i < parts.length - 1; i++) {
        node = node.entries[parts[i]];
        if (!node) return null;
    }
    return node.handle;
}

/**
 * Create a new file
 * @param {string} parentDirPath - '' for root, or 'subdir', 'a/b/c'
 */
async function createNewFile(parentDirPath) {
    // Resolve parent directory handle first (no user activation needed for reads)
    let parentHandle;
    if (parentDirPath === '') {
        parentHandle = directoryHandle;
    } else {
        const node = resolveNode(parentDirPath);
        if (!node || !node.handle) {
            alert('Could not locate parent directory.');
            return;
        }
        parentHandle = node.handle;
    }

    // Show in-page modal and wait for user to confirm or cancel.
    // Returns the filename string, or null if cancelled.
    const name = await new Promise((resolve) => {
        const modal = document.getElementById('new-file-modal');
        const input = document.getElementById('new-file-input');
        const confirmBtn = document.getElementById('new-file-confirm');
        const cancelBtn = document.getElementById('new-file-cancel');

        input.value = 'untitled.md';
        modal.classList.remove('hidden');
        input.focus();
        input.select();

        function cleanup() {
            modal.classList.add('hidden');
            confirmBtn.removeEventListener('click', onConfirm);
            cancelBtn.removeEventListener('click', onCancel);
            input.removeEventListener('keydown', onKey);
        }

        function onConfirm() {
            const val = input.value.trim();
            cleanup();
            resolve(val || null);
        }

        function onCancel() {
            cleanup();
            resolve(null);
        }

        function onKey(e) {
            if (e.key === 'Enter') onConfirm();
            if (e.key === 'Escape') onCancel();
        }

        confirmBtn.addEventListener('click', onConfirm);
        cancelBtn.addEventListener('click', onCancel);
        input.addEventListener('keydown', onKey);
    });

    if (!name) {
        if (DEBUG) console.log('New file creation cancelled');
        return;
    }

    // Validate name
    if (name.includes('/') || name.includes('\\')) {
        alert('Invalid filename: cannot contain / or \\.');
        return;
    }

    // Check if file already exists
    try {
        await parentHandle.getFileHandle(name);
        const overwrite = window.confirm('A file named "' + name + '" already exists. Overwrite it?');
        if (!overwrite) return;
    } catch (e) {
        if (e.name !== 'NotFoundError') throw e;
    }

    // Create the file — this must happen after the modal's button click
    // which is the user activation token.
    try {
        const newHandle = await parentHandle.getFileHandle(name, { create: true });

        const writable = await newHandle.createWritable();
        await writable.write('');
        await writable.close();

        if (DEBUG) console.log(`Created new file: ${parentDirPath ? parentDirPath + '/' : ''}${name}`);

        await refreshDirectory();

        const newFilePath = parentDirPath ? parentDirPath + '/' + name : name;
        const element = document.querySelector('.file-item[data-path="' + CSS.escape(newFilePath) + '"]');
        if (element) {
            handleFileClick(newHandle, newFilePath, element);
        }
    } catch (error) {
        console.error('Error creating new file:', error);
        alert('Error creating file: ' + error.message);
    }
}

/**
 * Rename a file or directory
 * @param {string} filePath - Full path like 'subdir/file.md'
 * @param {boolean} isDirectory - true if renaming a directory (not supported on Chrome)
 */
async function renameEntry(filePath, isDirectory) {
    const currentName = filePath.split('/').pop();
    const newName = window.prompt('Rename to:', currentName);
    
    if (newName === null || newName === currentName) {
        if (DEBUG) console.log('Rename cancelled or unchanged');
        return;
    }
    
    // Validate name
    if (newName.includes('/') || newName.includes('\\') || newName.trim() === '') {
        alert('Invalid filename: cannot contain / or \\ and must not be empty.');
        return;
    }
    
    // Resolve parent directory handle
    const parentHandle = resolveParentDirHandle(filePath);
    if (!parentHandle) {
        alert('Could not locate parent directory.');
        return;
    }
    
    // For files: rename via File System Access API
    if (!isDirectory) {
        try {
            // Check if new name already exists (file or directory)
            try {
                const existing = await parentHandle.getFileHandle(newName);
                // A file with that name exists
                const overwrite = window.confirm('A file named "' + newName + '" already exists. Overwrite?');
                if (!overwrite) return;
            } catch (fileErr) {
                if (fileErr.name === 'TypeMismatchError') {
                    // A directory with that name exists
                    window.alert('A folder named "' + newName + '" already exists. Choose a different name.');
                    return;
                }
                if (fileErr.name !== 'NotFoundError') throw fileErr;
                // NotFoundError = safe to create
            }
            
            const oldHandle = resolveNode(filePath);
            if (!oldHandle || !oldHandle.handle) {
                alert('Could not find file to rename.');
                return;
            }
            
            const file = await oldHandle.handle.getFile();
            const content = await file.text();
            
            const newHandle = await parentHandle.getFileHandle(newName, { create: true });
            const writable = await newHandle.createWritable();
            await writable.write(content);
            await writable.close();
            const newFile = await newHandle.getFile();
            
            await parentHandle.removeEntry(currentName);
            
            // Update editor instances
            if (editorInstances.has(filePath)) {
                const instance = editorInstances.get(filePath);
                const newFilePath = filePath.substring(0, filePath.length - currentName.length) + newName;
                
                // Remove old instance
                const data = editorInstances.get(filePath);
                if (data.fileViewContainer) {
                    data.fileViewContainer.classList.add('hidden');
                }
                editorInstances.delete(filePath);
                
                // Re-add with new path
                editorInstances.set(newFilePath, { ...data, fileHandle: newHandle, lastModified: newFile.lastModified });
                
                // Update active state
                if (instance.fileViewContainer) {
                    instance.fileViewContainer.classList.remove('hidden');
                    instance.fileViewContainer.dataset.path = newFilePath;
                }
                
                // Update fileTree entries
                const parts = filePath.split('/');
                const fileName = parts.pop();
                const dirPath = parts.join('/');
                let targetEntries = fileTree.entries;
                if (dirPath) {
                    const dirParts = dirPath.split('/');
                    let current = fileTree;
                    for (const part of dirParts) {
                        current = current.entries[part];
                    }
                    targetEntries = current.entries;
                }
                if (targetEntries && targetEntries[currentName]) {
                    delete targetEntries[currentName];
                    targetEntries[newName] = {
                        name: newName,
                        type: 'file',
                        handle: newHandle
                    };
                }
                
                renderFileTree();
                restoreActiveFile(newFilePath);
            } else {
                renderFileTree();
            }
            
        } catch (error) {
            console.error('Error renaming file:', error);
            alert('Error renaming file: ' + error.message);
        }
    } else {
        // For directories: not supported by browser API
        alert('Directory rename is not supported by the browser File System API. Please rename the folder in your OS file manager and refresh.');
    }
}

/**
 * Delete a file or directory
 * @param {string} filePath - Full path like 'subdir/file.md' or 'subdir'
 * @param {boolean} isDirectory - true if deleting a directory
 */
async function deleteEntry(filePath, isDirectory) {
    const name = filePath.split('/').pop();
    
    const message = isDirectory 
        ? 'Delete folder "' + name + '" and all its contents?'
        : 'Delete "' + name + '"?';
    
    const ok = window.confirm(message);
    if (!ok) {
        if (DEBUG) console.log('Delete cancelled by user');
        return;
    }
    
    // Resolve parent directory handle
    const parentHandle = resolveParentDirHandle(filePath);
    if (!parentHandle) {
        alert('Could not locate parent directory.');
        return;
    }
    
    let deleted = false;
    try {
        await parentHandle.removeEntry(name, { recursive: isDirectory });
        deleted = true;
    } catch (error) {
        if (error.name === 'NotFoundError') {
            // Already gone — treat as success for cleanup purposes
            deleted = true;
        } else {
            console.error('Error deleting entry:', error);
            alert('Error deleting entry: ' + error.message);
        }
    }

    if (deleted) {
        // Close editor if open
        if (!isDirectory && editorInstances.has(filePath)) {
            closeEditorInstance(filePath);
        } else if (isDirectory) {
            // Close any editors under this directory
            const dirsToClose = [];
            editorInstances.forEach(function(instance, key) {
                if (key === filePath || key.startsWith(filePath + '/')) {
                    dirsToClose.push(key);
                }
            });
            dirsToClose.forEach(function(key) {
                closeEditorInstance(key);
            });
        }
        
        // Remove from fileTree entries
        const parts = filePath.split('/');
        const entryName = parts.pop();
        const dirPath = parts.join('/');
        let targetEntries = fileTree.entries;
        if (dirPath) {
            const dirParts = dirPath.split('/');
            let current = fileTree;
            for (const part of dirParts) {
                current = current.entries[part];
            }
            targetEntries = current.entries;
        }
        if (targetEntries && targetEntries[entryName]) {
            delete targetEntries[entryName];
        }
        
        renderFileTree();
        updateStatusCountsFromTree();
    }
}

/**
 * Close an editor instance and show welcome screen if no files open
 * @param {string} filePath - Path of file to close
 */
function closeEditorInstance(filePath) {
    const instance = editorInstances.get(filePath);
    if (!instance) return;
    
    if (instance.fileViewContainer) {
        instance.fileViewContainer.classList.add('hidden');
    }
    editorInstances.delete(filePath);
    
    // Check if any visible file-view-container children remain
    const contentContainer = document.getElementById('content-container');
    if (contentContainer) {
        const visibleChildren = Array.from(contentContainer.querySelectorAll('.file-view-container'))
            .filter(function(el) { return !el.classList.contains('hidden'); });
        if (visibleChildren.length === 0) {
            document.getElementById('welcome-screen').classList.remove('hidden');
            contentContainer.classList.add('hidden');
        }
    }
}

/**
 * Restore active file state after rename
 * @param {string} newFilePath - New path of the file
 */
function restoreActiveFile(newFilePath) {
    const element = document.querySelector('.file-item[data-path="' + CSS.escape(newFilePath) + '"]');
    if (element) {
        element.classList.add('active-file');
        element.style.backgroundColor = '';
        element.style.color = '';
    }
}

/**
 * Update status counts from fileTree
 */
function updateStatusCountsFromTree() {
    let folderCount = 0;
    let fileCount = 0;
    
    function countEntries(entries) {
        if (!entries) return;
        for (const [name, item] of Object.entries(entries)) {
            if (item.type === 'directory') {
                folderCount++;
                countEntries(item.entries);
            } else if (item.type === 'file') {
                fileCount++;
            }
        }
    }
    
    countEntries(fileTree.entries);
    updateStatusCounts(folderCount, fileCount);
}
