/**
 * Toast UI Editor initialization and management
 */

/**
 * Initialize or update the Toast UI Editor for a file
 * @param {string} content - Content to display
 * @param {boolean} isMarkdown - Whether content is markdown
 * @param {string} filePath - Path of the file
 * @param {string} fileName - Name of the file
 * @param {FileSystemFileHandle} fileHandle - File handle for saving
 * @param {number} lastModified - Timestamp of last modification
 */
function initializeEditor(content, isMarkdown = true, filePath = '', fileName = '', fileHandle = null, lastModified = null) {
    // Parse front matter
    let frontMatterData = {};
    let markdownBody = content;
    
    if (isMarkdown && content) {
        try {
            const parsed = parseFrontMatter(content);
            frontMatterData = parsed.data;
            markdownBody = parsed.content;
        } catch (error) {
            console.error('Failed to parse front matter:', error);
        }
    }
    
    const contentContainer = document.getElementById('content-container');
    if (!contentContainer) {
        alert('Error: content-container element not found!');
        return;
    }

    // Hide all file view containers
    document.querySelectorAll('.file-view-container').forEach(container => {
        container.style.display = 'none';
    });

    // Check if file already has an instance
    if (editorInstances.has(filePath)) {
        const existingInstance = editorInstances.get(filePath);
        if (existingInstance.fileViewContainer) {
            existingInstance.fileViewContainer.style.display = 'flex';
        }
        return existingInstance.editor;
    }

    // Create file view container
    const fileViewContainer = document.createElement('div');
    fileViewContainer.className = 'file-view-container flex flex-col h-full';

    // Create file header
    const fileHeader = document.createElement('div');
    fileHeader.className = 'file-header flex justify-between items-center px-4 py-2 bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-200 font-medium border-b border-gray-200 dark:border-gray-700';

    const fileTitle = document.createElement('span');
    fileTitle.textContent = fileName || 'No file selected';
    fileHeader.appendChild(fileTitle);

    // Button container for alignment
    const buttonContainer = document.createElement('div');
    buttonContainer.className = 'flex gap-2';

    // Determine if this is a scratchpad (no file handle)
    const isScratchpad = !fileHandle;
    const isReadOnlyHandle = !!(fileHandle && fileHandle._readOnly);

    // Save button (or Save As for scratchpads / read-only server files)
    const saveButton = document.createElement('button');
    saveButton.className = 'btn btn-primary btn-sm';
    saveButton.textContent = (isScratchpad || isReadOnlyHandle) ? 'Save As...' : 'Save File';
    saveButton.disabled = !isScratchpad; // Scratchpads can always save; read-only enables on edit
    buttonContainer.appendChild(saveButton);

    // Reload button (only for files, not scratchpads) — icon to match file-tree refresh
    let reloadButton = null;
    if (!isScratchpad) {
        reloadButton = document.createElement('button');
        reloadButton.className = 'btn btn-secondary btn-sm';
        reloadButton.textContent = '↻';
        reloadButton.title = 'Reload from disk (discards unsaved changes)';
        reloadButton.setAttribute('aria-label', 'Reload from disk');
        buttonContainer.appendChild(reloadButton);
    }

    fileHeader.appendChild(buttonContainer);

    fileViewContainer.appendChild(fileHeader);

    // Content area
    const contentArea = document.createElement('div');
    contentArea.className = 'flex flex-col flex-1 overflow-hidden';
    
    // Editor area with TOC
    const editorArea = document.createElement('div');
    editorArea.className = 'flex flex-row flex-1 overflow-hidden';

    // TOC pane (markdown only)
    let tocContainer = null;
    let frontMatterTextarea = null;
    if (isMarkdown) {
        const tocPane = document.createElement('div');
        tocPane.className = 'toc-pane bg-white dark:bg-gray-900 border-r border-gray-200 dark:border-gray-700';
        tocPane.style.width = '325px';
        tocPane.style.minWidth = '150px';

        // Front matter section (collapsible, height-resizable)
        const frontMatterNav = document.createElement('div');
        frontMatterNav.className = 'front-matter-nav';
        frontMatterNav.style.height = '180px';

        const frontMatterHeader = document.createElement('div');
        frontMatterHeader.className = 'front-matter-header pane-section-header cursor-pointer';

        const toggleIcon = document.createElement('span');
        toggleIcon.textContent = '▼';
        toggleIcon.className = 'toggle-icon';
        frontMatterHeader.appendChild(toggleIcon);

        const headerText = document.createElement('span');
        headerText.textContent = 'YAML Front Matter';
        frontMatterHeader.appendChild(headerText);

        frontMatterNav.appendChild(frontMatterHeader);

        const frontMatterContent = document.createElement('div');
        frontMatterContent.className = 'front-matter-content';

        frontMatterTextarea = document.createElement('textarea');
        frontMatterTextarea.className = 'front-matter-textarea';
        frontMatterTextarea.placeholder = 'title: Document Title\ndate: 2024-01-01\ntags: [example]';

        if (frontMatterData && Object.keys(frontMatterData).length > 0) {
            try {
                let yamlText = '';
                for (const [key, value] of Object.entries(frontMatterData)) {
                    if (Array.isArray(value)) {
                        yamlText += `${key}: [${value.map(v => `"${v}"`).join(', ')}]\n`;
                    } else {
                        yamlText += `${key}: ${value}\n`;
                    }
                }
                frontMatterTextarea.value = yamlText.trim();
            } catch (error) {
                console.warn('Failed to stringify front matter:', error);
                frontMatterTextarea.value = '';
            }
        }

        frontMatterContent.appendChild(frontMatterTextarea);
        frontMatterNav.appendChild(frontMatterContent);
        tocPane.appendChild(frontMatterNav);

        // Horizontal resizer between front-matter and TOC
        const fmTocResizer = document.createElement('div');
        fmTocResizer.className = 'pane-resizer horizontal';
        tocPane.appendChild(fmTocResizer);

        // TOC section
        const tocSection = document.createElement('div');
        tocSection.className = 'toc-section';

        const tocHeader = document.createElement('div');
        tocHeader.className = 'toc-header pane-section-header';

        const tocTitle = document.createElement('span');
        tocTitle.textContent = 'Table of Contents';
        tocHeader.appendChild(tocTitle);

        const tocDepthSelector = document.createElement('select');
        tocDepthSelector.className = 'toc-depth-selector';
        tocDepthSelector.innerHTML = `
            <option value="6">All Levels</option>
            <option value="1">H1 Only</option>
            <option value="2">H1-H2</option>
            <option value="3" selected>H1-H3</option>
            <option value="4">H1-H4</option>
            <option value="5">H1-H5</option>
        `;
        tocHeader.appendChild(tocDepthSelector);

        tocSection.appendChild(tocHeader);

        tocContainer = document.createElement('div');
        tocContainer.className = 'toc-container toc-content';
        tocSection.appendChild(tocContainer);

        tocPane.appendChild(tocSection);

        // Toggle: collapsed only shows the header. Hide content + horizontal resizer.
        let fmIsCollapsed = false;
        frontMatterHeader.addEventListener('click', () => {
            fmIsCollapsed = !fmIsCollapsed;
            frontMatterNav.classList.toggle('collapsed', fmIsCollapsed);
            toggleIcon.textContent = fmIsCollapsed ? '▶' : '▼';
            fmTocResizer.style.display = fmIsCollapsed ? 'none' : '';
            if (fmIsCollapsed) {
                frontMatterNav.style.height = '';
            } else {
                frontMatterNav.style.height = '180px';
            }
        });

        editorArea.appendChild(tocPane);

        // Vertical resizer between toc-pane and editor (placed inside editorArea)
        const tocResizer = document.createElement('div');
        tocResizer.className = 'pane-resizer bg-gray-200 dark:bg-gray-700 transition-colors relative z-10 w-1 cursor-col-resize hover:bg-blue-500';
        tocResizer.setAttribute('data-resizer-for', 'toc-pane');
        editorArea.appendChild(tocResizer);

        makeResizable(tocResizer, tocPane);

        // Make the front-matter / TOC split height-adjustable
        makeHeightResizable(fmTocResizer, frontMatterNav, tocPane);

        tocDepthSelector.addEventListener('change', function () {
            const depth = parseInt(this.value);
            if (editorInstance) {
                const currentContent = editorInstance.getMarkdown();
                updateToc(currentContent, tocContainer, editorInstance, depth);
            }
        });
    }

    // Editor container
    const editorContainer = document.createElement('div');
    editorContainer.className = 'editor-instance flex-1 overflow-hidden';
    editorArea.appendChild(editorContainer);
    
    contentArea.appendChild(editorArea);
    fileViewContainer.appendChild(contentArea);
    contentContainer.appendChild(fileViewContainer);

    // Check Toast UI availability
    if (typeof toastui === 'undefined') {
        alert('Error: Toast UI library not loaded!');
        editorContainer.innerHTML = '<div style="padding: 20px; background: #ffeeee; color: red;">Error: Toast UI library not loaded!</div>';
        return;
    }

    let editorInstance;

    try {
        // Initialize Toast UI Editor
        const editor = new toastui.Editor({
            el: editorContainer,
            height: '100%',
            initialEditType: 'markdown',
            previewStyle: 'vertical',
            initialValue: markdownBody,
            toolbarItems: [
                ['heading', 'bold', 'italic', 'strike'],
                ['hr', 'quote'],
                ['ul', 'ol', 'task', 'indent', 'outdent'],
                ['table', 'image', 'link'],
                ['code', 'codeblock']
            ]
        });

        editorInstance = editor;
        
        if (!isMarkdown) {
            editorInstance.changeMode('wysiwyg');
        }

        // Generate initial TOC
        if (isMarkdown && tocContainer) {
            try {
                updateToc(markdownBody, tocContainer, editorInstance, tocMaxDepth);
            } catch (error) {
                console.error('Error generating TOC:', error);
            }

            const debouncedUpdateToc = debounce(() => {
                const currentContent = editorInstance.getMarkdown();
                updateToc(currentContent, tocContainer, editorInstance, tocMaxDepth);
            }, 300);

            editorInstance.on('change', () => {
                debouncedUpdateToc();

                const instanceData = editorInstances.get(filePath);
                if (instanceData && !instanceData.isDirty) {
                    instanceData.isDirty = true;
                    updateFileDirtyStatus(filePath, true);
                    updateUnsavedCount();
                }
                saveButton.disabled = false;

                if (filePath === SCRATCHPAD_ID) updateScratchpadDownloadState();
            });

            // Scroll listener for TOC highlighting
            const mdPreview = editorInstance.getEditorElements().mdPreview;
            if (mdPreview) {
                let activeTimeout = null;
                let lastHeader = null;

                const updateActiveHeader = () => {
                    // Re-query live headings (TOC may have been regenerated)
                    const liveHeaders = mdPreview.querySelectorAll('h1, h2, h3, h4, h5, h6');
                    const previewRect = mdPreview.getBoundingClientRect();
                    // Use a threshold slightly below the top so a header touching
                    // the top edge counts as "active"
                    const threshold = previewRect.top + 4;
                    let activeHeader = null;
                    for (const header of liveHeaders) {
                        if (header.getBoundingClientRect().top <= threshold) {
                            activeHeader = header.textContent.trim();
                        } else {
                            break;
                        }
                    }
                    if (activeHeader !== lastHeader) {
                        lastHeader = activeHeader;
                        setActiveTocItem(tocContainer, activeHeader);
                    }
                };

                const onScroll = () => {
                    cancelAnimationFrame(activeTimeout);
                    activeTimeout = requestAnimationFrame(updateActiveHeader);
                };

                mdPreview.addEventListener('scroll', onScroll);
            }
        } else {
            editorInstance.on('change', () => {
                const instanceData = editorInstances.get(filePath);
                if (instanceData && !instanceData.isDirty) {
                    instanceData.isDirty = true;
                    updateFileDirtyStatus(filePath, true);
                    updateUnsavedCount();
                }
                saveButton.disabled = false;
            });
        }

        // Front matter change listener
        if (frontMatterTextarea) {
            frontMatterTextarea.addEventListener('input', () => {
                const instanceData = editorInstances.get(filePath);
                if (instanceData && !instanceData.isDirty) {
                    instanceData.isDirty = true;
                    updateFileDirtyStatus(filePath, true);
                    updateUnsavedCount();
                }
                saveButton.disabled = false;
            });
        }

        // Button event listeners
        saveButton.addEventListener('click', async () => {
            if (isScratchpad) {
                // For scratchpads, use Save As
                const content = editorInstance.getMarkdown();
                const savedHandle = await saveFileAs(content, 'untitled.md');
                if (savedHandle && hasFileSystemAccess) {
                    // Check if saved to current directory - add to file tree
                    if (directoryHandle) {
                        try {
                            // Try to get the file from the directory to verify it's there
                            const checkHandle = await directoryHandle.getFileHandle(savedHandle.name);
                            // File is in current directory, add to tree
                            fileTree.entries[savedHandle.name] = {
                                name: savedHandle.name,
                                type: 'file',
                                handle: checkHandle
                            };
                            renderFileTree();

                        } catch (e) {
                            // File not in current directory, that's fine
                        }
                    }
                    // Clear scratchpad content after successful save
                    editorInstance.setMarkdown('');
                    saveButton.disabled = true;
                    const instanceData = editorInstances.get(filePath);
                    if (instanceData) {
                        instanceData.isDirty = false;
                    }
                }
            } else {
                saveFile(filePath);
            }
        });

        if (reloadButton) {
            reloadButton.addEventListener('click', async () => {
                await reloadFileFromDisk(filePath);
            });
        }

        // Store instance data
        const instanceData = {
            editor: editor,
            fileViewContainer: fileViewContainer,
            tocContainer: tocContainer,
            saveButton: saveButton,
            reloadButton: reloadButton,
            frontMatterTextarea: frontMatterTextarea,
            frontMatterData: frontMatterData,
            fileHandle: fileHandle,
            lastModified: lastModified,
            isDirty: false
        };

        editorInstances.set(filePath, instanceData);

        return editorInstance;
    } catch (error) {
        console.error('Error initializing editor:', error);
        alert(`Error initializing Toast UI Editor: ${error}`);
        return null;
    }
}
