/**
 * Main Application
 * Coordinates all modules and handles user interactions
 */
// Global state
let webdavClient;
let fileTree;
let editor;
let darkMode;
let collectionSelector;
let clipboard = null;
let currentFilePath = null;
// Event bus is now loaded from event-bus.js module
// No need to define it here - it's available as window.eventBus
/**
 * Auto-load page in view mode
 * Tries to load the last viewed page, falls back to first file if none saved
 */
async function autoLoadPageInViewMode() {
    if (!editor || !fileTree) return;
    try {
        // Try to get last viewed page
        let pageToLoad = editor.getLastViewedPage();
        // If no last viewed page, get the first markdown file
        if (!pageToLoad) {
            pageToLoad = fileTree.getFirstMarkdownFile();
        }
        // If we found a page to load, load it
        if (pageToLoad) {
            // Use fileTree.onFileSelect to handle both text and binary files
            if (fileTree.onFileSelect) {
                fileTree.onFileSelect({ path: pageToLoad, isDirectory: false });
            } else {
                // Fallback to direct loading (for text files only)
                await editor.loadFile(pageToLoad);
                fileTree.selectAndExpandPath(pageToLoad);
            }
        } else {
            // No files found, show empty state message
            editor.previewElement.innerHTML = `
                
            `;
        }
    } catch (error) {
        console.error('Failed to auto-load page in view mode:', error);
        editor.previewElement.innerHTML = `
            
        `;
    }
}
/**
 * Show directory preview with list of files
 * @param {string} dirPath - The directory path
 */
async function showDirectoryPreview(dirPath) {
    if (!editor || !fileTree || !webdavClient) return;
    try {
        const dirName = dirPath.split('/').pop() || dirPath;
        const files = fileTree.getDirectoryFiles(dirPath);
        // Start building the preview HTML
        let html = ``;
        html += `
${dirName}
`;
        if (files.length === 0) {
            html += `
This directory is empty
`;
        } else {
            html += `
`;
            // Create cards for each file
            for (const file of files) {
                const fileName = file.name;
                let fileDescription = '';
                // Try to get file description from markdown files
                if (file.name.endsWith('.md')) {
                    try {
                        const content = await webdavClient.get(file.path);
                        // Extract first heading or first line as description
                        const lines = content.split('\n');
                        for (const line of lines) {
                            if (line.trim().startsWith('#')) {
                                fileDescription = line.replace(/^#+\s*/, '').trim();
                                break;
                            } else if (line.trim() && !line.startsWith('---')) {
                                fileDescription = line.trim().substring(0, 100);
                                break;
                            }
                        }
                    } catch (error) {
                        console.error('Failed to read file description:', error);
                    }
                }
                html += `
                    
                        
                        ${fileDescription ? `
${fileDescription}
` : ''}
                    
                `;
            }
            html += `
`;
        }
        html += `
                Failed to load directory preview
             
        `;
    }
}
/**
 * Parse URL to extract collection and file path
 * URL format: // or ///
 * @returns {Object} {collection, filePath} or {collection, null} if only collection
 */
function parseURLPath() {
    const pathname = window.location.pathname;
    const parts = pathname.split('/').filter(p => p); // Remove empty parts
    if (parts.length === 0) {
        return { collection: null, filePath: null };
    }
    const collection = parts[0];
    const filePath = parts.length > 1 ? parts.slice(1).join('/') : null;
    return { collection, filePath };
}
/**
 * Update URL based on current collection and file
 * @param {string} collection - The collection name
 * @param {string} filePath - The file path (optional)
 * @param {boolean} isEditMode - Whether in edit mode
 */
function updateURL(collection, filePath, isEditMode) {
    let url = `/${collection}`;
    if (filePath) {
        url += `/${filePath}`;
    }
    if (isEditMode) {
        url += '?edit=true';
    }
    // Use pushState to update URL without reloading
    window.history.pushState({ collection, filePath }, '', url);
}
/**
 * Load file from URL path
 * Assumes the collection is already set and file tree is loaded
 * @param {string} collection - The collection name (for validation)
 * @param {string} filePath - The file path
 */
async function loadFileFromURL(collection, filePath) {
    console.log('[loadFileFromURL] Called with:', { collection, filePath });
    if (!fileTree || !editor || !collectionSelector) {
        console.error('[loadFileFromURL] Missing dependencies:', { fileTree: !!fileTree, editor: !!editor, collectionSelector: !!collectionSelector });
        return;
    }
    try {
        // Verify we're on the right collection
        const currentCollection = collectionSelector.getCurrentCollection();
        if (currentCollection !== collection) {
            console.error(`[loadFileFromURL] Collection mismatch: expected ${collection}, got ${currentCollection}`);
            return;
        }
        // Load the file or directory
        if (filePath) {
            // Check if the path is a directory or a file
            const node = fileTree.findNode(filePath);
            console.log('[loadFileFromURL] Found node:', node);
            if (node && node.isDirectory) {
                // It's a directory, show directory preview
                console.log('[loadFileFromURL] Loading directory preview');
                await showDirectoryPreview(filePath);
                fileTree.selectAndExpandPath(filePath);
            } else if (node) {
                // It's a file, check if it's binary
                console.log('[loadFileFromURL] Loading file');
                // Use the fileTree.onFileSelect callback to handle both text and binary files
                if (fileTree.onFileSelect) {
                    fileTree.onFileSelect({ path: filePath, isDirectory: false });
                } else {
                    // Fallback to direct loading
                    await editor.loadFile(filePath);
                    fileTree.selectAndExpandPath(filePath);
                }
            } else {
                console.error(`[loadFileFromURL] Path not found in file tree: ${filePath}`);
            }
        }
    } catch (error) {
        console.error('[loadFileFromURL] Failed to load file from URL:', error);
    }
}
/**
 * Handle browser back/forward navigation
 */
function setupPopStateListener() {
    window.addEventListener('popstate', async (event) => {
        const { collection, filePath } = parseURLPath();
        if (collection) {
            // Ensure the collection is set
            const currentCollection = collectionSelector.getCurrentCollection();
            if (currentCollection !== collection) {
                await collectionSelector.setCollection(collection);
                await fileTree.load();
            }
            // Load the file/directory
            await loadFileFromURL(collection, filePath);
        }
    });
}
// Initialize application
document.addEventListener('DOMContentLoaded', async () => {
    // Determine view mode from URL parameter
    const urlParams = new URLSearchParams(window.location.search);
    const isEditMode = urlParams.get('edit') === 'true';
    // Set view mode class on body
    if (isEditMode) {
        document.body.classList.add('edit-mode');
        document.body.classList.remove('view-mode');
    } else {
        document.body.classList.add('view-mode');
        document.body.classList.remove('edit-mode');
    }
    // Initialize WebDAV client
    webdavClient = new WebDAVClient('/fs/');
    // Initialize dark mode
    darkMode = new DarkMode();
    document.getElementById('darkModeBtn').addEventListener('click', () => {
        darkMode.toggle();
    });
    // Initialize sidebar toggle
    const sidebarToggle = new SidebarToggle('sidebarPane', 'sidebarToggleBtn');
    // Initialize collection selector (always needed)
    collectionSelector = new CollectionSelector('collectionSelect', webdavClient);
    await collectionSelector.load();
    // Setup New Collection button
    document.getElementById('newCollectionBtn').addEventListener('click', async () => {
        try {
            const collectionName = await window.ModalManager.prompt(
                'Enter new collection name (lowercase, underscore only):',
                'new_collection'
            );
            if (!collectionName) return;
            // Validate collection name
            const validation = ValidationUtils.validateFileName(collectionName, true);
            if (!validation.valid) {
                window.showNotification(validation.message, 'warning');
                return;
            }
            // Create the collection
            await webdavClient.createCollection(validation.sanitized);
            // Reload collections and switch to the new one
            await collectionSelector.load();
            await collectionSelector.setCollection(validation.sanitized);
            window.showNotification(`Collection "${validation.sanitized}" created`, 'success');
        } catch (error) {
            Logger.error('Failed to create collection:', error);
            window.showNotification('Failed to create collection', 'error');
        }
    });
    // Setup URL routing
    setupPopStateListener();
    // Initialize editor (always needed for preview)
    // In view mode, editor is read-only
    editor = new MarkdownEditor('editor', 'preview', 'filenameInput', !isEditMode);
    editor.setWebDAVClient(webdavClient);
    // Initialize file tree (needed in both modes)
    // Pass isEditMode to control image filtering (hide images only in view mode)
    fileTree = new FileTree('fileTree', webdavClient, isEditMode);
    fileTree.onFileSelect = async (item) => {
        try {
            const currentCollection = collectionSelector.getCurrentCollection();
            // Check if the file is a binary/non-editable file
            if (PathUtils.isBinaryFile(item.path)) {
                const fileType = PathUtils.getFileType(item.path);
                const fileName = PathUtils.getFileName(item.path);
                Logger.info(`Previewing binary file: ${item.path}`);
                // Initialize and show loading spinner for binary file preview
                editor.initLoadingSpinners();
                if (editor.previewSpinner) {
                    editor.previewSpinner.show(`Loading ${fileType.toLowerCase()}...`);
                }
                // Set flag to prevent auto-update of preview
                editor.isShowingCustomPreview = true;
                // In edit mode, show a warning notification
                if (isEditMode) {
                    if (window.showNotification) {
                        window.showNotification(
                            `"${fileName}" is read-only. Showing preview only.`,
                            'warning'
                        );
                    }
                    // Hide the editor pane temporarily
                    const editorPane = document.getElementById('editorPane');
                    const resizer1 = document.getElementById('resizer1');
                    if (editorPane) editorPane.style.display = 'none';
                    if (resizer1) resizer1.style.display = 'none';
                }
                // Clear the editor (but don't trigger preview update due to flag)
                if (editor.editor) {
                    editor.editor.setValue('');
                }
                editor.filenameInput.value = item.path;
                editor.currentFile = item.path;
                // Build the file URL using the WebDAV client's method
                const fileUrl = webdavClient.getFullUrl(item.path);
                Logger.debug(`Binary file URL: ${fileUrl}`);
                // Generate preview HTML based on file type
                let previewHtml = '';
                if (fileType === 'Image') {
                    // Preview images
                    previewHtml = `
                        
                            ${fileName}
                            Image Preview (Read-only)
                             
                         
                    `;
                } else if (fileType === 'PDF') {
                    // Preview PDFs
                    previewHtml = `
                        
                            ${fileName}
                            PDF Preview (Read-only)
                            
                         
                    `;
                } else {
                    // For other binary files, show download link
                    previewHtml = `
                        
                            ${fileName}
                            ${fileType} File (Read-only)
                            This file cannot be previewed in the browser.
                            Download ${fileName}
                         
                    `;
                }
                // Display in preview pane
                editor.previewElement.innerHTML = previewHtml;
                // Hide loading spinner after content is set
                // Add small delay for images to start loading
                setTimeout(() => {
                    if (editor.previewSpinner) {
                        editor.previewSpinner.hide();
                    }
                }, fileType === 'Image' ? 300 : 100);
                // Highlight the file in the tree
                fileTree.selectAndExpandPath(item.path);
                // Save as last viewed page (for binary files too)
                editor.saveLastViewedPage(item.path);
                // Update URL to reflect current file
                updateURL(currentCollection, item.path, isEditMode);
                return;
            }
            // For text files, restore the editor pane if it was hidden
            if (isEditMode) {
                const editorPane = document.getElementById('editorPane');
                const resizer1 = document.getElementById('resizer1');
                if (editorPane) editorPane.style.display = '';
                if (resizer1) resizer1.style.display = '';
            }
            await editor.loadFile(item.path);
            // Highlight the file in the tree and expand parent directories
            fileTree.selectAndExpandPath(item.path);
            // Update URL to reflect current file
            updateURL(currentCollection, item.path, isEditMode);
        } catch (error) {
            Logger.error('Failed to select file:', error);
            if (window.showNotification) {
                window.showNotification('Failed to load file', 'error');
            }
        }
    };
    fileTree.onFolderSelect = async (item) => {
        try {
            // Show directory preview
            await showDirectoryPreview(item.path);
            // Highlight the directory in the tree and expand parent directories
            fileTree.selectAndExpandPath(item.path);
            // Update URL to reflect current directory
            const currentCollection = collectionSelector.getCurrentCollection();
            updateURL(currentCollection, item.path, isEditMode);
        } catch (error) {
            Logger.error('Failed to select folder:', error);
            if (window.showNotification) {
                window.showNotification('Failed to load folder', 'error');
            }
        }
    };
    collectionSelector.onChange = async (collection) => {
        try {
            await fileTree.load();
            // In view mode, auto-load last viewed page when collection changes
            if (!isEditMode) {
                await autoLoadPageInViewMode();
            }
        } catch (error) {
            Logger.error('Failed to change collection:', error);
            if (window.showNotification) {
                window.showNotification('Failed to change collection', 'error');
            }
        }
    };
    await fileTree.load();
    // Parse URL to load file if specified
    const { collection: urlCollection, filePath: urlFilePath } = parseURLPath();
    console.log('[URL PARSE]', { urlCollection, urlFilePath });
    if (urlCollection) {
        // First ensure the collection is set
        const currentCollection = collectionSelector.getCurrentCollection();
        if (currentCollection !== urlCollection) {
            console.log('[URL LOAD] Switching collection from', currentCollection, 'to', urlCollection);
            await collectionSelector.setCollection(urlCollection);
            await fileTree.load();
        }
        // If there's a file path in the URL, load it
        if (urlFilePath) {
            console.log('[URL LOAD] Loading file from URL:', urlCollection, urlFilePath);
            await loadFileFromURL(urlCollection, urlFilePath);
        } else if (!isEditMode) {
            // Collection-only URL in view mode: auto-load last viewed page
            console.log('[URL LOAD] Collection-only URL, auto-loading page');
            await autoLoadPageInViewMode();
        }
    } else if (!isEditMode) {
        // No URL collection specified, in view mode: auto-load last viewed page
        await autoLoadPageInViewMode();
    }
    // Initialize file tree and editor-specific features only in edit mode
    if (isEditMode) {
        // Add test content to verify preview works
        setTimeout(() => {
            if (!editor.editor.getValue()) {
                editor.editor.setValue('# Welcome to Markdown Editor\n\nStart typing to see preview...\n');
                editor.updatePreview();
            }
        }, 200);
        // Setup editor drop handler
        const editorDropHandler = new EditorDropHandler(
            document.querySelector('.editor-container'),
            async (file) => {
                try {
                    await handleEditorFileDrop(file);
                } catch (error) {
                    Logger.error('Failed to handle file drop:', error);
                }
            }
        );
        // Setup button handlers
        document.getElementById('newBtn').addEventListener('click', () => {
            editor.newFile();
        });
        document.getElementById('saveBtn').addEventListener('click', async () => {
            try {
                await editor.save();
            } catch (error) {
                Logger.error('Failed to save file:', error);
                if (window.showNotification) {
                    window.showNotification('Failed to save file', 'error');
                }
            }
        });
        document.getElementById('deleteBtn').addEventListener('click', async () => {
            try {
                await editor.deleteFile();
            } catch (error) {
                Logger.error('Failed to delete file:', error);
                if (window.showNotification) {
                    window.showNotification('Failed to delete file', 'error');
                }
            }
        });
        // Setup context menu handlers
        setupContextMenuHandlers();
        // Initialize file tree actions manager
        window.fileTreeActions = new FileTreeActions(webdavClient, fileTree, editor);
        // Setup Exit Edit Mode button
        document.getElementById('exitEditModeBtn').addEventListener('click', () => {
            // Switch to view mode by removing edit=true from URL
            const url = new URL(window.location.href);
            url.searchParams.delete('edit');
            window.location.href = url.toString();
        });
        // Hide Edit Mode button in edit mode
        document.getElementById('editModeBtn').style.display = 'none';
    } else {
        // In view mode, hide editor buttons
        document.getElementById('newBtn').style.display = 'none';
        document.getElementById('saveBtn').style.display = 'none';
        document.getElementById('deleteBtn').style.display = 'none';
        document.getElementById('exitEditModeBtn').style.display = 'none';
        // Show Edit Mode button in view mode
        document.getElementById('editModeBtn').style.display = 'block';
        // Setup Edit Mode button
        document.getElementById('editModeBtn').addEventListener('click', () => {
            // Switch to edit mode by adding edit=true to URL
            const url = new URL(window.location.href);
            url.searchParams.set('edit', 'true');
            window.location.href = url.toString();
        });
        // Auto-load last viewed page or first file
        await autoLoadPageInViewMode();
    }
    // Setup clickable navbar brand (logo/title)
    const navbarBrand = document.getElementById('navbarBrand');
    if (navbarBrand) {
        navbarBrand.addEventListener('click', (e) => {
            e.preventDefault();
            const currentCollection = collectionSelector ? collectionSelector.getCurrentCollection() : null;
            if (currentCollection) {
                // Navigate to collection root
                window.location.href = `/${currentCollection}/`;
            } else {
                // Navigate to home page
                window.location.href = '/';
            }
        });
    }
    // Initialize mermaid (always needed)
    mermaid.initialize({ startOnLoad: true, theme: darkMode.isDark ? 'dark' : 'default' });
    // Listen for file-saved event to reload file tree
    window.eventBus.on('file-saved', async (path) => {
        try {
            if (fileTree) {
                await fileTree.load();
                fileTree.selectNode(path);
            }
        } catch (error) {
            Logger.error('Failed to reload file tree after save:', error);
        }
    });
    window.eventBus.on('file-deleted', async () => {
        try {
            if (fileTree) {
                await fileTree.load();
            }
        } catch (error) {
            Logger.error('Failed to reload file tree after delete:', error);
        }
    });
});
// Listen for column resize events to refresh editor
window.addEventListener('column-resize', () => {
    if (editor && editor.editor) {
        editor.editor.refresh();
    }
});
/**
 * File Operations
 */
/**
 * Context Menu Handlers
 */
function setupContextMenuHandlers() {
    const menu = document.getElementById('contextMenu');
    menu.addEventListener('click', async (e) => {
        const item = e.target.closest('.context-menu-item');
        if (!item) return;
        const action = item.dataset.action;
        const targetPath = menu.dataset.targetPath;
        const isDir = menu.dataset.targetIsDir === 'true';
        hideContextMenu();
        await window.fileTreeActions.execute(action, targetPath, isDir);
    });
}
// All context actions are now handled by FileTreeActions, so this function is no longer needed.
// async function handleContextAction(action, targetPath, isDir) { ... }
function updatePasteVisibility() {
    const pasteItem = document.getElementById('pasteMenuItem');
    if (pasteItem) {
        pasteItem.style.display = clipboard ? 'block' : 'none';
    }
}
/**
 * Editor File Drop Handler
 */
async function handleEditorFileDrop(file) {
    try {
        // Get current file's directory
        let targetDir = '';
        if (currentFilePath) {
            const parts = currentFilePath.split('/');
            parts.pop(); // Remove filename
            targetDir = parts.join('/');
        }
        // Upload file
        const uploadedPath = await fileTree.uploadFile(targetDir, file);
        // Insert markdown link at cursor
        // Use relative path (without collection name) so the image renderer can resolve it correctly
        const isImage = file.type.startsWith('image/');
        const link = isImage
            ? ``
            : `[${file.name}](${uploadedPath})`;
        editor.insertAtCursor(link);
        showNotification(`Uploaded and inserted link`, 'success');
    } catch (error) {
        console.error('Failed to handle file drop:', error);
        showNotification('Failed to upload file', 'error');
    }
}
// Make showContextMenu global
window.showContextMenu = showContextMenu;