/**
 * MarkdownConverter Renderer Process
 * @version 4.4.2
 */

const { ipcRenderer } = require('electron');

// Shim window.electronAPI for main window which uses nodeIntegration
// without preload script (window.electronAPI is normally set by preload.js).
if (typeof window !== 'undefined' && !window.electronAPI) {
    window.electronAPI = {
        getAppVersion: () => ipcRenderer.invoke('get-app-version'),
        invoke: (channel, data) => ipcRenderer.invoke(channel, data),
        on: (channel, callback) => ipcRenderer.on(channel, (event, ...args) => callback(...args))
    };
}

const marked = require('marked');
const { markedHighlight } = require('marked-highlight');
const createDOMPurify = require('dompurify');
const DOMPurify = createDOMPurify(window);
const hljs = require('highlight.js');
const { createEditor } = require('./editor/codemirror-setup');
const { undo, redo } = require('@codemirror/commands');
// ModalManager is loaded via <script src="utils/ModalManager.js"> in index.html.
// It already exists in the global scope — re-declaring with let/const causes
// SyntaxError: "Identifier 'ModalManager' has already been declared".
if (typeof ModalManager === 'undefined') {
    const result = require('./utils/ModalManager');
    ModalManager = result.ModalManager || result;
}
// Lazy-loaded modules — defer heavy imports until first use
let _SidebarManager, _renderTemplatesPanel, _renderExplorerPanel, _renderGitPanel, _renderSnippetsPanel;
let _ReplPanel, _CommandPalette, _PrintPreview, _createWelcomeContent;

function getSidebarManager() { if (!_SidebarManager) _SidebarManager = require('./sidebar/sidebar-manager').SidebarManager; return _SidebarManager; }
function getRenderTemplatesPanel() { if (!_renderTemplatesPanel) _renderTemplatesPanel = require('./sidebar/templates-panel').renderTemplatesPanel; return _renderTemplatesPanel; }
function getRenderExplorerPanel() { if (!_renderExplorerPanel) _renderExplorerPanel = require('./sidebar/explorer-panel').renderExplorerPanel; return _renderExplorerPanel; }
function getRenderGitPanel() { if (!_renderGitPanel) _renderGitPanel = require('./sidebar/git-panel').renderGitPanel; return _renderGitPanel; }
function getRenderSnippetsPanel() { if (!_renderSnippetsPanel) _renderSnippetsPanel = require('./sidebar/snippets-panel').renderSnippetsPanel; return _renderSnippetsPanel; }
let _renderOutlinePanel;
function getRenderOutlinePanel() { if (!_renderOutlinePanel) _renderOutlinePanel = require('./sidebar/outline-panel').renderOutlinePanel; return _renderOutlinePanel; }
function getReplPanel() { if (!_ReplPanel) _ReplPanel = require('./repl/repl-panel').ReplPanel; return _ReplPanel; }
function getCommandPalette() { if (!_CommandPalette) _CommandPalette = require('./command-palette').CommandPalette; return _CommandPalette; }
function getPrintPreview() { if (!_PrintPreview) _PrintPreview = require('./print-preview').PrintPreview; return _PrintPreview; }
function getCreateWelcomeContent() { if (!_createWelcomeContent) _createWelcomeContent = require('./welcome').createWelcomeContent; return _createWelcomeContent; }
let _ZenMode;
function getZenMode() { if (!_ZenMode) _ZenMode = require('./zen-mode').ZenMode; return _ZenMode; }
let _showAnalyticsModal;
function getShowAnalyticsModal() { if (!_showAnalyticsModal) _showAnalyticsModal = require('./analytics/analytics-panel').showAnalyticsModal; return _showAnalyticsModal; }

function ensureToastContainer() {
    let container = document.getElementById('app-toast-container');
    if (!container) {
        container = document.createElement('div');
        container.id = 'app-toast-container';
        container.className = 'app-toast-container';
        document.body.appendChild(container);
    }
    return container;
}

function notifyUser(message, type = 'info', options = {}) {
    if (!message) return;

    const { duration = 3500 } = options;
    const container = ensureToastContainer();
    const toast = document.createElement('div');
    toast.className = `app-toast app-toast-${type}`;
    toast.setAttribute('role', type === 'warning' ? 'alert' : 'status');
    toast.textContent = message;
    container.appendChild(toast);

    requestAnimationFrame(() => {
        toast.classList.add('visible');
    });

    const dismiss = () => {
        toast.classList.remove('visible');
        setTimeout(() => toast.remove(), 180);
    };

    if (duration > 0) {
        setTimeout(dismiss, duration);
    }

    toast.addEventListener('click', dismiss);
    return toast;
}

// Configure marked with highlight extension
marked.use(markedHighlight({
    highlight: function(code, lang) {
        if (lang && hljs.getLanguage(lang)) {
            try {
                return hljs.highlight(code, { language: lang }).value;
            } catch (err) {
                console.warn('Syntax highlighting failed for language:', lang, err.message);
            }
        }
        return hljs.highlightAuto(code).value;
    }
}));

marked.use({
    breaks: true,
    gfm: true
});

// Footnotes support
const markedFootnote = require('marked-footnote');
marked.use(markedFootnote());

// Admonitions support (:::note, :::warning, :::tip, :::danger, :::info)
marked.use({
    extensions: [{
        name: 'admonition',
        level: 'block',
        start(src) { return src.match(/^:::(note|warning|tip|danger|info)/m)?.index; },
        tokenizer(src) {
            const match = src.match(/^:::(note|warning|tip|danger|info)\s*\n([\s\S]*?)^:::\s*$/m);
            if (match && match.index === 0) {
                const admonitionType = match[1];
                const text = match[2].trim();
                const tokens = [];
                this.lexer.blockTokens(text, tokens);
                return {
                    type: 'admonition',
                    raw: match[0],
                    admonitionType,
                    text,
                    tokens
                };
            }
        },
        renderer(token) {
            const icons = { note: '\u2139', warning: '\u26A0', tip: '\uD83D\uDCA1', danger: '\uD83D\uDD34', info: '\u2139' };
            const icon = icons[token.admonitionType] || '\u2139';
            const inner = this.parser.parse(token.tokens || []);
            return `<div class="admonition admonition-${token.admonitionType}">
                <div class="admonition-title">${icon} ${token.admonitionType.charAt(0).toUpperCase() + token.admonitionType.slice(1)}</div>
                <div class="admonition-content">${inner}</div>
            </div>`;
        }
    }]
});

// PlantUML hex encoding for server rendering
function plantumlEncode(text) {
    const hex = Array.from(new TextEncoder().encode(text))
        .map(b => b.toString(16).padStart(2, '0'))
        .join('');
    return '~h' + hex;
}

// Scopes user custom CSS by prefixing all selectors to protect application UI
function scopeCSS(cssText, scopeSelector) {
    if (!cssText) return '';
    return cssText.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|(?=[^{]*{))/g, (match, selector, separator) => {
        const trimmed = selector.trim();
        if (!trimmed || trimmed.startsWith('@') || trimmed.startsWith(':root') || trimmed.startsWith('from') || trimmed.startsWith('to') || /^\d+%$/.test(trimmed)) {
            return match;
        }
        return scopeSelector + ' ' + trimmed + (separator || '');
    });
}

// Module-level reference set by DOMContentLoaded after sidebar registration
const outlinePanelContainer = null;

// Tab Management
class TabManager {
    constructor() {
        this.tabs = new Map();
        this.activeTabId = 1;
        this.nextTabId = 2;
        this.isPreviewVisible = true;
        this.showLineNumbers = false;
        this.autoSaveInterval = null;
        this.autoSaveDelay = 30000; // 30 seconds
        this.recentFiles = JSON.parse(localStorage.getItem('recentFiles') || '[]');
        this.previewDebounceTimers = new Map(); // Debounce timers per tab
        this.previewDebounceDelay = 300; // 300ms debounce
        this.previewCache = new Map(); // Performance optimization render cache

        // Initialize first tab
        this.tabs.set(1, {
            id: 1,
            title: 'Untitled',
            content: '',
            filePath: null,
            isDirty: false,
            editorView: null,
            findMatches: [],
            currentMatchIndex: -1,
            type: 'markdown', // 'markdown' or 'pdf'
            // PDF-specific state
            pdfDoc: null,
            pdfCurrentPage: 1,
            pdfZoomLevel: 1.0,
            pdfRotation: 0
        });

        this.setupEventListeners();
        this.updateUI();
    }
    
    setupEventListeners() {
        // Tab bar events
        document.getElementById('new-tab-btn').addEventListener('click', () => this.createNewTab());
        document.getElementById('tab-bar').addEventListener('click', (e) => {
            if (e.target.classList.contains('tab-close')) {
                e.stopPropagation();
                const tabId = parseInt(e.target.closest('.tab').dataset.tabId);
                this.closeTab(tabId);
            } else if (e.target.closest('.tab')) {
                const tabId = parseInt(e.target.closest('.tab').dataset.tabId);
                this.switchToTab(tabId);
            }
        });
        
        // Editor events for active tab
        this.setupEditorEvents();
        
        // Toolbar events
        this.setupToolbarEvents();
        
        // Find dialog events
        this.setupFindEvents();
        
        // Keyboard shortcuts
        document.addEventListener('keydown', (e) => {
            if (e.ctrlKey || e.metaKey) {
                switch (e.key) {
                    case 'n':
                    case 't':
                        e.preventDefault();
                        this.createNewTab();
                        break;
                    case 'w':
                        if (this.tabs.size > 1) {
                            e.preventDefault();
                            this.closeTab(this.activeTabId);
                        }
                        break;
                    case 'Tab':
                        if (this.tabs.size > 1) {
                            e.preventDefault();
                            this.switchToNextTab();
                        }
                        break;
                }
            }
        });
    }
    
    createNewTab(type = 'markdown') {
        const newTabId = this.nextTabId++;
        const tab = {
            id: newTabId,
            title: type === 'pdf' ? 'PDF Document' : 'Untitled',
            content: '',
            filePath: null,
            isDirty: false,
            editorView: null,
            findMatches: [],
            currentMatchIndex: -1,
            type: type, // 'markdown' or 'pdf'
            // PDF-specific state
            pdfDoc: null,
            pdfCurrentPage: 1,
            pdfZoomLevel: 1.0,
            pdfRotation: 0
        };

        this.tabs.set(newTabId, tab);
        this.createTabElements(tab);
        this.switchToTab(newTabId);
        this.startAutoSave();
        this.updateTabBar();
        console.log('createNewTab: tab created with type:', type);
    }

    createPdfTab(filePath) {
        const newTabId = this.nextTabId++;
        const fileName = require('path').basename(filePath);
        const tab = {
            id: newTabId,
            title: fileName,
            content: '',
            filePath: filePath,
            isDirty: false,
            editorView: null,
            findMatches: [],
            currentMatchIndex: -1,
            type: 'pdf',
            // PDF-specific state
            pdfDoc: null,
            pdfCurrentPage: 1,
            pdfZoomLevel: 1.0,
            pdfRotation: 0
        };

        this.tabs.set(newTabId, tab);
        this.createPdfTabElements(tab);
        this.switchToTab(newTabId);
        this.loadPdfInTab(tab.id, filePath);
        this.updateTabBar();
        return tab.id;
    }

    createPdfTabElements(tab) {
        // Create PDF tab content container
        const tabContent = document.createElement('div');
        tabContent.className = 'tab-content';
        tabContent.id = `tab-content-${tab.id}`;
        tabContent.dataset.tabId = tab.id;
        tabContent.dataset.tabType = 'pdf';

        tabContent.innerHTML = `
            <div class="pdf-tab-container" id="pdf-container-${tab.id}">
                <div class="pdf-controls">
                    <button class="pdf-nav-btn" data-action="prev" title="Previous Page">◀</button>
                    <input type="number" class="pdf-page-input" id="pdf-page-${tab.id}" value="1" min="1">
                    <span class="pdf-page-info">/ <span id="pdf-total-${tab.id}">1</span></span>
                    <button class="pdf-nav-btn" data-action="next" title="Next Page">▶</button>
                    <button class="pdf-zoom-btn" data-action="zoom-out" title="Zoom Out">−</button>
                    <span class="pdf-zoom-level" id="pdf-zoom-${tab.id}">100%</span>
                    <button class="pdf-zoom-btn" data-action="zoom-in" title="Zoom In">+</button>
                    <button class="pdf-zoom-btn" data-action="fit-width" title="Fit Width">↔</button>
                    <button class="pdf-rotate-btn" data-action="rotate-left" title="Rotate Left">↺</button>
                    <button class="pdf-rotate-btn" data-action="rotate-right" title="Rotate Right">↻</button>
                </div>
                <div class="pdf-canvas-container">
                    <canvas id="pdf-canvas-${tab.id}"></canvas>
                </div>
            </div>
        `;

        document.querySelector('.editor-container').appendChild(tabContent);

        // Add event listeners for PDF controls
        this.setupPdfTabEvents(tab.id);
    }

    setupPdfTabEvents(tabId) {
        const container = document.getElementById(`pdf-container-${tabId}`);
        if (!container) return;

        container.addEventListener('click', async (e) => {
            const action = e.target.dataset.action;
            if (!action) return;

            const tab = this.tabs.get(tabId);
            if (!tab || !tab.pdfDoc) return;

            switch (action) {
                case 'prev':
                    if (tab.pdfCurrentPage > 1) {
                        tab.pdfCurrentPage--;
                        await this.renderPdfPageInTab(tabId);
                    }
                    break;
                case 'next':
                    if (tab.pdfCurrentPage < tab.pdfDoc.numPages) {
                        tab.pdfCurrentPage++;
                        await this.renderPdfPageInTab(tabId);
                    }
                    break;
                case 'zoom-out':
                    if (tab.pdfZoomLevel > 0.25) {
                        tab.pdfZoomLevel -= 0.25;
                        await this.renderPdfPageInTab(tabId);
                    }
                    break;
                case 'zoom-in':
                    if (tab.pdfZoomLevel < 4.0) {
                        tab.pdfZoomLevel += 0.25;
                        await this.renderPdfPageInTab(tabId);
                    }
                    break;
                case 'fit-width':
                    const page = await tab.pdfDoc.getPage(tab.pdfCurrentPage);
                    const viewport = page.getViewport({ scale: 1, rotation: tab.pdfRotation });
                    const containerWidth = container.querySelector('.pdf-canvas-container').clientWidth - 40;
                    tab.pdfZoomLevel = containerWidth / viewport.width;
                    await this.renderPdfPageInTab(tabId);
                    break;
                case 'rotate-left':
                    tab.pdfRotation = (tab.pdfRotation - 90 + 360) % 360;
                    await this.renderPdfPageInTab(tabId);
                    break;
                case 'rotate-right':
                    tab.pdfRotation = (tab.pdfRotation + 90) % 360;
                    await this.renderPdfPageInTab(tabId);
                    break;
            }
        });

        // Page input handler
        const pageInput = document.getElementById(`pdf-page-${tabId}`);
        if (pageInput) {
            pageInput.addEventListener('change', async (e) => {
                const tab = this.tabs.get(tabId);
                const pageNum = parseInt(e.target.value);
                if (tab && tab.pdfDoc && pageNum >= 1 && pageNum <= tab.pdfDoc.numPages) {
                    tab.pdfCurrentPage = pageNum;
                    await this.renderPdfPageInTab(tabId);
                }
            });
        }
    }

    async loadPdfInTab(tabId, filePath) {
        const tab = this.tabs.get(tabId);
        if (!tab) return;

        try {
            document.getElementById('status-text').textContent = 'Loading PDF...';

            const loadingTask = getPdfjsLib().getDocument(filePath);
            tab.pdfDoc = await loadingTask.promise;
            tab.pdfCurrentPage = 1;
            tab.pdfZoomLevel = 1.0;
            tab.pdfRotation = 0;

            // Update UI
            document.getElementById(`pdf-total-${tabId}`).textContent = tab.pdfDoc.numPages;
            document.getElementById(`pdf-page-${tabId}`).value = 1;
            document.getElementById(`pdf-page-${tabId}`).max = tab.pdfDoc.numPages;
            document.getElementById(`pdf-zoom-${tabId}`).textContent = '100%';

            await this.renderPdfPageInTab(tabId);

            document.getElementById('status-text').textContent = `PDF: ${tab.title} (${tab.pdfDoc.numPages} pages)`;
        } catch (error) {
            console.error('Error loading PDF:', error);
            document.getElementById('status-text').textContent = 'Error loading PDF';
            notifyUser(`Error loading PDF: ${error.message}`, 'warning');
        }
    }

    async renderPdfPageInTab(tabId) {
        const tab = this.tabs.get(tabId);
        if (!tab || !tab.pdfDoc) return;

        try {
            const page = await tab.pdfDoc.getPage(tab.pdfCurrentPage);
            const canvas = document.getElementById(`pdf-canvas-${tabId}`);
            if (!canvas) return;

            const ctx = canvas.getContext('2d');
            const viewport = page.getViewport({ scale: tab.pdfZoomLevel, rotation: tab.pdfRotation });

            canvas.width = viewport.width;
            canvas.height = viewport.height;

            await page.render({
                canvasContext: ctx,
                viewport: viewport
            }).promise;

            // Update UI
            document.getElementById(`pdf-page-${tabId}`).value = tab.pdfCurrentPage;
            document.getElementById(`pdf-zoom-${tabId}`).textContent = Math.round(tab.pdfZoomLevel * 100) + '%';
        } catch (error) {
            console.error('Error rendering PDF page:', error);
        }
    }
    
    createTabElements(tab) {
        // Create tab content container
        const tabContent = document.createElement('div');
        tabContent.className = 'tab-content';
        tabContent.id = `tab-content-${tab.id}`;
        tabContent.dataset.tabId = tab.id;

        tabContent.innerHTML = `
            <div id="editor-pane-${tab.id}" class="pane">
                <div class="editor-wrapper">
                    <div id="editor-cm-${tab.id}" class="codemirror-container"></div>
                </div>
            </div>
            <div class="pane-resizer" id="pane-resizer-${tab.id}" title="Drag to resize"></div>
            <div id="preview-pane-${tab.id}" class="pane">
                <div id="preview-${tab.id}" class="preview-content"></div>
            </div>
        `;

        document.querySelector('.editor-container').appendChild(tabContent);

        // Initialize CodeMirror editor
        this.ensureEditor(tab);
    }
    
    switchToTab(tabId) {
        if (!this.tabs.has(tabId)) return;
        
        // Save current tab state before switching
        if (this.activeTabId && this.tabs.has(this.activeTabId)) {
            this.saveCurrentTabState();
        }
        
        this.activeTabId = tabId;
        this.updateUI();
        this.restoreTabState(tabId);
        this.focusActiveEditor();
        this.updateFilePath();
        this.updateBreadcrumb();

        // Update cursor position for the newly active tab
        const tabForCursor = this.tabs.get(tabId);
        if (tabForCursor?.editorView) {
            this.updateCursorPosition(tabForCursor.editorView);
        }

        // Notify main process about current file for exports
        const tab = this.tabs.get(tabId);
        ipcRenderer.send('set-current-file', tab?.filePath || null);

        // Refresh outline panel for new tab content
        if (outlinePanelContainer?._refreshOutline) outlinePanelContainer._refreshOutline();
    }
    
    switchToNextTab() {
        const tabIds = Array.from(this.tabs.keys());
        const currentIndex = tabIds.indexOf(this.activeTabId);
        const nextIndex = (currentIndex + 1) % tabIds.length;
        this.switchToTab(tabIds[nextIndex]);
    }
    
    closeTab(tabId) {
        if (this.tabs.size === 1) return; // Don't close the last tab

        const tab = this.tabs.get(tabId);
        if (!tab) return;

        if (tab.isDirty && tab.type === 'markdown') {
            // Show confirmation dialog for unsaved changes (only for markdown)
            const result = confirm('You have unsaved changes. Do you want to close this tab without saving?');
            if (!result) return;
        }

        // Destroy CodeMirror view (for markdown tabs)
        if (tab?.editorView) {
            tab.editorView.destroy();
        }

        // Destroy PDF document (for PDF tabs)
        if (tab?.pdfDoc) {
            try {
                tab.pdfDoc.destroy();
            } catch (e) {
                console.warn('Error destroying PDF:', e);
            }
        }

        // Remove tab elements
        const tabElement = document.querySelector(`.tab[data-tab-id="${tabId}"]`);
        const tabContent = document.getElementById(`tab-content-${tabId}`);

        if (tabElement?.classList.contains('tab')) {
            tabElement.remove();
        }
        if (tabContent) {
            tabContent.remove();
        }

        this.tabs.delete(tabId);
        
        // Switch to another tab if this was active
        if (this.activeTabId === tabId) {
            const remainingTabs = Array.from(this.tabs.keys());
            this.switchToTab(remainingTabs[0]);
        }
        
        this.updateTabBar();
    }
    
    updateTabBar() {
        const tabBar = document.getElementById('tab-bar');
        const existingTabs = tabBar.querySelectorAll('.tab');
        
        // Remove all existing tab elements except the new tab button
        existingTabs.forEach(tab => tab.remove());
        
        // Add tabs in order
        const sortedTabs = Array.from(this.tabs.values()).sort((a, b) => a.id - b.id);
        const newTabBtn = document.getElementById('new-tab-btn');
        
        sortedTabs.forEach(tab => {
            const tabElement = document.createElement('div');
            const typeClass = tab.type === 'pdf' ? 'pdf-tab' : 'markdown-tab';
            tabElement.className = `tab ${typeClass} ${tab.id === this.activeTabId ? 'active' : ''}`;
            tabElement.dataset.tabId = tab.id;
            tabElement.dataset.tabType = tab.type || 'markdown';

            const title = tab.filePath ?
                tab.filePath.split('/').pop() :
                tab.title;

            const dirtyIndicator = tab.isDirty ? ' •' : '';
            const typeIndicator = tab.type === 'pdf' ? '📄 ' : '';

            tabElement.innerHTML = `
                <span class="tab-title">${typeIndicator}${title}${dirtyIndicator}</span>
                <button class="tab-close" title="Close tab">×</button>
            `;

            tabBar.insertBefore(tabElement, newTabBtn);
        });
    }

    updateUI() {
        // Show/hide tab contents
        document.querySelectorAll('.tab-content').forEach(content => {
            content.classList.remove('active');
        });

        const activeContent = document.getElementById(`tab-content-${this.activeTabId}`);
        if (activeContent) {
            activeContent.classList.add('active');
        }

        // Get active tab to check type
        const activeTab = this.tabs.get(this.activeTabId);

        // Show/hide toolbar based on tab type
        const toolbar = document.querySelector('.toolbar');
        if (toolbar) {
            if (activeTab?.type === 'pdf') {
                toolbar.classList.add('hidden');
            } else {
                toolbar.classList.remove('hidden');
            }
        }

        // Update preview visibility (only for markdown tabs)
        if (activeTab?.type !== 'pdf') {
            this.updatePreviewVisibility();
            this.updateLineNumbers();
        }

        this.updateTabBar();
    }
    
    saveCurrentTabState() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab) return;

        if (tab.editorView) {
            tab.content = tab.editorView.state.doc.toString();
            tab.isDirty = tab.content !== (tab.originalContent || '');
        }
    }
    
    restoreTabState(tabId) {
        const tab = this.tabs.get(tabId);
        if (!tab) return;

        if (tab.editorView) {
            this.setEditorContent(tabId, tab.content);
            this.updatePreview(tabId, true); // immediate=true for tab switches
            this.updateWordCount();
        }
    }
    
    focusActiveEditor() {
        const tab = this.tabs.get(this.activeTabId);
        if (tab?.editorView) {
            tab.editorView.focus();
        }
    }
    
    updatePreview(tabId = this.activeTabId, immediate = false) {
        const tab = this.tabs.get(tabId);
        if (!tab || tab.type === 'pdf') return;

        // Guard against auto-renders in large file mode
        if (tab.largeFileMode && !immediate) {
            return;
        }

        // Clear existing debounce timer for this tab
        if (this.previewDebounceTimers.has(tabId)) {
            clearTimeout(this.previewDebounceTimers.get(tabId));
        }

        // If immediate, render right away (for tab switches, file loads)
        if (immediate) {
            this._renderPreview(tabId);
            return;
        }

        // Debounce preview rendering for typing performance
        this.previewDebounceTimers.set(tabId, setTimeout(() => {
            this._renderPreview(tabId);
            this.previewDebounceTimers.delete(tabId);
        }, this.previewDebounceDelay));
    }

    _hash(str) {
        if (!str) return 0;
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            hash = ((hash << 5) - hash) + str.charCodeAt(i);
            hash |= 0; // Convert to 32bit integer
        }
        return hash;
    }

    _renderPreview(tabId) {
        const tab = this.tabs.get(tabId);
        const preview = document.getElementById(`preview-${tabId}`);
        console.log('[_renderPreview] tabId:', tabId, 'tab exists:', !!tab, 'preview exists:', !!preview, 'content length:', tab?.content?.length);

        if (!tab || !preview) return;

        try {
            // Check if libraries are available
            if (!marked || !DOMPurify) {
                console.error('[_renderPreview] Libraries not available:', { marked: !!marked, DOMPurify: !!DOMPurify });
                preview.innerHTML = '<div class="preview-error"><div class="preview-error-icon">⚠️</div><div class="preview-error-title">Libraries Not Loaded</div><div class="preview-error-message">Required libraries (marked/DOMPurify) could not be loaded. Please check your installation.</div></div>';
                return;
            }

            // Cache lookup
            const contentHash = this._hash(tab.content);
            let sanitizedHtml;
            if (this.previewCache.has(contentHash)) {
                console.log('[_renderPreview] Cache hit for hash:', contentHash);
                sanitizedHtml = this.previewCache.get(contentHash);
            } else {
                console.log('[_renderPreview] Cache miss. About to call marked.parse, content length:', tab.content.length);
                const html = marked.parse(tab.content);
                console.log('[_renderPreview] marked.parse returned type:', typeof html, 'isPromise:', html instanceof Promise);
                if (html instanceof Promise) {
                    console.error('[_renderPreview] marked.parse returned a Promise! Need to await it.');
                    return;
                }
                sanitizedHtml = DOMPurify.sanitize(html);
                console.log('[_renderPreview] DOMPurify.sanitize returned, length:', sanitizedHtml.length);

                // Add to cache and maintain cache size limit (100 entries)
                this.previewCache.set(contentHash, sanitizedHtml);
                if (this.previewCache.size > 100) {
                    const oldestKey = this.previewCache.keys().next().value;
                    this.previewCache.delete(oldestKey);
                }
            }

            // TOC generation
            if (sanitizedHtml.includes('[[toc]]') || sanitizedHtml.includes('[TOC]')) {
                const headingRegex = /<h([1-6])[^>]*>(.*?)<\/h[1-6]>/gi;
                let tocMatch;
                const toc = [];
                const tempHtml = sanitizedHtml;
                while ((tocMatch = headingRegex.exec(tempHtml)) !== null) {
                    const level = parseInt(tocMatch[1]);
                    const text = tocMatch[2].replace(/<[^>]+>/g, '');
                    const id = text.toLowerCase().replace(/[^\w]+/g, '-');
                    toc.push({ level, text, id });
                }

                if (toc.length > 0) {
                    const tocHtml = '<nav class="toc"><h2>Table of Contents</h2><ul>' +
                        toc.map(h => `<li class="toc-h${h.level}"><a href="#${h.id}">${h.text}</a></li>`).join('') +
                        '</ul></nav>';
                    sanitizedHtml = sanitizedHtml.replace(/\[\[toc\]\]|\[TOC\]/gi, tocHtml);

                    // Add IDs to headings for anchor links
                    toc.forEach(h => {
                        sanitizedHtml = sanitizedHtml.replace(
                            new RegExp(`(<h${h.level}[^>]*)>`, 'i'),
                            `$1 id="${h.id}">`
                        );
                    });
                }
            }

            preview.innerHTML = sanitizedHtml;

            // Render math expressions if KaTeX is available
            if (window.katex && window.renderMathInElement) {
                try {
                    window.renderMathInElement(preview, {
                        delimiters: [
                            {left: '$$', right: '$$', display: true},
                            {left: '$', right: '$', display: false},
                            {left: '\\[', right: '\\]', display: true},
                            {left: '\\(', right: '\\)', display: false}
                        ]
                    });
                } catch (mathError) {
                    console.warn('Math rendering error:', mathError);
                }
            }

            // Render Mermaid diagrams — lazy-load mermaid only when needed
            const mermaidBlocks = preview.querySelectorAll('pre code.language-mermaid');
            if (mermaidBlocks.length > 0) {
                try {
                    // Lazy-load mermaid on first use
                    if (!window.mermaid) {
                        const mermaidModule = require('mermaid');
                        window.mermaid = mermaidModule.default || mermaidModule;
                    }

                    mermaidBlocks.forEach((block) => {
                        const code = block.textContent;
                        const pre = block.parentElement;
                        const mermaidDiv = document.createElement('div');
                        mermaidDiv.className = 'mermaid';
                        mermaidDiv.setAttribute('data-processed', 'true');
                        mermaidDiv.textContent = code;
                        pre.parentElement.replaceChild(mermaidDiv, pre);
                    });

                    const theme = document.body.className.includes('theme-dark') ? 'dark' : 'default';
                    window.mermaid.initialize({ startOnLoad: false, theme, securityLevel: 'loose' });
                    window.mermaid.run({ querySelector: '.mermaid:not([data-rendered])' }).then(() => {
                        preview.querySelectorAll('.mermaid').forEach(el => {
                            el.setAttribute('data-rendered', 'true');
                        });
                    });
                } catch (mermaidError) {
                    console.warn('Mermaid rendering error:', mermaidError);
                }
            }

            // Render PlantUML diagrams
            const plantumlBlocks = preview.querySelectorAll('pre code.language-plantuml');
            plantumlBlocks.forEach((block) => {
                const code = block.textContent;
                const pre = block.parentElement;

                // Encode for PlantUML server using hex encoding
                const encoded = plantumlEncode(code);

                const img = document.createElement('img');
                img.src = `https://www.plantuml.com/plantuml/svg/${encoded}`;
                img.alt = 'PlantUML diagram';
                img.style.maxWidth = '100%';
                img.onerror = () => {
                    img.replaceWith(pre); // Fallback to code block on error
                };

                pre.parentElement.replaceChild(img, pre);
            });

            // Add Run buttons to executable code blocks (REPL)
            const codeBlocks = preview.querySelectorAll('pre code[class*="language-"]');
            codeBlocks.forEach(block => {
                const lang = block.className.match(/language-(\w+)/)?.[1];
                if (['javascript', 'js', 'python', 'py', 'bash', 'sh'].includes(lang)) {
                    const runBtn = document.createElement('button');
                    runBtn.className = 'code-run-btn';
                    runBtn.textContent = '\u25B6 Run';
                    runBtn.addEventListener('click', async () => {
                        if (replPanel) {
                            replPanel.show();
                            const result = await ipcRenderer.invoke('execute-code', { code: block.textContent, language: lang });
                            replPanel.appendOutput(`[${lang}]`, result);
                        }
                    });
                    block.parentElement.style.position = 'relative';
                    block.parentElement.appendChild(runBtn);
                }
            });
        } catch (error) {
            console.error('Error rendering preview:', error);
            preview.innerHTML = '<p class="error">Error rendering preview. Please check your markdown syntax.</p>';
        }
    }
    
    updatePreviewVisibility() {
        document.querySelectorAll('.tab-content').forEach(content => {
            const previewPane = content.querySelector('.pane:last-child');
            const editorPane = content.querySelector('.pane:first-child');
            
            if (this.isPreviewVisible) {
                previewPane.classList.remove('hidden');
                editorPane.classList.remove('full-width');
            } else {
                previewPane.classList.add('hidden');
                editorPane.classList.add('full-width');
            }
        });
    }
    
    updateLineNumbers() {
        // CodeMirror handles line numbers natively — this is now a no-op.
        // Line number visibility is controlled via the showLineNumbers option
        // passed to createEditor().
    }
    
    updateWordCount() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab) return;

        const content = tab.content;
        const words = content.trim() ? content.trim().split(/\s+/).filter(word => word.length > 0).length : 0;
        const chars = content.length;

        const wordEl = document.getElementById('word-count');
        const charEl = document.getElementById('char-count');
        if (wordEl) wordEl.textContent = `Words: ${words}`;
        if (charEl) charEl.textContent = `Chars: ${chars}`;
    }

    updateCursorPosition(view) {
        if (!view) return;
        const pos = view.state.selection.main.head;
        const line = view.state.doc.lineAt(pos);
        const lineCol = document.getElementById('line-col');
        if (lineCol) lineCol.textContent = `Ln ${line.number}, Col ${pos - line.from + 1}`;
    }

    updateFilePath() {
        const tab = this.tabs.get(this.activeTabId);
        const el = document.getElementById('status-file-path');
        if (el && tab) {
            el.textContent = tab.filePath || 'Untitled';
            el.title = tab.filePath || '';
        }
    }

    updateBreadcrumb() {
        const tab = this.tabs.get(this.activeTabId);
        const el = document.getElementById('breadcrumb-path');
        if (el && tab) {
            el.textContent = tab.filePath || 'Untitled';
            el.title = tab.filePath || '';
        }
    }
    
    setupEditorEvents() {
        // CodeMirror handles editor events via the onChange callback
        // passed to createEditor(). No additional event delegation needed.
    }
    
    handleEditorInput(tabId) {
        // CodeMirror's onChange callback handles content syncing.
        // This method is kept for any remaining callers but is largely a no-op now.
        const tab = this.tabs.get(tabId);
        if (!tab) return;

        if (tab.editorView) {
            tab.content = tab.editorView.state.doc.toString();
        }
        tab.isDirty = true;

        this.updatePreview(tabId);
        this.updateWordCount();
        this.updateTabBar();
    }
    
    // Auto-save functionality
    startAutoSave() {
        if (this.autoSaveInterval) {
            clearInterval(this.autoSaveInterval);
        }

        this.autoSaveInterval = setInterval(() => {
            this.performAutoSave();
        }, this.autoSaveDelay);
    }

    stopAutoSave() {
        if (this.autoSaveInterval) {
            clearInterval(this.autoSaveInterval);
            this.autoSaveInterval = null;
        }
    }

    performAutoSave() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab || !tab.filePath || !tab.content) return;

        // Only auto-save if content has changed since last save
        if (tab.lastSavedContent !== tab.content) {
            ipcRenderer.send('save-file', { path: tab.filePath, content: tab.content });
            tab.lastSavedContent = tab.content;

            // Show brief auto-save indicator
            this.showAutoSaveIndicator();
        }
    }

    showAutoSaveIndicator() {
        const indicator = document.createElement('div');
        indicator.textContent = 'Auto-saved';
        indicator.className = 'auto-save-indicator';
        document.body.appendChild(indicator);

        setTimeout(() => {
            indicator.classList.add('fade-out');
            setTimeout(() => {
                if (indicator.parentNode) {
                    indicator.parentNode.removeChild(indicator);
                }
            }, 300);
        }, 1500);
    }

    // Recent files functionality
    addToRecentFiles(filePath) {
        if (!filePath) return;

        // Remove if already exists
        this.recentFiles = this.recentFiles.filter(f => f !== filePath);

        // Add to beginning
        this.recentFiles.unshift(filePath);

        // Keep only last 10 files
        this.recentFiles = this.recentFiles.slice(0, 10);

        // Save to localStorage and sync with main process
        localStorage.setItem('recentFiles', JSON.stringify(this.recentFiles));
        ipcRenderer.send('save-recent-files', this.recentFiles);
    }

    getRecentFiles() {
        return this.recentFiles.filter(file => {
            // Check if file still exists (basic check by trying to access it)
            try {
                return file && file.length > 0;
            } catch (e) {
                return false;
            }
        });
    }

    setupToolbarEvents() {
        // Bold
        document.getElementById('btn-bold').addEventListener('click', () => {
            this.wrapSelection('**', '**');
        });

        // Italic
        document.getElementById('btn-italic').addEventListener('click', () => {
            this.wrapSelection('*', '*');
        });

        // Heading
        document.getElementById('btn-heading').addEventListener('click', () => {
            this.insertAtLineStart('## ');
        });

        // Link
        document.getElementById('btn-link').addEventListener('click', () => {
            this.wrapSelection('[', '](url)');
        });

        // Code
        document.getElementById('btn-code').addEventListener('click', () => {
            this.wrapSelection('`', '`');
        });

        // List
        document.getElementById('btn-list').addEventListener('click', () => {
            this.insertAtLineStart('- ');
        });

        // Quote
        document.getElementById('btn-quote').addEventListener('click', () => {
            this.insertAtLineStart('> ');
        });

        // Table
        document.getElementById('btn-table').addEventListener('click', () => {
            this.insertTable();
        });

        // Strikethrough
        document.getElementById('btn-strikethrough').addEventListener('click', () => {
            this.wrapSelection('~~', '~~');
        });

        // Code Block
        document.getElementById('btn-code-block').addEventListener('click', () => {
            this.insertCodeBlock();
        });

        // Horizontal Rule
        document.getElementById('btn-horizontal-rule').addEventListener('click', () => {
            this.insertHorizontalRule();
        });

        // Preview toggle
        document.getElementById('btn-preview-toggle').addEventListener('click', () => {
            this.isPreviewVisible = !this.isPreviewVisible;
            this.updatePreviewVisibility();
        });

        // Line numbers
        document.getElementById('btn-line-numbers').addEventListener('click', () => {
            this.showLineNumbers = !this.showLineNumbers;
            this.updateLineNumbers();
        });
    }

    // Helper function to wrap selected text
    wrapSelection(before, after) {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab?.editorView) return;

        const view = tab.editorView;
        const { from, to } = view.state.selection.main;
        const selectedText = view.state.sliceDoc(from, to);
        const replacement = before + (selectedText || 'text') + after;

        view.dispatch({
            changes: { from, to, insert: replacement }
        });
        view.focus();
    }

    // Helper function to insert text at the start of current line
    insertAtLineStart(prefix) {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab?.editorView) return;

        const view = tab.editorView;
        const pos = view.state.selection.main.head;
        const line = view.state.doc.lineAt(pos);

        view.dispatch({
            changes: { from: line.from, insert: prefix }
        });
        view.focus();
    }

    // Insert a markdown table
    insertTable() {
        const table = '\n| Column 1 | Column 2 | Column 3 |\n' +
                     '|----------|----------|----------|\n' +
                     '| Cell 1   | Cell 2   | Cell 3   |\n' +
                     '| Cell 4   | Cell 5   | Cell 6   |\n';

        this.insertAtCursor(table);
    }

    // Insert a code block
    insertCodeBlock() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab?.editorView) return;

        const view = tab.editorView;
        const { from, to } = view.state.selection.main;
        const selectedText = view.state.sliceDoc(from, to);
        const codeBlock = '\n```\n' + (selectedText || 'code here') + '\n```\n';

        view.dispatch({
            changes: { from, to, insert: codeBlock }
        });
        view.focus();
    }

    // Insert a horizontal rule
    insertHorizontalRule() {
        this.insertAtCursor('\n\n---\n\n');
    }
    
    setupFindEvents() {
        const btnFind = document.getElementById('btn-find');
        const btnFindClose = document.getElementById('btn-find-close');
        const findInput = document.getElementById('find-input');
        const btnFindNext = document.getElementById('btn-find-next');
        const btnFindPrev = document.getElementById('btn-find-prev');
        const btnReplace = document.getElementById('btn-replace');
        const btnReplaceAll = document.getElementById('btn-replace-all');

        if (!btnFind || !btnFindClose || !findInput || !btnFindNext || !btnFindPrev || !btnReplace || !btnReplaceAll) {
            console.error('Find dialog elements not found');
            return;
        }

        // Show find dialog
        btnFind.addEventListener('click', () => {
            window.modals.findModal.open();
            findInput.focus();
        });

        // Close find dialog
        btnFindClose.addEventListener('click', () => {
            window.modals.findModal.close();
            this.clearFindHighlights();
        });

        // Find input change - update matches
        findInput.addEventListener('input', () => {
            this.performFind();
        });

        // Find next
        btnFindNext.addEventListener('click', () => {
            this.findNext();
        });

        // Find previous
        btnFindPrev.addEventListener('click', () => {
            this.findPrevious();
        });

        // Replace
        btnReplace.addEventListener('click', () => {
            this.replaceOne();
        });

        // Replace all
        btnReplaceAll.addEventListener('click', () => {
            this.replaceAll();
        });

        // Enter key in find input - find next
        findInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') {
                e.preventDefault();
                if (e.shiftKey) {
                    this.findPrevious();
                } else {
                    this.findNext();
                }
            }
        });

    }

    performFind() {
        const findText = document.getElementById('find-input').value;
        const tab = this.tabs.get(this.activeTabId);

        if (!findText || !tab) {
            this.clearFindHighlights();
            const findCount = document.getElementById('find-count');
            if (findCount) {
                findCount.textContent = '0 matches';
            }
            return;
        }

        const content = this.getEditorContent();
        const matches = [];
        let index = 0;

        // Find all matches
        while ((index = content.indexOf(findText, index)) !== -1) {
            matches.push(index);
            index += findText.length;
        }

        tab.findMatches = matches;
        tab.currentMatchIndex = matches.length > 0 ? 0 : -1;

        // Update match count
        const findCount = document.getElementById('find-count');
        if (findCount) {
            findCount.textContent = `${matches.length} match${matches.length !== 1 ? 'es' : ''}`;
        }

        // Highlight first match
        if (matches.length > 0) {
            this.highlightMatch(0);
        }
    }

    findNext() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab || tab.findMatches.length === 0) return;

        tab.currentMatchIndex = (tab.currentMatchIndex + 1) % tab.findMatches.length;
        this.highlightMatch(tab.currentMatchIndex);
    }

    findPrevious() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab || tab.findMatches.length === 0) return;

        tab.currentMatchIndex = tab.currentMatchIndex - 1;
        if (tab.currentMatchIndex < 0) {
            tab.currentMatchIndex = tab.findMatches.length - 1;
        }
        this.highlightMatch(tab.currentMatchIndex);
    }

    highlightMatch(matchIndex) {
        const tab = this.tabs.get(this.activeTabId);
        const findText = document.getElementById('find-input').value;

        if (!tab || !tab.editorView || matchIndex < 0 || matchIndex >= tab.findMatches.length) return;

        const position = tab.findMatches[matchIndex];
        const view = tab.editorView;

        // Select the match in CodeMirror
        view.dispatch({
            selection: { anchor: position, head: position + findText.length },
            scrollIntoView: true,
        });

        // Restore focus to find input
        const findInput = document.getElementById('find-input');
        if (findInput) {
            setTimeout(() => {
                findInput.focus();
                findInput.setSelectionRange(findInput.value.length, findInput.value.length);
            }, 10);
        }

        // Update match counter
        const findCount = document.getElementById('find-count');
        if (findCount) {
            findCount.textContent = `Match ${matchIndex + 1} of ${tab.findMatches.length}`;
        }
    }

    replaceOne() {
        const tab = this.tabs.get(this.activeTabId);
        const findText = document.getElementById('find-input').value;
        const replaceText = document.getElementById('replace-input').value;

        if (!tab || !tab.editorView || tab.findMatches.length === 0 || tab.currentMatchIndex < 0) return;

        const position = tab.findMatches[tab.currentMatchIndex];
        const view = tab.editorView;

        view.dispatch({
            changes: { from: position, to: position + findText.length, insert: replaceText }
        });

        tab.content = view.state.doc.toString();
        tab.isDirty = true;

        this.updatePreview(this.activeTabId);
        this.updateWordCount();
        this.updateTabBar();

        // Re-perform find to update matches
        this.performFind();
    }

    replaceAll() {
        const tab = this.tabs.get(this.activeTabId);
        const findText = document.getElementById('find-input').value;
        const replaceText = document.getElementById('replace-input').value;

        if (!tab || !tab.editorView || !findText || tab.findMatches.length === 0) return;

        const view = tab.editorView;
        const replacedCount = tab.findMatches.length;

        // Build all changes as a single transaction for proper undo support.
        // Changes must be provided in document order; findMatches is already sorted.
        const changes = tab.findMatches.map(pos => ({
            from: pos,
            to: pos + findText.length,
            insert: replaceText,
        }));

        view.dispatch({ changes });

        tab.content = view.state.doc.toString();
        tab.isDirty = true;

        this.updatePreview(this.activeTabId);
        this.updateWordCount();
        this.updateTabBar();

        // Update match count
        document.getElementById('find-count').textContent = `Replaced ${replacedCount} match${replacedCount !== 1 ? 'es' : ''}`;

        // Re-perform find
        this.performFind();
    }

    clearFindHighlights() {
        const tab = this.tabs.get(this.activeTabId);
        if (tab) {
            tab.findMatches = [];
            tab.currentMatchIndex = -1;
        }
    }
    
    checkForLargeFile(tab, content) {
        if (content && content.length > 1024 * 1024) { // >1MB
            tab.largeFileMode = true;
            this.isPreviewVisible = false;
            this.updatePreviewVisibility();
            notifyUser('Large file detected (>1MB). Large File Mode enabled to maintain peak responsiveness. Live preview auto-render is disabled.', 'warning');
        } else {
            tab.largeFileMode = false;
        }
    }

    // File operations
    openFile(filePath, content) {
        console.log('openFile called with:', filePath, 'content length:', content.length);
        let tab = this.tabs.get(this.activeTabId);
        console.log('openFile tab state before:', { id: tab?.id, hasEditorView: !!tab?.editorView, contentLength: tab?.content?.length, filePath: tab?.filePath, isDirty: tab?.isDirty });

        // Handle both forward and back slashes for cross-platform compatibility
        const fileName = filePath.split(/[\\/]/).pop();

        // If current tab is empty and untitled, reuse it
        if (!tab.filePath && !tab.isDirty && tab.content === '') {
            console.log('Reusing current tab');
            tab.filePath = filePath;
            tab.title = fileName;
            tab.content = content;
            tab.originalContent = content;
            tab.isDirty = false;

            this.checkForLargeFile(tab, content);

            // Update the editor and preview
            this.setEditorContent(this.activeTabId, content);
            console.log('openFile after setEditorContent, tab state:', { id: tab.id, hasEditorView: !!tab.editorView, contentLength: tab.content.length });
            this.updatePreview(this.activeTabId, true); // immediate=true for initial load
            this.updateWordCount();
        } else {
            // Create new tab for the file
            console.log('Creating new tab for file');
            this.createNewTab();
            tab = this.tabs.get(this.activeTabId);
            console.log('openFile after createNewTab, tab:', { id: tab.id, hasEditorView: !!tab.editorView });
            tab.filePath = filePath;
            tab.title = fileName;
            tab.content = content;
            tab.originalContent = content;
            tab.isDirty = false;

            this.checkForLargeFile(tab, content);

            // Set content in the CodeMirror editor
            this.setEditorContent(this.activeTabId, content);
            console.log('openFile after setEditorContent, tab state:', { id: tab.id, hasEditorView: !!tab.editorView, contentLength: tab.content.length });
            this.updatePreview(this.activeTabId, true); // immediate=true for initial load
            this.updateWordCount();
        }
        this.startAutoSave();
        this.addToRecentFiles(filePath);
        this.updateTabBar();
        this.updateFilePath();
        this.updateBreadcrumb();
        this.updateUI(); // Ensure tab content is visible

        // Notify main process about current file for exports
        ipcRenderer.send('set-current-file', filePath);

        console.log('File opened successfully');
    }
    
    // Get content from active editor
    getEditorContent(tabId = this.activeTabId) {
        const tab = this.tabs.get(tabId);
        if (tab?.editorView) {
            return tab.editorView.state.doc.toString();
        }
        return tab?.content || '';
    }

    // Ensure a tab has a CodeMirror editor (lazy creation fallback)
    ensureEditor(tab) {
        if (tab.editorView) return true;
        const editorContainer = document.getElementById(`editor-cm-${tab.id}`);
        if (!editorContainer) {
            console.error(`[ensureEditor] editor-cm-${tab.id} not found in DOM`);
            return false;
        }
        try {
            const isDark = document.body.className.includes('dark');
            tab.editorView = createEditor(editorContainer, {
                content: tab.content,
                onChange: (newContent) => {
                    tab.content = newContent;
                    tab.isDirty = true;
                    this.updatePreview(tab.id);
                    this.updateWordCount();
                    this.updateTabBar();
                    if (outlinePanelContainer?._refreshOutline) outlinePanelContainer._refreshOutline();
                },
                onUpdate: (view) => {
                    this.updateCursorPosition(view);
                    if (outlinePanelContainer?._setActiveHeading) outlinePanelContainer._setActiveHeading(view.state.doc.lineAt(view.state.selection.main.head).number);
                },
                isDark,
                showLineNumbers: this.showLineNumbers,
            });
            console.log(`[ensureEditor] Created editor for tab ${tab.id}`);
            return true;
        } catch (err) {
            console.error(`[ensureEditor] Failed to create editor for tab ${tab.id}:`, err);
            return false;
        }
    }

    // Set content in editor
    setEditorContent(tabId, content) {
        const tab = this.tabs.get(tabId);
        if (!tab?.editorView) {
            this.ensureEditor(tab);
        }
        if (tab?.editorView) {
            tab.editorView.dispatch({
                changes: { from: 0, to: tab.editorView.state.doc.length, insert: content }
            });
        }
        tab.content = content;
    }

    // Insert text at cursor position
    insertAtCursor(text) {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab?.editorView) return;
        const view = tab.editorView;
        const pos = view.state.selection.main.head;
        view.dispatch({
            changes: { from: pos, insert: text }
        });
        view.focus();
    }

    // Get selected text
    getSelection() {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab?.editorView) return '';
        const state = tab.editorView.state;
        return state.sliceDoc(state.selection.main.from, state.selection.main.to);
    }

    // Replace selection
    replaceSelection(text) {
        const tab = this.tabs.get(this.activeTabId);
        if (!tab?.editorView) return;
        const view = tab.editorView;
        const { from, to } = view.state.selection.main;
        view.dispatch({
            changes: { from, to, insert: text }
        });
        view.focus();
    }

    getCurrentContent() {
        const tab = this.tabs.get(this.activeTabId);
        return tab ? tab.content : '';
    }
    
    getCurrentFilePath() {
        const tab = this.tabs.get(this.activeTabId);
        return tab ? tab.filePath : null;
    }
}

// Initialize tab manager
let tabManager;
let replPanel;

document.addEventListener('DOMContentLoaded', async () => {
    tabManager = new TabManager();

    // Load saved Custom Preview CSS if present
    const savedCSSContent = localStorage.getItem('customPreviewCSSContent');
    if (savedCSSContent) {
        applyCustomPreviewCSS(savedCSSContent);
    }

    const ReplPanel = getReplPanel();
    replPanel = new ReplPanel();

    // Populate app version from main process
    window.electronAPI.getAppVersion().then((version) => {
      const el = document.getElementById('app-version-display');
      if (el) el.textContent = `v${version}`;
    });

    // Initialize ModalManager for all dialogs
    const findModal = new ModalManager('#find-dialog');
    const exportModal = new ModalManager('#export-dialog');
    const printPreviewModal = new ModalManager('#print-preview-overlay');
    const tableModal = new ModalManager('#table-generator-dialog');
    const asciiModal = new ModalManager('#ascii-art-dialog');
    const converterModal = new ModalManager('#universal-converter-dialog');
    const batchModal = new ModalManager('#batch-dialog');
    const pdfEditorModal = new ModalManager('#pdf-editor-dialog');
    const headerFooterModal = new ModalManager('#header-footer-dialog');
    const fieldPickerModal = new ModalManager('#field-picker-dialog');

    // Make modals globally accessible for functions outside this scope
    window.modals = {
        findModal,
        exportModal,
        printPreviewModal,
        tableModal,
        asciiModal,
        converterModal,
        batchModal,
        pdfEditorModal,
        headerFooterModal,
        fieldPickerModal
    };

    // Initialize sidebar
    const SidebarManager = getSidebarManager();
    const sidebarManager = new SidebarManager();
    const explorerCurrentDir = null;

    sidebarManager.registerPanel('explorer', {
        title: 'Explorer',
        render: (container) => getRenderExplorerPanel()(container, {
            listDirectory: (dir) => ipcRenderer.invoke('list-directory', dir),
            onFileOpen: (filePath) => ipcRenderer.send('open-file-path', filePath),
            currentDir: explorerCurrentDir,
        })
    });
    sidebarManager.registerPanel('git', {
        title: 'Git',
        render: (container) => getRenderGitPanel()(container, {
            gitStatus: () => ipcRenderer.invoke('git-status'),
            gitDiff: (file) => ipcRenderer.invoke('git-diff', { file }),
            gitStage: (files) => ipcRenderer.invoke('git-stage', { files }),
            gitCommit: (message) => ipcRenderer.invoke('git-commit', { message }),
            gitLog: () => ipcRenderer.invoke('git-log'),
        })
    });
    sidebarManager.registerPanel('snippets', {
        title: 'Snippets',
        render: (container) => getRenderSnippetsPanel()(container, {
            getSnippets: () => ipcRenderer.invoke('get-snippets'),
            saveSnippet: (s) => ipcRenderer.invoke('save-snippet', s),
            deleteSnippet: (id) => ipcRenderer.invoke('delete-snippet', id),
            onInsert: (code) => tabManager.insertAtCursor(code),
        })
    });
    sidebarManager.registerPanel('templates', {
        title: 'Templates',
        render: (container) => getRenderTemplatesPanel()(container, async (file) => {
            const templateContent = await ipcRenderer.invoke('load-template', file);
            if (templateContent) {
                const content = templateContent.replace(/\{\{DATE\}\}/g, new Date().toISOString().split('T')[0]);
                tabManager.createNewTab();
                const tab = tabManager.tabs.get(tabManager.activeTabId);
                tabManager.setEditorContent(tab.id, content);
            }
        })
    });

    let outlinePanelContainer = null;
    sidebarManager.registerPanel('outline', {
        title: 'Outline',
        render: (container) => {
            outlinePanelContainer = container;
            getRenderOutlinePanel()(container, {
                getEditorContent: () => tabManager.getEditorContent(),
                getActiveLine: () => {
                    const tab = tabManager.tabs.get(tabManager.activeTabId);
                    if (tab?.editorView) {
                        const pos = tab.editorView.state.selection.main.head;
                        return tab.editorView.state.doc.lineAt(pos).number;
                    }
                    return 1;
                },
                onHeadingClick: (line) => {
                    const tab = tabManager.tabs.get(tabManager.activeTabId);
                    if (tab?.editorView) {
                        const pos = tab.editorView.state.doc.line(line).from;
                        tab.editorView.dispatch({
                            selection: { anchor: pos },
                            scrollIntoView: true
                        });
                        tab.editorView.focus();
                    }
                }
            });
        }
    });

    // --- Plugin System ---
    const { PluginLoader } = require('./plugins/plugin-loader');
    const { PluginRegistry } = require('./plugins/plugin-registry');
    const { EventBus } = require('./plugins/event-bus');
    const { SettingsStore } = require('./plugins/settings-store');
    const pluginPath = require('path');

    const pluginEventBus = new EventBus();
    const pluginSettings = new SettingsStore({
        get: (key) => window.electronAPI.invoke('plugin-settings:get', key),
        set: (key, value) => window.electronAPI.invoke('plugin-settings:set', { key, value })
    });

    const statusBarRight = document.querySelector('.status-bar-right');
    const pluginRegistry = new PluginRegistry({
        sidebar: sidebarManager,
        commands: commandPalette,
        statusBar: {
            registerIndicator: (id, opts) => {
                const el = document.createElement('span');
                el.className = 'status-item';
                el.id = `plugin-status-${id}`;
                if (opts.tooltip) el.title = opts.tooltip;
                el.textContent = opts.text || '';
                const sep = document.createElement('span');
                sep.className = 'status-separator';
                sep.textContent = '|';
                if (statusBarRight) {
                    statusBarRight.appendChild(sep);
                    statusBarRight.appendChild(el);
                }
            }
        },
        eventBus: pluginEventBus,
        settings: pluginSettings,
        editor: {
            getContent: () => tabManager.getCurrentContent(),
            getSelection: () => tabManager.getSelection(),
            insertAtCursor: (text) => tabManager.insertAtCursor(text),
            onContentChanged: (cb) => pluginEventBus.on('document:changed', cb)
        },
        ipc: {
            invoke: (ch, data) => window.electronAPI.invoke(ch, data),
            on: (ch, cb) => window.electronAPI.on(ch, cb)
        }
    });

    const builtInDir = pluginPath.join(__dirname, 'plugins', 'built-in');
    const loader = new PluginLoader([builtInDir]);
    const discovered = loader.discoverPlugins();
    discovered.forEach(p => pluginRegistry.register(p));

    // Initialize Zen Mode
    const ZenModeClass = getZenMode();
    const zenMode = new ZenModeClass(tabManager);

    // Welcome tab on startup
    const hasLaunched = localStorage.getItem('hasLaunchedBefore');
    const showWelcome = localStorage.getItem('showWelcomeOnStartup') !== 'false';

    if (!hasLaunched || showWelcome) {
        localStorage.setItem('hasLaunchedBefore', 'true');

        // Set welcome content in the first tab's preview
        const recentFiles = JSON.parse(localStorage.getItem('recentFiles') || '[]');
        const appVersion = await window.electronAPI.getAppVersion().catch(() => '');
        const welcomeHtml = getCreateWelcomeContent()(recentFiles, appVersion);

        const tab = tabManager.tabs.get(tabManager.activeTabId);
        // Only show welcome if no file was opened while we were awaiting
        if (tab && !tab.filePath && tab.content === '') {
            tab.title = 'Welcome';
            tab.content = '';
            const preview = document.getElementById(`preview-${tab.id}`);
            if (preview) {
                preview.innerHTML = welcomeHtml;
                // Wire up card actions
                preview.querySelectorAll('.welcome-card').forEach(card => {
                    card.addEventListener('click', () => {
                        const action = card.dataset.action;
                        if (action === 'new-file') tabManager.createNewTab();
                        else if (action === 'open-file') ipcRenderer.send('menu-open');
                        else if (action === 'open-template') sidebarManager.togglePanel('templates');
                        else if (action === 'command-palette') {
                            if (typeof commandPalette !== 'undefined') commandPalette.open();
                        }
                    });
                });
                // Wire up recent files
                preview.querySelectorAll('.welcome-recent-item').forEach(item => {
                    item.addEventListener('click', () => ipcRenderer.send('open-file-path', item.dataset.path));
                });
                // Wire up show-on-startup checkbox
                const checkbox = document.getElementById('show-welcome-startup');
                if (checkbox) {
                    checkbox.addEventListener('change', () => {
                        localStorage.setItem('showWelcomeOnStartup', checkbox.checked);
                    });
                }
            }
            tabManager.updateTabBar();
        }
    }

    // Image paste handler
    document.addEventListener('paste', async (e) => {
        const items = e.clipboardData?.items;
        if (!items) return;

        for (const item of items) {
            if (item.type.startsWith('image/')) {
                e.preventDefault();
                const blob = item.getAsFile();
                const reader = new FileReader();
                reader.onload = async () => {
                    const base64 = reader.result.split(',')[1];
                    const ext = item.type.split('/')[1] === 'png' ? 'png' : 'jpg';
                    const result = await ipcRenderer.invoke('save-pasted-image', { base64, ext });
                    if (result?.relativePath) {
                        tabManager.insertAtCursor(`![image](${result.relativePath})\n`);
                    }
                };
                reader.readAsDataURL(blob);
                break;
            }
        }
    });

    // Drag and drop images
    const editorContainer = document.querySelector('.editor-container');
    editorContainer?.addEventListener('dragover', (e) => {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';
    });
    editorContainer?.addEventListener('drop', async (e) => {
        e.preventDefault();
        const files = Array.from(e.dataTransfer.files).filter(f => f.type.startsWith('image/'));
        for (const file of files) {
            const reader = new FileReader();
            reader.onload = async () => {
                const base64 = reader.result.split(',')[1];
                const ext = file.name.split('.').pop() || 'png';
                const result = await ipcRenderer.invoke('save-pasted-image', { base64, ext });
                if (result?.relativePath) {
                    tabManager.insertAtCursor(`![${file.name}](${result.relativePath})\n`);
                }
            };
            reader.readAsDataURL(file);
        }
    });

    // Initialize command palette
    const CommandPalette = getCommandPalette();
    const commandPalette = new CommandPalette();

    // Initialize print preview
    const PrintPreview = getPrintPreview();
    const printPreview = new PrintPreview();

    // Register commands
    commandPalette.register('New File', 'Ctrl+N', () => tabManager.createNewTab());
    commandPalette.register('Open File', 'Ctrl+O', () => ipcRenderer.send('menu-open'));
    commandPalette.register('Save', 'Ctrl+S', () => {
        const content = tabManager.getCurrentContent();
        ipcRenderer.send('save-current-file', content);
    });
    commandPalette.register('Toggle Preview', '', () => {
        tabManager.isPreviewVisible = !tabManager.isPreviewVisible;
        tabManager.updatePreviewVisibility();
    });
    commandPalette.register('Toggle Line Numbers', '', () => {
        tabManager.showLineNumbers = !tabManager.showLineNumbers;
        tabManager.updateLineNumbers();
    });
    commandPalette.register('Bold', 'Ctrl+B', () => tabManager.wrapSelection('**', '**'));
    commandPalette.register('Italic', 'Ctrl+I', () => tabManager.wrapSelection('*', '*'));
    commandPalette.register('Insert Table', '', () => tabManager.insertTable());
    commandPalette.register('Insert Code Block', '', () => tabManager.insertCodeBlock());
    commandPalette.register('Insert Horizontal Rule', '', () => tabManager.insertHorizontalRule());
    commandPalette.register('Find & Replace', 'Ctrl+F', () => {
        const findDialog = document.getElementById('find-dialog');
        if (findDialog) {
            findDialog.classList.toggle('hidden');
            if (!findDialog.classList.contains('hidden')) {
                document.getElementById('find-input').focus();
            }
        }
    });
    commandPalette.register('Toggle Sidebar: Explorer', 'Ctrl+Shift+E', () => sidebarManager.togglePanel('explorer'));
    commandPalette.register('Toggle Sidebar: Git', 'Ctrl+Shift+G', () => sidebarManager.togglePanel('git'));
    commandPalette.register('Toggle Sidebar: Snippets', '', () => sidebarManager.togglePanel('snippets'));
    commandPalette.register('Toggle Sidebar: Templates', '', () => sidebarManager.togglePanel('templates'));
    commandPalette.register('Toggle Sidebar: Outline', 'Ctrl+Shift+O', () => sidebarManager.togglePanel('outline'));
    commandPalette.register('Print Preview', 'Ctrl+P', () => {
        const tab = tabManager.tabs.get(tabManager.activeTabId);
        const preview = document.getElementById(`preview-${tab.id}`);
        printPreview.open(preview?.innerHTML || '');
    });
    commandPalette.register('Export to PDF', '', () => ipcRenderer.send('export', 'pdf'));
    commandPalette.register('Export to DOCX', '', () => ipcRenderer.send('export', 'docx'));
    commandPalette.register('Export to HTML', '', () => ipcRenderer.send('export', 'html'));
    commandPalette.register('New Tab', 'Ctrl+T', () => tabManager.createNewTab());
    commandPalette.register('Close Tab', 'Ctrl+W', () => tabManager.closeTab(tabManager.activeTabId));
    commandPalette.register('Undo', 'Ctrl+Z', () => { const tab = tabManager.tabs.get(tabManager.activeTabId); if (tab?.editorView) undo(tab.editorView); });
    commandPalette.register('Redo', 'Ctrl+Shift+Z', () => { const tab = tabManager.tabs.get(tabManager.activeTabId); if (tab?.editorView) redo(tab.editorView); });
    commandPalette.register('Heading 1', '', () => tabManager.insertAtLineStart('# '));
    commandPalette.register('Heading 2', '', () => tabManager.insertAtLineStart('## '));
    commandPalette.register('Heading 3', '', () => tabManager.insertAtLineStart('### '));
    commandPalette.register('Insert Link', '', () => tabManager.wrapSelection('[', '](url)'));
    commandPalette.register('Insert Image', '', () => tabManager.wrapSelection('![', '](image.jpg)'));
    commandPalette.register('Toggle Zen Mode', 'F11', () => zenMode.toggle());
    commandPalette.register('Writing Analytics', 'Ctrl+Shift+A', () => getShowAnalyticsModal()(tabManager));
    commandPalette.register('Load Custom Preview CSS', '', triggerLoadCustomCSS);
    commandPalette.register('Clear Custom Preview CSS', '', triggerClearCustomCSS);

    // Keyboard shortcuts
    document.addEventListener('keydown', (e) => {
        // Ctrl+Shift+P — Command Palette
        if (e.ctrlKey && e.shiftKey && e.key === 'P') {
            e.preventDefault();
            commandPalette.open();
        }
        // F11 — Zen Mode
        if (e.key === 'F11') {
            e.preventDefault();
            zenMode.toggle();
        }
        // Ctrl+Shift+A — Writing Analytics
        if (e.ctrlKey && e.shiftKey && e.key === 'A') {
            e.preventDefault();
            getShowAnalyticsModal()(tabManager);
        }
        // Escape — Exit Zen Mode
        if (e.key === 'Escape' && zenMode.active) {
            zenMode.deactivate();
        }
    });

    // Initialize CodeMirror for the initial tab (tab 1)
    const initialTab = tabManager.tabs.get(1);
    if (initialTab) {
        tabManager.ensureEditor(initialTab);
    }

    // Request current theme
    ipcRenderer.send('get-theme');

    // Also send renderer-ready immediately as backup
    // This ensures we don't get stuck waiting for theme-changed
    setTimeout(() => {
        console.log('Backup renderer-ready timeout triggered');
        ipcRenderer.send('renderer-ready');
    }, 100);

    // Set up auto-save interval
    setInterval(() => {
        // Auto-save logic for all tabs
        tabManager.tabs.forEach(tab => {
            if (tab.isDirty && tab.filePath) {
                ipcRenderer.send('save-current-file', { filePath: tab.filePath, content: tab.content });
            }
        });
    }, 30000);
});

// IPC event listeners
// IPC event listeners
ipcRenderer.on('file-new', () => {
    tabManager.createNewTab();
});

ipcRenderer.on('file-opened', (event, data) => {
    console.log('[RENDERER] file-opened received:', data.path, 'content length:', data.content.length);
    console.log('[RENDERER] activeTabId before openFile:', tabManager.activeTabId);
    // Diagnostic: check library state
    console.log('[RENDERER] Library state:', {
        marked: typeof marked,
        DOMPurify: typeof DOMPurify,
        markedParse: typeof marked?.parse,
        dompurifySanitize: typeof DOMPurify?.sanitize,
        tabManagerExists: !!tabManager
    });
    if (tabManager) {
        tabManager.openFile(data.path, data.content);
        console.log('[RENDERER] activeTabId after openFile:', tabManager.activeTabId);
        const tab = tabManager.tabs.get(tabManager.activeTabId);
        console.log('[RENDERER] tab state:', { id: tab?.id, hasEditorView: !!tab?.editorView, contentLength: tab?.content?.length });
    } else {
        console.error('[RENDERER] tabManager not initialized!');
    }
});

ipcRenderer.on('file-save', () => {
    const currentContent = tabManager.getCurrentContent();
    const currentFilePath = tabManager.getCurrentFilePath();
    // send to main process which will save or trigger save-as dialog
    ipcRenderer.send('save-current-file', { filePath: currentFilePath, content: currentContent });
});

ipcRenderer.on('get-content-for-save', (event, filePath) => {
    const currentContent = tabManager.getCurrentContent();
    ipcRenderer.send('save-file', { path: filePath, content: currentContent });
    // Update the active tab's file path and title after save-as
    const tab = tabManager.tabs.get(tabManager.activeTabId);
    if (tab) {
        tab.filePath = filePath;
        tab.originalContent = currentContent;
        tab.isDirty = false;
        tab.title = filePath.split(/[/\\]/).pop();
        tabManager.updateTabBar();
        tabManager.updateFilePath();
        tabManager.updateBreadcrumb();
    }
});

ipcRenderer.on('get-content-for-spreadsheet', (event, format) => {
    const currentContent = tabManager.getCurrentContent();
    ipcRenderer.send('export-spreadsheet', { content: currentContent, format });
});

ipcRenderer.on('toggle-preview', () => {
    tabManager.isPreviewVisible = !tabManager.isPreviewVisible;
    tabManager.updatePreviewVisibility();
});

ipcRenderer.on('toggle-find', () => {
    if (window.modals.findModal.isOpen()) {
        window.modals.findModal.close();
    } else {
        window.modals.findModal.open();
        document.getElementById('find-input').focus();
    }
});

ipcRenderer.on('theme-changed', (event, theme) => {
    console.log('[RENDERER] Theme changed to:', theme);
    document.body.className = `theme-${theme}`;

    // After theme is applied, wait for next frame then signal renderer is ready
    // This ensures complete UI initialization before files are opened
    requestAnimationFrame(() => {
        console.log('[RENDERER] Sending renderer-ready from theme-changed');
        ipcRenderer.send('renderer-ready');
    });
});

// Undo/Redo handlers — delegate to CodeMirror's built-in history
ipcRenderer.on('undo', () => {
    if (tabManager) {
        const tab = tabManager.tabs.get(tabManager.activeTabId);
        if (tab?.editorView) {
            undo(tab.editorView);
        }
    }
});

ipcRenderer.on('redo', () => {
    if (tabManager) {
        const tab = tabManager.tabs.get(tabManager.activeTabId);
        if (tab?.editorView) {
            redo(tab.editorView);
        }
    }
});

// Custom Preview CSS event handlers and trigger helpers
function applyCustomPreviewCSS(cssContent) {
    let styleTag = document.getElementById('custom-preview-style');
    if (!styleTag) {
        styleTag = document.createElement('style');
        styleTag.id = 'custom-preview-style';
        document.head.appendChild(styleTag);
    }
    const scopedCSS = scopeCSS(cssContent, '.preview-content');
    styleTag.textContent = scopedCSS;
}

async function triggerLoadCustomCSS() {
    try {
        const result = await window.electronAPI.invoke('select-custom-css');
        if (result) {
            console.log('[RENDERER] Custom CSS loaded from:', result.path);
            localStorage.setItem('customPreviewCSSPath', result.path);
            localStorage.setItem('customPreviewCSSContent', result.content);
            applyCustomPreviewCSS(result.content);
            notifyUser('Custom preview stylesheet applied successfully.', 'success');
        }
    } catch (err) {
        console.error('[RENDERER] Error loading custom CSS:', err);
        notifyUser('Failed to load custom CSS stylesheet.', 'error');
    }
}

function triggerClearCustomCSS() {
    localStorage.removeItem('customPreviewCSSPath');
    localStorage.removeItem('customPreviewCSSContent');
    const styleTag = document.getElementById('custom-preview-style');
    if (styleTag) {
        styleTag.remove();
    }
    notifyUser('Custom preview stylesheet cleared.', 'info');
}

ipcRenderer.on('load-custom-css', triggerLoadCustomCSS);
ipcRenderer.on('clear-custom-css', triggerClearCustomCSS);



// Font size adjustment
let currentFontSize = parseInt(localStorage.getItem('fontSize')) || 15;

function updateFontSizes(size) {
    const editors = document.querySelectorAll('.cm-editor');
    const previews = document.querySelectorAll('#preview, .preview-content');

    editors.forEach(editor => {
        editor.style.fontSize = `${size}px`;
    });

    previews.forEach(preview => {
        preview.style.fontSize = `${size}px`;
    });

    localStorage.setItem('fontSize', size);
}

// Apply saved font size on load
updateFontSizes(currentFontSize);

ipcRenderer.on('adjust-font-size', (event, action) => {
    if (action === 'increase' && currentFontSize < 24) {
        currentFontSize++;
    } else if (action === 'decrease' && currentFontSize > 10) {
        currentFontSize--;
    } else if (action === 'reset') {
        currentFontSize = 15;
    }
    updateFontSizes(currentFontSize);
});

// Print preview request handlers - open print preview dialog
ipcRenderer.on('print-preview', () => {
    console.log('[RENDERER] print-preview received');
    openPrintPreviewDialog();
});

ipcRenderer.on('print-preview-styled', () => {
    console.log('[RENDERER] print-preview-styled received');
    openPrintPreviewDialog();
});

function openPrintPreviewDialog() {
    const activeTabId = tabManager ? tabManager.activeTabId : 1;
    const previewContent = document.getElementById(`preview-${activeTabId}`);

    if (!previewContent || !previewContent.innerHTML.trim()) {
        notifyUser('Nothing to print. Create or open a document and keep the preview visible.', 'warning');
        return;
    }

    const PrintPreviewClass = getPrintPreview();
    const printPreviewInstance = new PrintPreviewClass();
    printPreviewInstance.open(previewContent.innerHTML);
}

// Export Dialog functionality
let currentExportFormat = null;

ipcRenderer.on('show-export-dialog', (event, format) => {
    currentExportFormat = format;
    showExportDialog(format);
});

function showExportDialog(format) {
    console.log('showExportDialog called with format:', format);
    const dialog = document.getElementById('export-dialog');
    const title = document.getElementById('export-dialog-title');

    if (!dialog) {
        console.error('Export dialog element not found!');
        return;
    }

    console.log('Dialog found, showing export options for:', format);
    title.textContent = `Export as ${format.toUpperCase()}`;
    dialog.setAttribute('data-format', format);
    window.modals.exportModal.open();

    // Initialize form values
    initializeExportForm(format);
    console.log('Export dialog should now be visible');
}

function hideExportDialog() {
    window.modals.exportModal.close();
    currentExportFormat = null;
}

function initializeExportForm(format) {
    // Reset advanced export toggle to unchecked
    const advancedToggle = document.getElementById('advanced-export-toggle');
    const advancedOptions = document.getElementById('advanced-export-options');

    advancedToggle.checked = false;
    advancedOptions.classList.add('hidden');

    // Reset form to defaults
    document.getElementById('export-template').value = 'default';
    document.getElementById('custom-template-path').style.display = 'none';

    // Clear metadata fields
    const metadataFields = document.querySelectorAll('.metadata-field');
    metadataFields.forEach((field, index) => {
        if (index < 4) { // Keep first 4 default fields
            field.querySelector('.metadata-key').value = ['title', 'author', 'date', 'subject'][index] || '';
            field.querySelector('.metadata-value').value = '';
        } else {
            field.remove(); // Remove additional fields
        }
    });

    // Reset checkboxes and other fields
    document.getElementById('export-toc').checked = false;
    document.getElementById('export-number-sections').checked = false;
    document.getElementById('export-citeproc').checked = false;
    document.getElementById('export-toc-depth').value = 3;

    // Toggle and reset PDF-specific fields
    const pdfOnly = document.querySelector('.pdf-only');
    if (pdfOnly) {
        pdfOnly.style.display = (format === 'pdf') ? 'block' : 'none';
    }
    if (format === 'pdf') {
        document.getElementById('pdf-engine').value = 'xelatex';
        document.getElementById('pdf-geometry').value = 'margin=1in';
        document.getElementById('custom-geometry').style.display = 'none';
    }

    // Toggle and reset Reveal.js-specific fields
    const revealjsOnly = document.querySelector('.revealjs-only');
    if (revealjsOnly) {
        revealjsOnly.style.display = (format === 'revealjs') ? 'block' : 'none';
    }
    const revealTheme = document.getElementById('reveal-theme');
    if (revealTheme) revealTheme.value = 'black';
    const revealTransition = document.getElementById('reveal-transition');
    if (revealTransition) revealTransition.value = 'slide';
    const revealSpeed = document.getElementById('reveal-speed');
    if (revealSpeed) revealSpeed.value = 'default';
    const revealSlideNumber = document.getElementById('reveal-slide-number');
    if (revealSlideNumber) revealSlideNumber.checked = false;
    const revealControls = document.getElementById('reveal-controls');
    if (revealControls) revealControls.checked = true;
    const revealProgress = document.getElementById('reveal-progress');
    if (revealProgress) revealProgress.checked = true;
    const revealHistory = document.getElementById('reveal-history');
    if (revealHistory) revealHistory.checked = true;
    const revealCenter = document.getElementById('reveal-center');
    if (revealCenter) revealCenter.checked = true;

    // Clear bibliography fields
    document.getElementById('bibliography-file').value = '';
    document.getElementById('csl-file').value = '';

    // Request current page settings from main process and apply them
    ipcRenderer.send('get-page-settings');
}

function collectExportOptions() {
    const advancedMode = document.getElementById('advanced-export-toggle').checked;
    const options = {};

    if (advancedMode) {
        // Collect advanced options
        options.template = document.getElementById('export-template').value;
        options.metadata = {};
        options.variables = {};
        options.toc = document.getElementById('export-toc').checked;
        options.tocDepth = document.getElementById('export-toc-depth').value;
        options.numberSections = document.getElementById('export-number-sections').checked;
        options.citeproc = document.getElementById('export-citeproc').checked;
    } else {
        // Collect basic options only
        options.template = 'default';
        options.metadata = {};
        options.variables = {};
        options.toc = document.getElementById('basic-toc').checked;
        options.tocDepth = 3;
        options.numberSections = document.getElementById('basic-number-sections').checked;
        options.citeproc = false;
    }

    if (advancedMode) {
        // Collect custom template path
        if (options.template === 'custom') {
            options.template = document.getElementById('custom-template-path').value.trim();
        }

        // Collect metadata
        const metadataFields = document.querySelectorAll('.metadata-field');
        metadataFields.forEach(field => {
            const key = field.querySelector('.metadata-key').value.trim();
            const value = field.querySelector('.metadata-value').value.trim();
            if (key && value) {
                options.metadata[key] = value;
            }
        });

        // PDF-specific options
        if (currentExportFormat === 'pdf') {
            options.pdfEngine = document.getElementById('pdf-engine').value;
            const geometrySelect = document.getElementById('pdf-geometry');
            if (geometrySelect.value === 'custom') {
                options.geometry = document.getElementById('custom-geometry').value.trim() || 'margin=1in';
            } else {
                options.geometry = geometrySelect.value;
            }
        }

        // Reveal.js-specific options
        if (currentExportFormat === 'revealjs') {
            options.revealTheme = document.getElementById('reveal-theme').value;
            options.revealTransition = document.getElementById('reveal-transition').value;
            options.revealTransitionSpeed = document.getElementById('reveal-speed').value;
            options.revealSlideNumber = document.getElementById('reveal-slide-number').checked;
            options.revealControls = document.getElementById('reveal-controls').checked;
            options.revealProgress = document.getElementById('reveal-progress').checked;
            options.revealHistory = document.getElementById('reveal-history').checked;
            options.revealCenter = document.getElementById('reveal-center').checked;
        }

        // Bibliography
        const bibFile = document.getElementById('bibliography-file').value.trim();
        const cslFile = document.getElementById('csl-file').value.trim();
        if (bibFile) options.bibliography = bibFile;
        if (cslFile) options.csl = cslFile;
    } else {
        // Basic mode - set default PDF options if needed
        if (currentExportFormat === 'pdf') {
            options.pdfEngine = 'xelatex';
            options.geometry = 'margin=1in';
        } else if (currentExportFormat === 'revealjs') {
            options.revealTheme = 'black';
            options.revealTransition = 'slide';
            options.revealTransitionSpeed = 'default';
            options.revealSlideNumber = false;
            options.revealControls = true;
            options.revealProgress = true;
            options.revealHistory = true;
            options.revealCenter = true;
        }
    }

    // Collect page size and orientation (always collected, from basic options)
    const pageSize = document.getElementById('page-size').value;
    const pageOrientation = document.getElementById('page-orientation').value;
    const customWidth = document.getElementById('custom-width').value.trim();
    const customHeight = document.getElementById('custom-height').value.trim();

    // Send page settings to main process
    ipcRenderer.send('update-page-settings', {
        size: pageSize,
        orientation: pageOrientation,
        customWidth: customWidth || null,
        customHeight: customHeight || null
    });

    return options;
}

// Export Profiles Management
let exportProfiles = {};

function loadExportProfiles() {
    const saved = localStorage.getItem('exportProfiles');
    if (saved) {
        try {
            exportProfiles = JSON.parse(saved);
            populateProfileDropdown();
        } catch (e) {
            console.error('Failed to load export profiles:', e);
            exportProfiles = {};
        }
    }
}

function saveExportProfiles() {
    localStorage.setItem('exportProfiles', JSON.stringify(exportProfiles));
}

function populateProfileDropdown() {
    const select = document.getElementById('export-profile-select');
    if (!select) return;

    // Clear existing options except the first one
    while (select.options.length > 1) {
        select.remove(1);
    }

    // Add saved profiles
    Object.keys(exportProfiles).forEach(name => {
        const option = document.createElement('option');
        option.value = name;
        option.textContent = name;
        select.appendChild(option);
    });
}

function saveCurrentProfile() {
    const name = prompt('Enter a name for this export profile:', 'My Profile');
    if (!name || name.trim() === '') return;

    const profileName = name.trim();

    // Collect current settings
    const profile = {
        format: currentExportFormat,
        advancedMode: document.getElementById('advanced-export-toggle').checked,
        pageSize: document.getElementById('page-size').value,
        pageOrientation: document.getElementById('page-orientation').value,
        basicToc: document.getElementById('basic-toc').checked,
        basicNumberSections: document.getElementById('basic-number-sections').checked
    };

    // Add advanced options if enabled
    if (profile.advancedMode) {
        profile.template = document.getElementById('export-template').value;
        profile.toc = document.getElementById('export-toc').checked;
        profile.tocDepth = document.getElementById('export-toc-depth').value;
        profile.numberSections = document.getElementById('export-number-sections').checked;
        profile.citeproc = document.getElementById('export-citeproc').checked;

        if (currentExportFormat === 'pdf') {
            profile.pdfEngine = document.getElementById('pdf-engine').value;
            profile.pdfGeometry = document.getElementById('pdf-geometry').value;
        }
    }

    exportProfiles[profileName] = profile;
    saveExportProfiles();
    populateProfileDropdown();

    // Select the newly created profile
    document.getElementById('export-profile-select').value = profileName;

    notifyUser(`Profile "${profileName}" saved successfully.`, 'success');
}

function loadProfile(profileName) {
    if (!profileName || !exportProfiles[profileName]) return;

    const profile = exportProfiles[profileName];

    // Apply settings
    if (profile.advancedMode !== undefined) {
        document.getElementById('advanced-export-toggle').checked = profile.advancedMode;
        const advancedOptions = document.getElementById('advanced-export-options');
        if (profile.advancedMode) {
            advancedOptions.classList.remove('hidden');
        } else {
            advancedOptions.classList.add('hidden');
        }
    }

    if (profile.pageSize) document.getElementById('page-size').value = profile.pageSize;
    if (profile.pageOrientation) document.getElementById('page-orientation').value = profile.pageOrientation;
    if (profile.basicToc !== undefined) document.getElementById('basic-toc').checked = profile.basicToc;
    if (profile.basicNumberSections !== undefined) document.getElementById('basic-number-sections').checked = profile.basicNumberSections;

    // Advanced options
    if (profile.advancedMode && profile.template) document.getElementById('export-template').value = profile.template;
    if (profile.toc !== undefined) document.getElementById('export-toc').checked = profile.toc;
    if (profile.tocDepth) document.getElementById('export-toc-depth').value = profile.tocDepth;
    if (profile.numberSections !== undefined) document.getElementById('export-number-sections').checked = profile.numberSections;
    if (profile.citeproc !== undefined) document.getElementById('export-citeproc').checked = profile.citeproc;

    if (profile.pdfEngine) document.getElementById('pdf-engine').value = profile.pdfEngine;
    if (profile.pdfGeometry) document.getElementById('pdf-geometry').value = profile.pdfGeometry;
}

function deleteSelectedProfile() {
    const select = document.getElementById('export-profile-select');
    const profileName = select.value;

    if (!profileName) {
        notifyUser('Select a profile to delete.', 'warning');
        return;
    }

    if (confirm(`Are you sure you want to delete the profile "${profileName}"?`)) {
        delete exportProfiles[profileName];
        saveExportProfiles();
        populateProfileDropdown();
        select.value = '';
        notifyUser(`Profile "${profileName}" deleted successfully.`, 'success');
    }
}

// Event listeners for export dialog
document.addEventListener('DOMContentLoaded', () => {
    // Load export profiles on startup
    loadExportProfiles();
    // Template selection
    document.getElementById('export-template').addEventListener('change', (e) => {
        const customPath = document.getElementById('custom-template-path');
        const fileInput = document.getElementById('template-file-input');

        if (e.target.value === 'custom') {
            customPath.style.display = 'block';
            fileInput.style.display = 'block';
        } else {
            customPath.style.display = 'none';
            fileInput.style.display = 'none';
            customPath.value = '';
        }
    });

    // Advanced export toggle
    document.getElementById('advanced-export-toggle').addEventListener('change', (e) => {
        const advancedOptions = document.getElementById('advanced-export-options');
        if (e.target.checked) {
            advancedOptions.classList.remove('hidden');
            // Scroll the advanced options into view after they become visible
            setTimeout(() => {
                advancedOptions.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            }, 100);
        } else {
            advancedOptions.classList.add('hidden');
        }
    });

    // Template file input
    document.getElementById('template-file-input').addEventListener('change', (e) => {
        const file = e.target.files[0];
        if (file) {
            document.getElementById('custom-template-path').value = file.path;
        }
    });

    // PDF geometry selection
    document.getElementById('pdf-geometry').addEventListener('change', (e) => {
        const customGeometry = document.getElementById('custom-geometry');
        if (e.target.value === 'custom') {
            customGeometry.style.display = 'block';
        } else {
            customGeometry.style.display = 'none';
        }
    });

    // Page size selection - show/hide custom size inputs
    document.getElementById('page-size').addEventListener('change', (e) => {
        const customPageSize = document.getElementById('custom-page-size');
        if (e.target.value === 'custom') {
            customPageSize.style.display = 'block';
        } else {
            customPageSize.style.display = 'none';
        }
    });

    // Load saved page settings on startup
    ipcRenderer.send('get-page-settings');

    // Handle page settings data (can be called multiple times)
    ipcRenderer.on('page-settings-data', (event, settings) => {
        console.log('Received page settings:', settings);
        if (settings) {
            const pageSizeEl = document.getElementById('page-size');
            const pageOrientationEl = document.getElementById('page-orientation');
            const customPageSizeEl = document.getElementById('custom-page-size');
            const customWidthEl = document.getElementById('custom-width');
            const customHeightEl = document.getElementById('custom-height');

            if (pageSizeEl) pageSizeEl.value = settings.size || 'a4';
            if (pageOrientationEl) pageOrientationEl.value = settings.orientation || 'portrait';

            if (customWidthEl && settings.customWidth) {
                customWidthEl.value = settings.customWidth;
            }
            if (customHeightEl && settings.customHeight) {
                customHeightEl.value = settings.customHeight;
            }

            // Show custom inputs if size is custom
            if (customPageSizeEl) {
                if (settings.size === 'custom') {
                    customPageSizeEl.style.display = 'block';
                } else {
                    customPageSizeEl.style.display = 'none';
                }
            }
        }
    });

    // Export Profile buttons
    document.getElementById('save-profile-btn').addEventListener('click', saveCurrentProfile);
    document.getElementById('delete-profile-btn').addEventListener('click', deleteSelectedProfile);
    document.getElementById('export-profile-select').addEventListener('change', (e) => {
        loadProfile(e.target.value);
    });

    // Add metadata field
    document.getElementById('add-metadata-field').addEventListener('click', () => {
        const container = document.querySelector('.metadata-container');
        const newField = document.createElement('div');
        newField.className = 'metadata-field';
        newField.innerHTML = `
            <input type="text" placeholder="key" class="metadata-key">
            <input type="text" placeholder="value" class="metadata-value">
        `;
        container.appendChild(newField);
    });

    // Browse bibliography
    document.getElementById('browse-bibliography').addEventListener('click', () => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.bib,.yaml,.yml,.json';
        input.onchange = (e) => {
            const file = e.target.files[0];
            if (file) {
                document.getElementById('bibliography-file').value = file.path;
            }
        };
        input.click();
    });

    // Browse CSL
    document.getElementById('browse-csl').addEventListener('click', () => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.csl';
        input.onchange = (e) => {
            const file = e.target.files[0];
            if (file) {
                document.getElementById('csl-file').value = file.path;
            }
        };
        input.click();
    });

    // Dialog close buttons
    document.getElementById('export-dialog-close').addEventListener('click', hideExportDialog);
    document.getElementById('export-cancel').addEventListener('click', hideExportDialog);

    // Export confirm
    document.getElementById('export-confirm').addEventListener('click', () => {
        const options = collectExportOptions();
        ipcRenderer.send('export-with-options', {
            format: currentExportFormat,
            options: options
        });
        hideExportDialog();
    });
});

// Batch Conversion Dialog functionality
let currentBatchOptions = {};

ipcRenderer.on('show-batch-dialog', () => {
    showBatchDialog();
});

// Universal Converter dialog handlers
ipcRenderer.on('show-universal-converter-dialog', () => {
    showUniversalConverterDialog();
});

// Batch converter menu items - open universal converter with batch mode and correct tool
ipcRenderer.on('show-batch-converter', (event, type) => {
    showUniversalConverterDialog();
    // Map batch type to the appropriate tool
    const toolMap = { image: 'imagemagick', audio: 'ffmpeg', video: 'ffmpeg', pdf: 'libreoffice' };
    const tool = toolMap[type] || 'libreoffice';
    const toolSelect = document.getElementById('converter-tool');
    if (toolSelect) {
        toolSelect.value = tool;
        updateConverterFormats(tool);
    }
    // Enable batch mode
    const batchToggle = document.getElementById('converter-batch-mode');
    if (batchToggle) {
        batchToggle.checked = true;
        batchToggle.dispatchEvent(new Event('change'));
    }
});

ipcRenderer.on('conversion-status', (event, status) => {
    document.getElementById('converter-status').textContent = status;
});

ipcRenderer.on('conversion-complete', (event, result) => {
    document.getElementById('converter-progress').classList.add('hidden');
    if (result.success) {
        window.modals.converterModal.close();
    }
});

ipcRenderer.on('batch-progress', (event, progress) => {
    updateBatchProgress(progress);
});

ipcRenderer.on('folder-selected', (event, { type, path }) => {
    if (type === 'input') {
        document.getElementById('batch-input-folder').value = path;
        validateBatchForm();
    } else if (type === 'output') {
        document.getElementById('batch-output-folder').value = path;
        validateBatchForm();
    } else if (type === 'converter-batch-input') {
        document.getElementById('converter-batch-input-folder').value = path;
    } else if (type === 'converter-batch-output') {
        document.getElementById('converter-batch-output-folder').value = path;
    }
});

function showBatchDialog() {
    window.modals.batchModal.open();

    // Reset form
    document.getElementById('batch-input-folder').value = '';
    document.getElementById('batch-output-folder').value = '';
    document.getElementById('batch-format').value = 'html';
    document.getElementById('batch-include-subfolders').checked = true;
    document.getElementById('batch-progress').classList.add('hidden');
    document.getElementById('batch-start').disabled = true;

    currentBatchOptions = {
        template: 'default',
        metadata: {},
        variables: {},
        toc: false,
        tocDepth: 3,
        numberSections: false,
        citeproc: false
    };
}

function hideBatchDialog() {
    window.modals.batchModal.close();
}

function updateBatchProgress(progress) {
    const progressSection = document.getElementById('batch-progress');
    const progressFill = document.getElementById('batch-progress-fill');
    const progressText = document.getElementById('batch-progress-text');
    const progressCount = document.getElementById('batch-progress-count');

    progressSection.classList.remove('hidden');

    const percentage = Math.round((progress.completed / progress.total) * 100);
    progressFill.style.width = `${percentage}%`;

    if (progress.completed === progress.total) {
        progressText.textContent = 'Conversion complete!';
    } else {
        progressText.textContent = `Processing: ${progress.currentFile}`;
    }

    progressCount.textContent = `${progress.completed} / ${progress.total}`;
}

function validateBatchForm() {
    const inputFolder = document.getElementById('batch-input-folder').value.trim();
    const outputFolder = document.getElementById('batch-output-folder').value.trim();
    const startButton = document.getElementById('batch-start');

    startButton.disabled = !inputFolder || !outputFolder;
}

// Event listeners for batch dialog
document.addEventListener('DOMContentLoaded', () => {
    // Browse input folder
    document.getElementById('browse-input-folder').addEventListener('click', () => {
        ipcRenderer.send('select-folder', 'input');
    });

    // Browse output folder
    document.getElementById('browse-output-folder').addEventListener('click', () => {
        ipcRenderer.send('select-folder', 'output');
    });

    // Show advanced options
    document.getElementById('batch-show-options').addEventListener('click', () => {
        const format = document.getElementById('batch-format').value;
        currentExportFormat = format;
        showExportDialog(format);
    });

    // Dialog close buttons
    document.getElementById('batch-dialog-close').addEventListener('click', hideBatchDialog);
    document.getElementById('batch-cancel').addEventListener('click', hideBatchDialog);

    // Start batch conversion
    document.getElementById('batch-start').addEventListener('click', () => {
        const inputFolder = document.getElementById('batch-input-folder').value.trim();
        const outputFolder = document.getElementById('batch-output-folder').value.trim();
        const format = document.getElementById('batch-format').value;

        if (!inputFolder || !outputFolder) {
            return;
        }

        // Use current export options from advanced dialog if they were set
        const options = currentBatchOptions;

        // Start batch conversion
        ipcRenderer.send('batch-convert', {
            inputFolder,
            outputFolder,
            format,
            options
        });

        // Show progress
        document.getElementById('batch-progress').classList.remove('hidden');
        document.getElementById('batch-start').disabled = true;
    });

    // Input validation
    document.getElementById('batch-input-folder').addEventListener('input', validateBatchForm);
    document.getElementById('batch-output-folder').addEventListener('input', validateBatchForm);
});

// Override the export dialog confirm to also save batch options
const originalExportConfirm = document.getElementById('export-confirm');
if (originalExportConfirm) {
    originalExportConfirm.addEventListener('click', () => {
        // If batch dialog is open, save options for batch conversion
        if (window.modals.batchModal.isOpen()) {
            currentBatchOptions = collectExportOptions();
        }
    });
}

// Universal File Converter Dialog Functions
let converterFilePath = '';

// Format definitions for each converter
const converterFormats = {
    libreoffice: {
        input: [
            { value: 'docx', label: 'Word Document (DOCX)' },
            { value: 'doc', label: 'Word 97-2003 (DOC)' },
            { value: 'odt', label: 'OpenDocument Text (ODT)' },
            { value: 'rtf', label: 'Rich Text Format (RTF)' },
            { value: 'txt', label: 'Plain Text (TXT)' },
            { value: 'html', label: 'HTML Document' },
            { value: 'htm', label: 'HTM Document' },
            { value: 'xlsx', label: 'Excel Spreadsheet (XLSX)' },
            { value: 'xls', label: 'Excel 97-2003 (XLS)' },
            { value: 'ods', label: 'OpenDocument Spreadsheet (ODS)' },
            { value: 'csv', label: 'Comma Separated Values (CSV)' },
            { value: 'pptx', label: 'PowerPoint (PPTX)' },
            { value: 'ppt', label: 'PowerPoint 97-2003 (PPT)' },
            { value: 'odp', label: 'OpenDocument Presentation (ODP)' }
        ],
        output: [
            { value: 'pdf', label: 'PDF Document' },
            { value: 'docx', label: 'Word Document (DOCX)' },
            { value: 'doc', label: 'Word 97-2003 (DOC)' },
            { value: 'odt', label: 'OpenDocument Text (ODT)' },
            { value: 'rtf', label: 'Rich Text Format (RTF)' },
            { value: 'txt', label: 'Plain Text (TXT)' },
            { value: 'html', label: 'HTML Document' },
            { value: 'xlsx', label: 'Excel Spreadsheet (XLSX)' },
            { value: 'xls', label: 'Excel 97-2003 (XLS)' },
            { value: 'ods', label: 'OpenDocument Spreadsheet (ODS)' },
            { value: 'csv', label: 'CSV' },
            { value: 'pptx', label: 'PowerPoint (PPTX)' },
            { value: 'ppt', label: 'PowerPoint 97-2003 (PPT)' },
            { value: 'odp', label: 'OpenDocument Presentation (ODP)' }
        ]
    },
    imagemagick: {
        input: [
            { value: 'jpg', label: 'JPEG Image (JPG)' },
            { value: 'jpeg', label: 'JPEG Image (JPEG)' },
            { value: 'png', label: 'PNG Image' },
            { value: 'gif', label: 'GIF Image' },
            { value: 'bmp', label: 'Bitmap Image (BMP)' },
            { value: 'tiff', label: 'TIFF Image' },
            { value: 'tif', label: 'TIF Image' },
            { value: 'webp', label: 'WebP Image' },
            { value: 'svg', label: 'SVG Vector Image' },
            { value: 'ico', label: 'Icon File (ICO)' },
            { value: 'psd', label: 'Photoshop (PSD)' },
            { value: 'raw', label: 'RAW Image' },
            { value: 'cr2', label: 'Canon RAW (CR2)' },
            { value: 'nef', label: 'Nikon RAW (NEF)' },
            { value: 'heic', label: 'HEIC Image' },
            { value: 'avif', label: 'AVIF Image' }
        ],
        output: [
            { value: 'jpg', label: 'JPEG Image (JPG)' },
            { value: 'png', label: 'PNG Image' },
            { value: 'gif', label: 'GIF Image' },
            { value: 'bmp', label: 'Bitmap Image (BMP)' },
            { value: 'tiff', label: 'TIFF Image' },
            { value: 'webp', label: 'WebP Image' },
            { value: 'svg', label: 'SVG Vector Image' },
            { value: 'ico', label: 'Icon File (ICO)' },
            { value: 'pdf', label: 'PDF Document' },
            { value: 'eps', label: 'EPS Vector' },
            { value: 'ps', label: 'PostScript' },
            { value: 'avif', label: 'AVIF Image' }
        ]
    },
    ffmpeg: {
        input: [
            { value: 'mp4', label: 'MP4 Video' },
            { value: 'avi', label: 'AVI Video' },
            { value: 'mov', label: 'MOV Video (QuickTime)' },
            { value: 'mkv', label: 'MKV Video (Matroska)' },
            { value: 'wmv', label: 'WMV Video (Windows Media)' },
            { value: 'flv', label: 'FLV Video (Flash)' },
            { value: 'webm', label: 'WebM Video' },
            { value: 'mpeg', label: 'MPEG Video' },
            { value: 'mpg', label: 'MPG Video' },
            { value: 'm4v', label: 'M4V Video' },
            { value: 'mp3', label: 'MP3 Audio' },
            { value: 'wav', label: 'WAV Audio' },
            { value: 'ogg', label: 'OGG Audio' },
            { value: 'flac', label: 'FLAC Audio' },
            { value: 'aac', label: 'AAC Audio' },
            { value: 'm4a', label: 'M4A Audio' },
            { value: 'wma', label: 'WMA Audio' }
        ],
        output: [
            { value: 'mp4', label: 'MP4 Video' },
            { value: 'avi', label: 'AVI Video' },
            { value: 'mov', label: 'MOV Video (QuickTime)' },
            { value: 'mkv', label: 'MKV Video (Matroska)' },
            { value: 'webm', label: 'WebM Video' },
            { value: 'mpeg', label: 'MPEG Video' },
            { value: 'gif', label: 'Animated GIF' },
            { value: 'mp3', label: 'MP3 Audio' },
            { value: 'wav', label: 'WAV Audio' },
            { value: 'ogg', label: 'OGG Audio' },
            { value: 'flac', label: 'FLAC Audio' },
            { value: 'aac', label: 'AAC Audio' },
            { value: 'm4a', label: 'M4A Audio' }
        ]
    },
    pandoc: {
        input: [
            { value: 'md', label: 'Markdown (MD)' },
            { value: 'markdown', label: 'Markdown' },
            { value: 'html', label: 'HTML Document' },
            { value: 'docx', label: 'Word Document (DOCX)' },
            { value: 'odt', label: 'OpenDocument Text (ODT)' },
            { value: 'rtf', label: 'Rich Text Format (RTF)' },
            { value: 'tex', label: 'LaTeX Document' },
            { value: 'latex', label: 'LaTeX' },
            { value: 'epub', label: 'EPUB eBook' },
            { value: 'rst', label: 'reStructuredText (RST)' },
            { value: 'textile', label: 'Textile' },
            { value: 'org', label: 'Org Mode' },
            { value: 'mediawiki', label: 'MediaWiki' },
            { value: 'docbook', label: 'DocBook XML' }
        ],
        output: [
            { value: 'html', label: 'HTML Document' },
            { value: 'pdf', label: 'PDF Document' },
            { value: 'docx', label: 'Word Document (DOCX)' },
            { value: 'odt', label: 'OpenDocument Text (ODT)' },
            { value: 'rtf', label: 'Rich Text Format (RTF)' },
            { value: 'epub', label: 'EPUB eBook' },
            { value: 'latex', label: 'LaTeX Document' },
            { value: 'md', label: 'Markdown (MD)' },
            { value: 'rst', label: 'reStructuredText (RST)' },
            { value: 'textile', label: 'Textile' },
            { value: 'org', label: 'Org Mode' },
            { value: 'mediawiki', label: 'MediaWiki' },
            { value: 'docbook', label: 'DocBook XML' },
            { value: 'pptx', label: 'PowerPoint (PPTX)' }
        ]
    }
};

function showUniversalConverterDialog() {
    window.modals.converterModal.open();
    converterFilePath = '';
    document.getElementById('converter-file-path').value = '';
    document.getElementById('converter-tool').value = 'libreoffice';
    document.getElementById('converter-progress').classList.add('hidden');
    updateConverterFormats('libreoffice');
}

function updateConverterFormats(tool) {
    const fromSelect = document.getElementById('converter-from');
    const toSelect = document.getElementById('converter-to');
    const helpText = document.getElementById('converter-tool-help');

    // Clear existing options
    fromSelect.innerHTML = '';
    toSelect.innerHTML = '';

    // Get formats for selected tool
    const formats = converterFormats[tool];

    if (formats) {
        // Populate input formats
        formats.input.forEach(format => {
            const option = document.createElement('option');
            option.value = format.value;
            option.textContent = format.label;
            fromSelect.appendChild(option);
        });

        // Populate output formats
        formats.output.forEach(format => {
            const option = document.createElement('option');
            option.value = format.value;
            option.textContent = format.label;
            toSelect.appendChild(option);
        });

        // Update help text
        if (tool === 'libreoffice') {
            helpText.textContent = 'Documents, Spreadsheets, Presentations - Office file conversions';
        } else if (tool === 'imagemagick') {
            helpText.textContent = 'Image format conversions - JPG, PNG, GIF, TIFF, WebP, SVG, and more';
        } else if (tool === 'ffmpeg') {
            helpText.textContent = 'Video and audio conversions - MP4, AVI, MOV, MP3, WAV, and more';
        } else if (tool === 'pandoc') {
            helpText.textContent = 'Document markup conversions - Markdown, HTML, LaTeX, EPUB, and more';
        }
    }
}

function updateConverterAdvancedOptions(tool) {
    // Hide all tool-specific options
    const allOptions = document.querySelectorAll('.converter-options');
    allOptions.forEach(opt => opt.classList.add('hidden'));

    // Show options for selected tool
    const toolOptions = document.querySelector(`.${tool}-options`);
    if (toolOptions) {
        toolOptions.classList.remove('hidden');
    }
}

function collectConverterAdvancedOptions(tool) {
    const options = {};
    const advancedMode = document.getElementById('converter-advanced-toggle').checked;

    if (!advancedMode) {
        return options;
    }

    // Tool-specific options
    if (tool === 'imagemagick') {
        options.quality = document.getElementById('imagemagick-quality').value;
        options.dpi = document.getElementById('imagemagick-dpi').value || null;
        options.resize = document.getElementById('imagemagick-resize').value || null;
        options.compression = document.getElementById('imagemagick-compression').value || null;
    } else if (tool === 'ffmpeg') {
        options.videoCodec = document.getElementById('ffmpeg-video-codec').value || null;
        options.audioCodec = document.getElementById('ffmpeg-audio-codec').value || null;
        options.bitrate = document.getElementById('ffmpeg-bitrate').value || null;
        options.preset = document.getElementById('ffmpeg-preset').value || null;
        options.framerate = document.getElementById('ffmpeg-framerate').value || null;
    } else if (tool === 'libreoffice') {
        options.quality = document.getElementById('libreoffice-quality').value || null;
        options.pageRange = document.getElementById('libreoffice-page-range').value || null;
        options.exportBookmarks = document.getElementById('libreoffice-export-bookmarks').checked;
    }

    return options;
}

document.addEventListener('DOMContentLoaded', () => {
    // Universal Converter tool change
    const converterTool = document.getElementById('converter-tool');
    if (converterTool) {
        converterTool.addEventListener('change', (e) => {
            updateConverterFormats(e.target.value);
            updateConverterAdvancedOptions(e.target.value);
        });
    }

    // Batch mode toggle
    const converterBatchMode = document.getElementById('converter-batch-mode');
    if (converterBatchMode) {
        converterBatchMode.addEventListener('change', (e) => {
            const batchOptions = document.getElementById('converter-batch-options');
            const singleFileSection = document.getElementById('converter-file-path').closest('.export-section');

            if (e.target.checked) {
                batchOptions.classList.remove('hidden');
                singleFileSection.style.display = 'none';
            } else {
                batchOptions.classList.add('hidden');
                singleFileSection.style.display = 'block';
            }
        });
    }

    // Advanced options toggle
    const converterAdvancedToggle = document.getElementById('converter-advanced-toggle');
    if (converterAdvancedToggle) {
        converterAdvancedToggle.addEventListener('change', (e) => {
            const advancedOptions = document.getElementById('converter-advanced-options');
            if (e.target.checked) {
                advancedOptions.classList.remove('hidden');
                // Update which tool-specific options to show
                updateConverterAdvancedOptions(document.getElementById('converter-tool').value);
            } else {
                advancedOptions.classList.add('hidden');
            }
        });
    }

    // ImageMagick quality slider
    const imagemagickQuality = document.getElementById('imagemagick-quality');
    if (imagemagickQuality) {
        imagemagickQuality.addEventListener('input', (e) => {
            document.getElementById('imagemagick-quality-value').textContent = e.target.value;
        });
    }

    // Browse batch input folder
    const browseBatchInput = document.getElementById('browse-converter-batch-input');
    if (browseBatchInput) {
        browseBatchInput.addEventListener('click', () => {
            ipcRenderer.send('select-folder', 'converter-batch-input');
        });
    }

    // Browse batch output folder
    const browseBatchOutput = document.getElementById('browse-converter-batch-output');
    if (browseBatchOutput) {
        browseBatchOutput.addEventListener('click', () => {
            ipcRenderer.send('select-folder', 'converter-batch-output');
        });
    }

    // Browse for file to convert
    const browseConverterFile = document.getElementById('browse-converter-file');
    if (browseConverterFile) {
        browseConverterFile.addEventListener('click', () => {
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = '*';
            input.onchange = (e) => {
                const file = e.target.files[0];
                if (file) {
                    converterFilePath = file.path;
                    document.getElementById('converter-file-path').value = file.path;
                }
            };
            input.click();
        });
    }

    // Universal Converter dialog close
    const converterDialogClose = document.getElementById('converter-dialog-close');
    if (converterDialogClose) {
        converterDialogClose.addEventListener('click', () => {
            window.modals.converterModal.close();
        });
    }

    // Universal Converter cancel
    const converterCancel = document.getElementById('converter-cancel');
    if (converterCancel) {
        converterCancel.addEventListener('click', () => {
            window.modals.converterModal.close();
        });
    }

    // Universal Converter convert
    const converterConvert = document.getElementById('converter-convert');
    if (converterConvert) {
        converterConvert.addEventListener('click', () => {
            const tool = document.getElementById('converter-tool').value;
            const fromFormat = document.getElementById('converter-from').value;
            const toFormat = document.getElementById('converter-to').value;
            const batchMode = document.getElementById('converter-batch-mode').checked;
            const advancedOptions = collectConverterAdvancedOptions(tool);

            if (batchMode) {
                // Batch conversion
                const inputFolder = document.getElementById('converter-batch-input-folder').value.trim();
                const outputFolder = document.getElementById('converter-batch-output-folder').value.trim();
                const includeSubfolders = document.getElementById('converter-batch-subfolders').checked;

                if (!inputFolder || !outputFolder) {
                    document.getElementById('converter-progress').classList.remove('hidden');
                    document.getElementById('converter-status').textContent = 'Select both input and output folders for batch conversion.';
                    return;
                }

                // Show progress
                document.getElementById('converter-progress').classList.remove('hidden');

                // Send batch conversion request
                ipcRenderer.send('universal-convert-batch', {
                    tool,
                    fromFormat,
                    toFormat,
                    inputFolder,
                    outputFolder,
                    includeSubfolders,
                    advancedOptions
                });
            } else {
                // Single file conversion
                const filePath = converterFilePath;

                if (!filePath) {
                    document.getElementById('converter-progress').classList.remove('hidden');
                    document.getElementById('converter-status').textContent = 'Select a file to convert.';
                    return;
                }

                // Show progress
                document.getElementById('converter-progress').classList.remove('hidden');

                // Send single file conversion request
                ipcRenderer.send('universal-convert', {
                    tool,
                    fromFormat,
                    toFormat,
                    filePath,
                    advancedOptions
                });
            }
        });
    }
});

// IPC event listeners for recent files functionality
ipcRenderer.on('recent-files-cleared', () => {
    if (tabManager) {
        tabManager.recentFiles = [];
        localStorage.setItem('recentFiles', JSON.stringify([]));
        console.log('Recent files cleared');
    }
});

// ========================================
// PDF Editor Dialog Functionality
// ========================================

let currentPDFOperation = null;
let mergeFilePaths = [];

// Show Table Generator Dialog
ipcRenderer.on('show-table-generator', () => {
    showTableGenerator();
});

// Show PDF Editor Dialog
ipcRenderer.on('show-pdf-editor-dialog', (event, operation, openedFilePath) => {
    currentPDFOperation = operation;
    showPDFEditorDialog(operation, openedFilePath);
});

function showPDFEditorDialog(operation, openedFilePath = null) {
    const title = document.getElementById('pdf-editor-title');

    // Hide all operation sections
    document.querySelectorAll('.pdf-operation-section').forEach(section => {
        section.classList.add('hidden');
    });

    // Hide visual thumbnail sidebar by default
    const sidebar = document.getElementById('pdf-thumbnail-sidebar');
    if (sidebar) {
        sidebar.classList.add('hidden');
    }
    const body = document.querySelector('.pdf-editor-body');
    if (body) {
        body.classList.remove('side-by-side');
    }
    pdfDocInstance = null;
    pdfPreviewState = { pages: [], filePath: '' };

    // Show the appropriate section and set title
    let sectionId, titleText;
    switch (operation) {
        case 'merge':
            sectionId = 'pdf-merge-section';
            titleText = 'Merge PDFs';
            mergeFilePaths = [];
            // If we have an opened file, add it as the first file to merge
            if (openedFilePath) {
                mergeFilePaths.push(openedFilePath);
            }
            updateMergeFilesList();
            break;
        case 'split':
            sectionId = 'pdf-split-section';
            titleText = 'Split PDF';
            // Pre-fill input path if we have an opened file
            if (openedFilePath) {
                document.getElementById('split-input-path').value = openedFilePath;
            }
            break;
        case 'compress':
            sectionId = 'pdf-compress-section';
            titleText = 'Compress PDF';
            if (openedFilePath) {
                document.getElementById('compress-input-path').value = openedFilePath;
            }
            break;
        case 'rotate':
            sectionId = 'pdf-rotate-section';
            titleText = 'Rotate Pages';
            if (openedFilePath) {
                const rotateInput = document.getElementById('rotate-input-path');
                if (rotateInput) {
                    rotateInput.value = openedFilePath;
                    // Trigger thumbnail generation
                    setTimeout(() => onPDFFileSelected('rotate-input-path', openedFilePath), 50);
                }
            }
            break;
        case 'delete':
            sectionId = 'pdf-delete-section';
            titleText = 'Delete Pages';
            if (openedFilePath) {
                const deleteInput = document.getElementById('delete-input-path');
                if (deleteInput) {
                    deleteInput.value = openedFilePath;
                    // Trigger thumbnail generation
                    setTimeout(() => onPDFFileSelected('delete-input-path', openedFilePath), 50);
                }
            }
            break;
        case 'reorder':
            sectionId = 'pdf-reorder-section';
            titleText = 'Reorder Pages';
            if (openedFilePath) {
                const reorderInput = document.getElementById('reorder-input-path');
                if (reorderInput) {
                    reorderInput.value = openedFilePath;
                    // Trigger thumbnail generation
                    setTimeout(() => onPDFFileSelected('reorder-input-path', openedFilePath), 50);
                }
            }
            break;
        case 'watermark':
            sectionId = 'pdf-watermark-section';
            titleText = 'Add Watermark';
            if (openedFilePath) {
                const watermarkInput = document.getElementById('watermark-input-path');
                if (watermarkInput) watermarkInput.value = openedFilePath;
            }
            break;
        case 'encrypt':
            sectionId = 'pdf-encrypt-section';
            titleText = 'Password Protection';
            if (openedFilePath) {
                const encryptInput = document.getElementById('encrypt-input-path');
                if (encryptInput) encryptInput.value = openedFilePath;
            }
            break;
        case 'decrypt':
            sectionId = 'pdf-decrypt-section';
            titleText = 'Remove Password';
            if (openedFilePath) {
                const decryptInput = document.getElementById('decrypt-input-path');
                if (decryptInput) decryptInput.value = openedFilePath;
            }
            break;
        case 'permissions':
            sectionId = 'pdf-permissions-section';
            titleText = 'Set Permissions';
            if (openedFilePath) {
                const permInput = document.getElementById('permissions-input-path');
                if (permInput) permInput.value = openedFilePath;
            }
            break;
    }

    title.textContent = titleText;
    document.getElementById(sectionId).classList.remove('hidden');
    window.modals.pdfEditorModal.open();
}

function hidePDFEditorDialog() {
    window.modals.pdfEditorModal.close();
    clearPDFStatus();
    document.getElementById('pdf-progress').classList.add('hidden');
    document.getElementById('pdf-progress-text').textContent = 'Processing...';
    const progressFill = document.getElementById('pdf-progress-fill');
    if (progressFill) {
        progressFill.style.width = '0%';
    }
    currentPDFOperation = null;
}

function updateMergeFilesList() {
    const listContainer = document.getElementById('merge-files-list');
    listContainer.innerHTML = '';

    mergeFilePaths.forEach((filePath, index) => {
        const fileEntry = document.createElement('div');
        fileEntry.className = 'file-entry';
        fileEntry.innerHTML = `
            <span class="file-name">${filePath.split(/[\\/]/).pop()}</span>
            <button class="remove-file" data-index="${index}">Remove</button>
        `;
        listContainer.appendChild(fileEntry);
    });
}

// PDF Editor Event Listeners
document.addEventListener('DOMContentLoaded', () => {
    // Close PDF Editor Dialog
    const pdfEditorClose = document.getElementById('pdf-editor-dialog-close');
    if (pdfEditorClose) {
        pdfEditorClose.addEventListener('click', hidePDFEditorDialog);
    }

    const pdfEditorCancel = document.getElementById('pdf-editor-cancel');
    if (pdfEditorCancel) {
        pdfEditorCancel.addEventListener('click', hidePDFEditorDialog);
    }

    // Process button
    const pdfEditorProcess = document.getElementById('pdf-editor-process');
    if (pdfEditorProcess) {
        pdfEditorProcess.addEventListener('click', processPDFOperation);
    }

    // Merge PDFs - Add file button
    const addMergeFile = document.getElementById('add-merge-file');
    if (addMergeFile) {
        addMergeFile.addEventListener('click', () => {
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = '.pdf';
            input.multiple = true;
            input.onchange = (e) => {
                const files = Array.from(e.target.files);
                files.forEach(file => {
                    if (!mergeFilePaths.includes(file.path)) {
                        mergeFilePaths.push(file.path);
                    }
                });
                updateMergeFilesList();
            };
            input.click();
        });
    }

    // Remove file from merge list (using event delegation)
    const mergeFilesList = document.getElementById('merge-files-list');
    if (mergeFilesList) {
        mergeFilesList.addEventListener('click', (e) => {
            if (e.target.classList.contains('remove-file')) {
                const index = parseInt(e.target.dataset.index);
                mergeFilePaths.splice(index, 1);
                updateMergeFilesList();
            }
        });
    }

    // Browse buttons for all operations
    const browseButtons = [
        { id: 'browse-merge-output', inputId: 'merge-output-path', saveDialog: true },
        { id: 'browse-split-input', inputId: 'split-input-path', saveDialog: false },
        { id: 'browse-split-output', inputId: 'split-output-folder', folder: true },
        { id: 'browse-compress-input', inputId: 'compress-input-path', saveDialog: false },
        { id: 'browse-compress-output', inputId: 'compress-output-path', saveDialog: true },
        { id: 'browse-rotate-input', inputId: 'rotate-input-path', saveDialog: false },
        { id: 'browse-rotate-output', inputId: 'rotate-output-path', saveDialog: true },
        { id: 'browse-delete-input', inputId: 'delete-input-path', saveDialog: false },
        { id: 'browse-delete-output', inputId: 'delete-output-path', saveDialog: true },
        { id: 'browse-reorder-input', inputId: 'reorder-input-path', saveDialog: false },
        { id: 'browse-reorder-output', inputId: 'reorder-output-path', saveDialog: true },
        { id: 'browse-watermark-input', inputId: 'watermark-input-path', saveDialog: false },
        { id: 'browse-watermark-output', inputId: 'watermark-output-path', saveDialog: true },
        { id: 'browse-encrypt-input', inputId: 'encrypt-input-path', saveDialog: false },
        { id: 'browse-encrypt-output', inputId: 'encrypt-output-path', saveDialog: true },
        { id: 'browse-decrypt-input', inputId: 'decrypt-input-path', saveDialog: false },
        { id: 'browse-decrypt-output', inputId: 'decrypt-output-path', saveDialog: true },
        { id: 'browse-permissions-input', inputId: 'permissions-input-path', saveDialog: false },
        { id: 'browse-permissions-output', inputId: 'permissions-output-path', saveDialog: true }
    ];

    browseButtons.forEach(button => {
        const btn = document.getElementById(button.id);
        if (btn) {
            btn.addEventListener('click', () => {
                const input = document.createElement('input');
                input.type = 'file';

                if (button.folder) {
                    // Request folder selection via IPC
                    ipcRenderer.send('select-pdf-folder', button.inputId);
                } else if (button.saveDialog) {
                    input.nwsaveas = true;
                    input.accept = '.pdf';
                    input.onchange = (e) => {
                        const file = e.target.files[0];
                        if (file) {
                            document.getElementById(button.inputId).value = file.path;
                            onPDFFileSelected(button.inputId, file.path);
                        }
                    };
                    input.click();
                } else {
                    input.accept = '.pdf';
                    input.onchange = (e) => {
                        const file = e.target.files[0];
                        if (file) {
                            document.getElementById(button.inputId).value = file.path;
                            onPDFFileSelected(button.inputId, file.path);
                        }
                    };
                    input.click();
                }
            });
        }
    });

    // Split mode change handler
    const splitMode = document.getElementById('split-mode');
    if (splitMode) {
        splitMode.addEventListener('change', (e) => {
            // Hide all split options
            document.getElementById('split-pages-options').classList.add('hidden');
            document.getElementById('split-interval-options').classList.add('hidden');
            document.getElementById('split-size-options').classList.add('hidden');

            // Show selected split option
            if (e.target.value === 'pages') {
                document.getElementById('split-pages-options').classList.remove('hidden');
            } else if (e.target.value === 'interval') {
                document.getElementById('split-interval-options').classList.remove('hidden');
            } else if (e.target.value === 'size') {
                document.getElementById('split-size-options').classList.remove('hidden');
            }
        });
    }

    // Watermark opacity slider
    const watermarkOpacity = document.getElementById('watermark-opacity');
    if (watermarkOpacity) {
        watermarkOpacity.addEventListener('input', (e) => {
            document.getElementById('watermark-opacity-value').textContent = e.target.value;
        });
    }

    // Watermark pages selection
    const watermarkPages = document.getElementById('watermark-pages');
    if (watermarkPages) {
        watermarkPages.addEventListener('change', (e) => {
            const customPages = document.getElementById('watermark-custom-pages');
            if (e.target.value === 'custom') {
                customPages.classList.remove('hidden');
            } else {
                customPages.classList.add('hidden');
            }
        });
    }

    // Overwrite checkbox handlers - toggle Save As section visibility
    const overwriteCheckboxes = [
        { checkbox: 'compress-overwrite', section: 'compress-saveas-section' },
        { checkbox: 'rotate-overwrite', section: 'rotate-saveas-section' },
        { checkbox: 'delete-overwrite', section: 'delete-saveas-section' },
        { checkbox: 'reorder-overwrite', section: 'reorder-saveas-section' },
        { checkbox: 'watermark-overwrite', section: 'watermark-saveas-section' },
        { checkbox: 'encrypt-overwrite', section: 'encrypt-saveas-section' },
        { checkbox: 'decrypt-overwrite', section: 'decrypt-saveas-section' },
        { checkbox: 'permissions-overwrite', section: 'permissions-saveas-section' }
    ];

    overwriteCheckboxes.forEach(item => {
        const checkbox = document.getElementById(item.checkbox);
        const section = document.getElementById(item.section);
        if (checkbox && section) {
            checkbox.addEventListener('change', (e) => {
                if (e.target.checked) {
                    section.classList.add('hidden');
                } else {
                    section.classList.remove('hidden');
                }
            });
        }
    });

    // Load current page order button
    const loadCurrentOrder = document.getElementById('load-current-order');
    if (loadCurrentOrder) {
        loadCurrentOrder.addEventListener('click', () => {
            const inputPath = document.getElementById('reorder-input-path').value;
            if (!inputPath) {
                showPDFValidationMessage('Select a PDF file before loading the current page order.', '#reorder-input-path');
                return;
            }
            // Request page count from main process
            ipcRenderer.send('get-pdf-page-count', inputPath);
        });
    }
});

// Handle folder selection response
ipcRenderer.on('pdf-folder-selected', (event, { inputId, path }) => {
    document.getElementById(inputId).value = path;
});

// Handle PDF page count response
ipcRenderer.on('pdf-page-count', (event, { count, error }) => {
    if (error) {
        showPDFStatus(`Error reading PDF: ${error}`, 'warning');
        return;
    }

    const currentOrder = Array.from({ length: count }, (_, i) => i + 1).join(', ');
    document.getElementById('current-order-display').textContent = currentOrder;
    document.getElementById('current-page-order').classList.remove('hidden');
    document.getElementById('reorder-pages').value = currentOrder;
});

function getPDFStatusElement() {
    return document.getElementById('pdf-status-message');
}

function showPDFStatus(message, type = 'info') {
    const status = getPDFStatusElement();
    if (!status) return;

    status.textContent = message;
    status.classList.remove('hidden', 'info-message', 'warning-message', 'success-message');
    status.classList.add(`${type}-message`);
}

function clearPDFStatus() {
    const status = getPDFStatusElement();
    if (!status) return;

    status.textContent = '';
    status.classList.remove('info-message', 'warning-message', 'success-message');
    status.classList.add('hidden');
}

function showPDFValidationMessage(message, focusSelector = null) {
    showPDFStatus(message, 'warning');

    if (focusSelector) {
        const field = document.querySelector(focusSelector);
        if (field && typeof field.focus === 'function') {
            field.focus();
        }
    }
}

// Process PDF Operation
function processPDFOperation() {
    const operation = currentPDFOperation;
    const operationData = { operation };

    try {
        switch (operation) {
            case 'merge':
                if (mergeFilePaths.length < 2) {
                    showPDFValidationMessage('Add at least 2 PDF files to merge first.', '#add-merge-file');
                    return;
                }
                operationData.inputFiles = mergeFilePaths;
                operationData.outputPath = document.getElementById('merge-output-path').value.trim();
                if (!operationData.outputPath) {
                    showPDFValidationMessage('Select an output file path.', '#merge-output-path');
                    return;
                }
                break;

            case 'split':
                operationData.inputPath = document.getElementById('split-input-path').value.trim();
                operationData.outputFolder = document.getElementById('split-output-folder').value.trim();
                operationData.splitMode = document.getElementById('split-mode').value;

                if (!operationData.inputPath || !operationData.outputFolder) {
                    showPDFValidationMessage('Select both an input PDF and an output folder.', '#split-input-path');
                    return;
                }

                if (operationData.splitMode === 'pages') {
                    operationData.pageRanges = document.getElementById('split-page-ranges').value.trim();
                } else if (operationData.splitMode === 'interval') {
                    operationData.interval = parseInt(document.getElementById('split-interval').value);
                } else if (operationData.splitMode === 'size') {
                    operationData.maxSize = parseInt(document.getElementById('split-size').value);
                }
                break;

            case 'compress':
                operationData.inputPath = document.getElementById('compress-input-path').value.trim();
                operationData.overwrite = document.getElementById('compress-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('compress-output-path').value.trim();
                operationData.compressionLevel = document.getElementById('compress-level').value;
                operationData.compressImages = document.getElementById('compress-images').checked;
                operationData.removeDuplicates = document.getElementById('compress-remove-duplicates').checked;
                operationData.optimizeFonts = document.getElementById('compress-optimize-fonts').checked;

                if (!operationData.inputPath || !operationData.outputPath) {
                    showPDFValidationMessage(
                        'Select an input PDF' + (operationData.overwrite ? '.' : ' and an output file path.'),
                        '#compress-input-path'
                    );
                    return;
                }
                break;

            case 'rotate':
                operationData.inputPath = document.getElementById('rotate-input-path').value.trim();
                operationData.overwrite = document.getElementById('rotate-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('rotate-output-path').value.trim();
                operationData.pages = document.getElementById('rotate-pages').value.trim();
                operationData.angle = parseInt(document.getElementById('rotate-angle').value);

                if (!operationData.inputPath || !operationData.outputPath) {
                    showPDFValidationMessage(
                        'Select an input PDF' + (operationData.overwrite ? '.' : ' and an output file path.'),
                        '#rotate-input-path'
                    );
                    return;
                }
                break;

            case 'delete':
                operationData.inputPath = document.getElementById('delete-input-path').value.trim();
                operationData.overwrite = document.getElementById('delete-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('delete-output-path').value.trim();
                operationData.pages = document.getElementById('delete-pages').value.trim();

                if (!operationData.inputPath || !operationData.outputPath || !operationData.pages) {
                    showPDFValidationMessage('Fill in the input file, output path, and pages to delete.', '#delete-input-path');
                    return;
                }
                break;

            case 'reorder':
                operationData.inputPath = document.getElementById('reorder-input-path').value.trim();
                operationData.overwrite = document.getElementById('reorder-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('reorder-output-path').value.trim();
                operationData.newOrder = document.getElementById('reorder-pages').value.trim();

                if (!operationData.inputPath || !operationData.outputPath || !operationData.newOrder) {
                    showPDFValidationMessage('Fill in the input file, output path, and new page order.', '#reorder-input-path');
                    return;
                }
                break;

            case 'watermark':
                operationData.inputPath = document.getElementById('watermark-input-path').value.trim();
                operationData.overwrite = document.getElementById('watermark-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('watermark-output-path').value.trim();
                operationData.text = document.getElementById('watermark-text').value.trim();
                operationData.fontSize = parseInt(document.getElementById('watermark-font-size').value);
                operationData.opacity = parseInt(document.getElementById('watermark-opacity').value) / 100;
                operationData.position = document.getElementById('watermark-position').value;
                operationData.color = document.getElementById('watermark-color').value;
                operationData.pages = document.getElementById('watermark-pages').value;

                if (operationData.pages === 'custom') {
                    operationData.customPages = document.getElementById('watermark-custom-pages').value.trim();
                }

                if (!operationData.inputPath || !operationData.outputPath || !operationData.text) {
                    showPDFValidationMessage('Fill in the input file, output path, and watermark text.', '#watermark-input-path');
                    return;
                }
                break;

            case 'encrypt':
                operationData.inputPath = document.getElementById('encrypt-input-path').value.trim();
                operationData.overwrite = document.getElementById('encrypt-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('encrypt-output-path').value.trim();
                operationData.userPassword = document.getElementById('encrypt-user-password').value;
                operationData.ownerPassword = document.getElementById('encrypt-owner-password').value;
                operationData.encryptionLevel = parseInt(document.getElementById('encrypt-level').value);

                operationData.permissions = {
                    printing: document.getElementById('encrypt-allow-printing').checked,
                    modifying: document.getElementById('encrypt-allow-modify').checked,
                    copying: document.getElementById('encrypt-allow-copy').checked,
                    annotating: document.getElementById('encrypt-allow-annotate').checked,
                    fillingForms: document.getElementById('encrypt-allow-forms').checked,
                    contentAccessibility: document.getElementById('encrypt-allow-extract').checked,
                    documentAssembly: document.getElementById('encrypt-allow-assemble').checked,
                    printingQuality: document.getElementById('encrypt-allow-print-high').checked
                };

                if (!operationData.inputPath || !operationData.outputPath || !operationData.userPassword) {
                    showPDFValidationMessage('Select a file, output path, and user password.', '#encrypt-input-path');
                    return;
                }
                break;

            case 'decrypt':
                operationData.inputPath = document.getElementById('decrypt-input-path').value.trim();
                operationData.overwrite = document.getElementById('decrypt-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('decrypt-output-path').value.trim();
                operationData.password = document.getElementById('decrypt-password').value;

                if (!operationData.inputPath || !operationData.outputPath || !operationData.password) {
                    showPDFValidationMessage('Fill in the input file, output path, and password.', '#decrypt-input-path');
                    return;
                }
                break;

            case 'permissions':
                operationData.inputPath = document.getElementById('permissions-input-path').value.trim();
                operationData.overwrite = document.getElementById('permissions-overwrite').checked;
                operationData.outputPath = operationData.overwrite ? operationData.inputPath : document.getElementById('permissions-output-path').value.trim();
                operationData.currentPassword = document.getElementById('permissions-current-password').value;
                operationData.ownerPassword = document.getElementById('permissions-owner-password').value;

                operationData.permissions = {
                    printing: document.getElementById('permissions-allow-printing').checked,
                    modifying: document.getElementById('permissions-allow-modify').checked,
                    copying: document.getElementById('permissions-allow-copy').checked,
                    annotating: document.getElementById('permissions-allow-annotate').checked,
                    fillingForms: document.getElementById('permissions-allow-forms').checked,
                    contentAccessibility: document.getElementById('permissions-allow-extract').checked,
                    documentAssembly: document.getElementById('permissions-allow-assemble').checked,
                    printingQuality: document.getElementById('permissions-allow-print-high').checked
                };

                if (!operationData.inputPath || !operationData.outputPath || !operationData.ownerPassword) {
                    showPDFValidationMessage('Fill in the input file, output path, and owner password.', '#permissions-input-path');
                    return;
                }
                break;
        }

        clearPDFStatus();
        // Show progress
        document.getElementById('pdf-progress').classList.remove('hidden');
        document.getElementById('pdf-progress-text').textContent = 'Processing PDF...';
        const progressFill = document.getElementById('pdf-progress-fill');
        if (progressFill) {
            progressFill.style.width = '10%';
        }

        // Send to main process
        ipcRenderer.send('process-pdf-operation', operationData);

    } catch (error) {
        showPDFStatus(`Error: ${error.message}`, 'warning');
        console.error('PDF operation error:', error);
    }
}

// Handle PDF operation completion
ipcRenderer.on('pdf-operation-complete', (event, { success, error, message }) => {
    document.getElementById('pdf-progress').classList.add('hidden');

    if (success) {
        showPDFStatus(message || 'PDF operation completed successfully.', 'success');
        setTimeout(() => {
            if (window.modals?.pdfEditorModal?.isOpen()) {
                hidePDFEditorDialog();
            }
        }, 800);
    } else {
        showPDFStatus(`Error: ${error || 'PDF operation failed'}`, 'warning');
    }
});

// Handle PDF operation progress
ipcRenderer.on('pdf-operation-progress', (event, { message, progress }) => {
    document.getElementById('pdf-progress-text').textContent = message;
    if (progress !== undefined) {
        const progressFill = document.getElementById('pdf-progress-fill');
        if (progressFill) {
            progressFill.style.width = `${progress}%`;
        }
    }
});

// Add math rendering support using KaTeX for enhanced preview
function initMathSupport() {
    // Add KaTeX CSS
    const katexCSS = document.createElement('link');
    katexCSS.rel = 'stylesheet';
    katexCSS.href = 'https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css';
    katexCSS.crossOrigin = 'anonymous';
    document.head.appendChild(katexCSS);

    // Add KaTeX JS
    const katexJS = document.createElement('script');
    katexJS.src = 'https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js';
    katexJS.crossOrigin = 'anonymous';
    katexJS.onload = () => {
        // Add auto-render extension
        const autoRenderJS = document.createElement('script');
        autoRenderJS.src = 'https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js';
        autoRenderJS.crossOrigin = 'anonymous';
        autoRenderJS.onload = () => {
            console.log('Math support (KaTeX) initialized');
            // Re-render current preview to include math
            if (tabManager) {
                tabManager.updatePreview();
            }
        };
        document.head.appendChild(autoRenderJS);
    };
    document.head.appendChild(katexJS);
}

// Initialize math support on load
initMathSupport();

// ================================
// Header & Footer Dialog Management
// ================================

let currentFieldTarget = null; // Track which input field is being edited

// Open header/footer settings dialog
function openHeaderFooterDialog() {
    window.modals.headerFooterModal.open();

    // Request current settings from main process
    ipcRenderer.send('get-header-footer-settings');
}

// Close header/footer settings dialog
function closeHeaderFooterDialog() {
    window.modals.headerFooterModal.close();
}

// Open field picker dialog
function openFieldPickerDialog(targetInputId) {
    currentFieldTarget = targetInputId;
    window.modals.fieldPickerModal.open();
}

// Close field picker dialog
function closeFieldPickerDialog() {
    window.modals.fieldPickerModal.close();
    currentFieldTarget = null;
}

// Load settings into dialog
ipcRenderer.on('header-footer-settings-data', (event, settings) => {
    // Enable/disable checkbox
    document.getElementById('hf-enabled').checked = settings.enabled;

    // Header fields
    document.getElementById('header-left').value = settings.header.left || '';
    document.getElementById('header-center').value = settings.header.center || '';
    document.getElementById('header-right').value = settings.header.right || '';

    // Footer fields
    document.getElementById('footer-left').value = settings.footer.left || '';
    document.getElementById('footer-center').value = settings.footer.center || '';
    document.getElementById('footer-right').value = settings.footer.right || '';

    // Logo previews
    if (settings.header.logo) {
        document.getElementById('header-logo-preview').textContent = settings.header.logo.split(/[\\/]/).pop();
    } else {
        document.getElementById('header-logo-preview').textContent = '';
    }

    if (settings.footer.logo) {
        document.getElementById('footer-logo-preview').textContent = settings.footer.logo.split(/[\\/]/).pop();
    } else {
        document.getElementById('footer-logo-preview').textContent = '';
    }

    // Update config content visibility
    toggleConfigContent();
});

// Toggle config content based on enabled checkbox
function toggleConfigContent() {
    const enabled = document.getElementById('hf-enabled').checked;
    const configContent = document.getElementById('hf-config-content');

    if (enabled) {
        configContent.classList.remove('disabled');
    } else {
        configContent.classList.add('disabled');
    }
}

// Save header/footer settings
function saveHeaderFooterSettings() {
    const settings = {
        enabled: document.getElementById('hf-enabled').checked,
        header: {
            left: document.getElementById('header-left').value || '',
            center: document.getElementById('header-center').value || '',
            right: document.getElementById('header-right').value || '',
            logo: null // Logo paths are managed separately
        },
        footer: {
            left: document.getElementById('footer-left').value || '',
            center: document.getElementById('footer-center').value || '',
            right: document.getElementById('footer-right').value || '',
            logo: null
        }
    };

    ipcRenderer.send('save-header-footer-settings', settings);
    closeHeaderFooterDialog();
}

// Handle logo browsing - ask main process to show open dialog
function browseForLogo(position) {
    ipcRenderer.send('browse-header-footer-logo', position);
}

// Handle logo saved confirmation
ipcRenderer.on('header-footer-logo-saved', (event, { position, path }) => {
    document.getElementById(`${position}-logo-preview`).textContent = path.split(/[\\/]/).pop();
});

// Clear logo
function clearLogo(position) {
    ipcRenderer.send('clear-header-footer-logo', position);
    document.getElementById(`${position}-logo-preview`).textContent = '';
}

// Handle logo cleared confirmation
ipcRenderer.on('header-footer-logo-cleared', (event, position) => {
    console.log(`${position} logo cleared`);
});

// Insert dynamic field into input
function insertDynamicField(field) {
    if (currentFieldTarget) {
        const input = document.getElementById(currentFieldTarget);
        const cursorPos = input.selectionStart;
        const textBefore = input.value.substring(0, cursorPos);
        const textAfter = input.value.substring(cursorPos);

        input.value = textBefore + field + textAfter;
        input.focus();
        input.setSelectionRange(cursorPos + field.length, cursorPos + field.length);
    }

    closeFieldPickerDialog();
}

// Event Listeners for Header/Footer Dialog

// Close buttons
document.getElementById('header-footer-close').addEventListener('click', closeHeaderFooterDialog);
document.getElementById('header-footer-cancel').addEventListener('click', closeHeaderFooterDialog);
document.getElementById('header-footer-save').addEventListener('click', saveHeaderFooterSettings);

// Enable/disable checkbox
document.getElementById('hf-enabled').addEventListener('change', toggleConfigContent);

// Field insert buttons
document.querySelectorAll('.field-insert-btn').forEach(btn => {
    btn.addEventListener('click', () => {
        const target = btn.getAttribute('data-target');
        openFieldPickerDialog(target);
    });
});

// Logo browse buttons
document.getElementById('header-logo-browse').addEventListener('click', () => browseForLogo('header'));
document.getElementById('footer-logo-browse').addEventListener('click', () => browseForLogo('footer'));

// Logo clear buttons
document.getElementById('header-logo-clear').addEventListener('click', () => clearLogo('header'));
document.getElementById('footer-logo-clear').addEventListener('click', () => clearLogo('footer'));

// Field picker dialog
document.getElementById('field-picker-close').addEventListener('click', closeFieldPickerDialog);
document.querySelectorAll('.field-option').forEach(btn => {
    btn.addEventListener('click', () => {
        const field = btn.getAttribute('data-field');
        insertDynamicField(field);
    });
});

// Export function to make openHeaderFooterDialog accessible globally
window.openHeaderFooterDialog = openHeaderFooterDialog;

// Listen for menu command to open dialog
ipcRenderer.on('open-header-footer-dialog', () => {
    openHeaderFooterDialog();
});
// Command Palette - initialized via CommandPalette class
// (see DOMContentLoaded handler for registration of commands)

// ============================================================================
// TABLE GENERATOR
// ============================================================================

function showTableGenerator() {
    window.modals.tableModal.open();

    // Generate initial preview
    generateTablePreview();

    // Focus on rows input
    setTimeout(() => {
        document.getElementById('table-rows').focus();
    }, 100);
}

function hideTableGenerator() {
    window.modals.tableModal.close();
}

function generateTablePreview() {
    const rows = parseInt(document.getElementById('table-rows').value) || 3;
    const cols = parseInt(document.getElementById('table-cols').value) || 3;
    const hasHeader = document.getElementById('table-has-header').checked;
    const alignment = document.getElementById('table-alignment').value;

    const table = generateMarkdownTable(rows, cols, hasHeader, alignment);
    document.getElementById('table-preview').textContent = table;
}

function generateMarkdownTable(rows, cols, hasHeader, alignment) {
    let table = '';

    // Generate alignment string
    let alignChar = '-';
    if (alignment === 'center') {
        alignChar = ':' + '-'.repeat(Math.max(8, 10)) + ':';
    } else if (alignment === 'right') {
        alignChar = '-'.repeat(Math.max(8, 10)) + ':';
    } else {
        alignChar = '-'.repeat(Math.max(8, 10));
    }

    // Generate header row
    if (hasHeader) {
        table += '| ';
        for (let c = 1; c <= cols; c++) {
            table += `Header ${c}`;
            if (c < cols) table += ' | ';
        }
        table += ' |\n';

        // Separator row
        table += '| ';
        for (let c = 1; c <= cols; c++) {
            table += alignChar;
            if (c < cols) table += ' | ';
        }
        table += ' |\n';

        // Data rows (excluding header)
        for (let r = 1; r < rows; r++) {
            table += '| ';
            for (let c = 1; c <= cols; c++) {
                table += `Cell ${r},${c}`;
                if (c < cols) table += ' | ';
            }
            table += ' |\n';
        }
    } else {
        // No header - all rows are data rows
        // First row (acts as separator position)
        table += '| ';
        for (let c = 1; c <= cols; c++) {
            table += `Cell 1,${c}`;
            if (c < cols) table += ' | ';
        }
        table += ' |\n';

        // Separator row
        table += '| ';
        for (let c = 1; c <= cols; c++) {
            table += alignChar;
            if (c < cols) table += ' | ';
        }
        table += ' |\n';

        // Remaining data rows
        for (let r = 2; r <= rows; r++) {
            table += '| ';
            for (let c = 1; c <= cols; c++) {
                table += `Cell ${r},${c}`;
                if (c < cols) table += ' | ';
            }
            table += ' |\n';
        }
    }

    return table;
}

function insertGeneratedTable() {
    const table = document.getElementById('table-preview').textContent;

    if (!table) {
        notifyUser('Generate a table preview first.', 'warning');
        return;
    }

    // Insert table using CodeMirror
    if (!tabManager) {
        notifyUser('No active editor found.', 'warning');
        return;
    }

    // Add newlines for spacing
    const tableWithSpacing = '\n' + table + '\n';
    tabManager.insertAtCursor(tableWithSpacing);

    // Trigger update
    if (tabManager) {
        tabManager.handleEditorInput(tabManager.activeTabId);
    }

    // Close dialog
    hideTableGenerator();
}

// Table Generator Event Listeners
document.getElementById('table-dialog-close').addEventListener('click', hideTableGenerator);
document.getElementById('table-cancel').addEventListener('click', hideTableGenerator);
document.getElementById('table-generate-preview').addEventListener('click', generateTablePreview);
document.getElementById('table-insert').addEventListener('click', insertGeneratedTable);

// Auto-update preview when inputs change
document.getElementById('table-rows').addEventListener('input', generateTablePreview);
document.getElementById('table-cols').addEventListener('input', generateTablePreview);
document.getElementById('table-has-header').addEventListener('change', generateTablePreview);
document.getElementById('table-alignment').addEventListener('change', generateTablePreview);

// Handle Enter key in inputs
document.getElementById('table-rows').addEventListener('keypress', (e) => {
    if (e.key === 'Enter') {
        e.preventDefault();
        insertGeneratedTable();
    }
});

document.getElementById('table-cols').addEventListener('keypress', (e) => {
    if (e.key === 'Enter') {
        e.preventDefault();
        insertGeneratedTable();
    }
});

// ============================================================================
// ASCII ART GENERATOR
// ============================================================================

let currentASCIIMode = 'text';

function showASCIIGenerator() {
    window.modals.asciiModal.open();

    // Initialize with text mode
    switchASCIIMode('text');

    // Generate initial preview
    setTimeout(() => {
        generateASCIIPreview();
    }, 100);
}

function hideASCIIGenerator() {
    window.modals.asciiModal.close();
}

function switchASCIIMode(mode) {
    currentASCIIMode = mode;

    // Update button states
    document.querySelectorAll('.ascii-mode-btn').forEach(btn => {
        btn.classList.remove('active');
    });

    // Hide all mode sections
    document.querySelectorAll('.ascii-mode-section').forEach(section => {
        section.classList.add('hidden');
    });

    // Show selected mode
    if (mode === 'text') {
        document.getElementById('ascii-mode-text').classList.add('active');
        document.getElementById('ascii-text-mode').classList.remove('hidden');
    } else if (mode === 'box') {
        document.getElementById('ascii-mode-box').classList.add('active');
        document.getElementById('ascii-box-mode').classList.remove('hidden');
    } else if (mode === 'templates') {
        document.getElementById('ascii-mode-templates').classList.add('active');
        document.getElementById('ascii-templates-mode').classList.remove('hidden');
    }

    // Generate preview
    generateASCIIPreview();
}

function generateASCIIPreview() {
    let result = '';

    if (currentASCIIMode === 'text') {
        const text = document.getElementById('ascii-text-input').value || 'Sample';
        const style = document.getElementById('ascii-font-style').value;
        result = textToASCII(text, style);
    } else if (currentASCIIMode === 'box') {
        const text = document.getElementById('ascii-box-text').value || 'Sample Text';
        const style = document.getElementById('ascii-box-style').value;
        const padding = parseInt(document.getElementById('ascii-box-padding').value) || 2;
        result = createASCIIBox(text, style, padding);
    } else if (currentASCIIMode === 'templates') {
        result = 'Select a template from the buttons above';
    }

    document.getElementById('ascii-preview').textContent = result;
}

// Simple ASCII art text generator
function textToASCII(text, style) {
    const fonts = {
        standard: {
            height: 5,
            chars: {
                'A': ['  _  ', ' / \\ ', '/___\\', '|   |', '|   |'],
                'B': ['____ ', '|   \\', '|___/', '|   \\', '|___/'],
                'C': [' ___ ', '/  _/', '|   \\', '|    ', '\\___/'],
                'D': ['____ ', '|   \\', '|    |', '|    |', '|___/'],
                'E': ['_____', '|    ', '|___ ', '|    ', '|____'],
                'F': ['_____', '|    ', '|___ ', '|    ', '|    '],
                'G': [' ___ ', '/   _', '|  ||', '|   |', '\\___/'],
                'H': ['|   |', '|   |', '|___|', '|   |', '|   |'],
                'I': ['_____', '  |  ', '  |  ', '  |  ', '_____'],
                'J': ['_____', '   | ', '   | ', '|  | ', '\\__/ '],
                'K': ['|   |', '|  / ', '|_/  ', '| \\  ', '|  \\ '],
                'L': ['|    ', '|    ', '|    ', '|    ', '|____'],
                'M': ['|   |', '|\\ /|', '| V |', '|   |', '|   |'],
                'N': ['|   |', '|\\  |', '| \\ |', '|  \\|', '|   |'],
                'O': [' ___ ', '/   \\', '|   |', '|   |', '\\___/'],
                'P': ['____ ', '|   \\', '|___/', '|    ', '|    '],
                'Q': [' ___ ', '/   \\', '|   |', '| |\\ ', '\\__\\|'],
                'R': ['____ ', '|   \\', '|___/', '| \\  ', '|  \\ '],
                'S': [' ___ ', '/  _/', '\\_  \\', '   \\ ', '\\___/'],
                'T': ['_____', '  |  ', '  |  ', '  |  ', '  |  '],
                'U': ['|   |', '|   |', '|   |', '|   |', '\\___/'],
                'V': ['|   |', '|   |', '|   |', ' \\ / ', '  V  '],
                'W': ['|   |', '|   |', '| W |', '|/ \\|', '|   |'],
                'X': ['|   |', ' \\ / ', '  X  ', ' / \\ ', '|   |'],
                'Y': ['|   |', ' \\ / ', '  Y  ', '  |  ', '  |  '],
                'Z': ['_____', '   / ', '  /  ', ' /   ', '/___ '],
                ' ': ['     ', '     ', '     ', '     ', '     '],
                '0': [' ___ ', '/   \\', '| | |', '|   |', '\\___/'],
                '1': ['  |  ', ' ||  ', '  |  ', '  |  ', ' _|_ '],
                '2': [' ___ ', '\\   /', ' __/ ', '/    ', '\\____'],
                '3': [' ___ ', '\\   /', ' __/ ', '   / ', '\\___/'],
                '4': ['|   |', '|   |', '|___|', '    |', '    |'],
                '5': [' ___ ', '|    ', '|___ ', '   / ', '\\___/'],
                '6': [' ___ ', '/    ', '|___ ', '|   |', '\\___/'],
                '7': ['_____', '   / ', '  /  ', ' /   ', '/    '],
                '8': [' ___ ', '|   |', ' ___ ', '|   |', '\\___/'],
                '9': [' ___ ', '|   |', '\\___|', '    |', '\\___/']
            }
        },
        banner: {
            height: 7,
            chars: {
                'A': ['   ###   ', '  ## ##  ', ' ##   ## ', ' ##   ## ', ' ####### ', ' ##   ## ', ' ##   ## '],
                'B': [' ######  ', ' ##   ## ', ' ##   ## ', ' ######  ', ' ##   ## ', ' ##   ## ', ' ######  '],
                'C': ['  #####  ', ' ##   ## ', ' ##      ', ' ##      ', ' ##      ', ' ##   ## ', '  #####  '],
                'D': [' ######  ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ######  '],
                'E': [' ####### ', ' ##      ', ' ##      ', ' #####   ', ' ##      ', ' ##      ', ' ####### '],
                'F': [' ####### ', ' ##      ', ' ##      ', ' #####   ', ' ##      ', ' ##      ', ' ##      '],
                'G': ['  #####  ', ' ##   ## ', ' ##      ', ' ##  ### ', ' ##   ## ', ' ##   ## ', '  #####  '],
                'H': [' ##   ## ', ' ##   ## ', ' ##   ## ', ' ####### ', ' ##   ## ', ' ##   ## ', ' ##   ## '],
                'I': [' ####### ', '   ###   ', '   ###   ', '   ###   ', '   ###   ', '   ###   ', ' ####### '],
                'J': [' ####### ', '     ##  ', '     ##  ', '     ##  ', ' ##  ##  ', ' ##  ##  ', '  ####   '],
                'K': [' ##   ## ', ' ##  ##  ', ' ## ##   ', ' ####    ', ' ## ##   ', ' ##  ##  ', ' ##   ## '],
                'L': [' ##      ', ' ##      ', ' ##      ', ' ##      ', ' ##      ', ' ##      ', ' ####### '],
                'M': [' ##   ## ', ' ### ### ', ' ####### ', ' ## # ## ', ' ##   ## ', ' ##   ## ', ' ##   ## '],
                'N': [' ##   ## ', ' ###  ## ', ' #### ## ', ' ## #### ', ' ##  ### ', ' ##   ## ', ' ##   ## '],
                'O': ['  #####  ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', '  #####  '],
                'P': [' ######  ', ' ##   ## ', ' ##   ## ', ' ######  ', ' ##      ', ' ##      ', ' ##      '],
                'Q': ['  #####  ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ## # ## ', ' ##  ##  ', '  ### ## '],
                'R': [' ######  ', ' ##   ## ', ' ##   ## ', ' ######  ', ' ## ##   ', ' ##  ##  ', ' ##   ## '],
                'S': ['  #####  ', ' ##   ## ', ' ##      ', '  #####  ', '      ## ', ' ##   ## ', '  #####  '],
                'T': [' ####### ', '   ###   ', '   ###   ', '   ###   ', '   ###   ', '   ###   ', '   ###   '],
                'U': [' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', '  #####  '],
                'V': [' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', ' ##   ## ', '  ## ##  ', '   ###   '],
                'W': [' ##   ## ', ' ##   ## ', ' ##   ## ', ' ## # ## ', ' ####### ', ' ### ### ', ' ##   ## '],
                'X': [' ##   ## ', '  ## ##  ', '   ###   ', '    #    ', '   ###   ', '  ## ##  ', ' ##   ## '],
                'Y': [' ##   ## ', '  ## ##  ', '   ###   ', '    #    ', '    #    ', '    #    ', '    #    '],
                'Z': [' ####### ', '     ##  ', '    ##   ', '   ##    ', '  ##     ', ' ##      ', ' ####### '],
                ' ': ['         ', '         ', '         ', '         ', '         ', '         ', '         '],
                '0': ['  #####  ', ' ##   ## ', ' ##  ### ', ' ## #### ', ' ###  ## ', ' ##   ## ', '  #####  '],
                '1': ['    ##   ', '   ###   ', '    ##   ', '    ##   ', '    ##   ', '    ##   ', ' ####### '],
                '2': ['  #####  ', ' ##   ## ', '      ## ', '    ##   ', '  ##     ', ' ##      ', ' ####### '],
                '3': ['  #####  ', ' ##   ## ', '      ## ', '    ###  ', '      ## ', ' ##   ## ', '  #####  '],
                '4': ['    ###  ', '   ####  ', '  ## ##  ', ' ##  ##  ', ' ####### ', '     ##  ', '     ##  '],
                '5': [' ####### ', ' ##      ', ' ######  ', '      ## ', '      ## ', ' ##   ## ', '  #####  '],
                '6': ['  #####  ', ' ##   ## ', ' ##      ', ' ######  ', ' ##   ## ', ' ##   ## ', '  #####  '],
                '7': [' ####### ', '      ## ', '     ##  ', '    ##   ', '   ##    ', '  ##     ', ' ##      '],
                '8': ['  #####  ', ' ##   ## ', ' ##   ## ', '  #####  ', ' ##   ## ', ' ##   ## ', '  #####  '],
                '9': ['  #####  ', ' ##   ## ', ' ##   ## ', '  ###### ', '      ## ', ' ##   ## ', '  #####  ']
            }
        },
        block: {
            height: 6,
            chars: {
                'A': ['█████╗ ', '██╔══██╗', '███████║', '██╔══██║', '██║  ██║', '╚═╝  ╚═╝'],
                'B': ['██████╗ ', '██╔══██╗', '██████╔╝', '██╔══██╗', '██████╔╝', '╚═════╝ '],
                'C': ['██████╗', '██╔════╝', '██║     ', '██║     ', '╚██████╗', ' ╚═════╝'],
                'D': ['██████╗ ', '██╔══██╗', '██║  ██║', '██║  ██║', '██████╔╝', '╚═════╝ '],
                'E': ['███████╗', '██╔════╝', '█████╗  ', '██╔══╝  ', '███████╗', '╚══════╝'],
                'F': ['███████╗', '██╔════╝', '█████╗  ', '██╔══╝  ', '██║     ', '╚═╝     '],
                'G': ['██████╗ ', '██╔════╝', '██║  ███╗', '██║   ██║', '╚██████╔╝', ' ╚═════╝ '],
                'H': ['██╗  ██╗', '██║  ██║', '███████║', '██╔══██║', '██║  ██║', '╚═╝  ╚═╝'],
                'I': ['██╗', '██║', '██║', '██║', '██║', '╚═╝'],
                ' ': ['    ', '    ', '    ', '    ', '    ', '    ']
            }
        },
        bubble: {
            height: 5,
            chars: {
                'A': ['  Ⓐ  ', ' ⒜ ⒜ ', '⒜⒜⒜⒜⒜', '⒜   ⒜', '⒜   ⒜'],
                'B': ['ⒷⒷⒷⒷ ', 'Ⓑ   Ⓑ', 'ⒷⒷⒷⒷ ', 'Ⓑ   Ⓑ', 'ⒷⒷⒷⒷ '],
                'C': [' ⒸⒸⒸ ', 'Ⓒ    ', 'Ⓒ    ', 'Ⓒ    ', ' ⒸⒸⒸ '],
                ' ': ['     ', '     ', '     ', '     ', '     ']
            }
        },
        digital: {
            height: 7,
            chars: {
                'A': [' ▄▀▀▀▄ ', '▐    ▌', '▐▄▄▄▄▌', '▐    ▌', '▐    ▌', '▐    ▌', '       '],
                'B': ['▐▀▀▀▄ ', '▐▄▄▄▀ ', '▐▄▄▄▄ ', '▐    ▌', '▐▄▄▄▀ ', '       ', '       '],
                'C': [' ▄▀▀▀▄', '▐     ', '▐     ', '▐     ', ' ▀▄▄▄▀', '       ', '       '],
                ' ': ['       ', '       ', '       ', '       ', '       ', '       ', '       ']
            }
        }
    };

    // Use selected font or fallback to standard
    const font = fonts[style] || fonts.standard;
    const lines = [];
    const upperText = text.toUpperCase();

    for (let i = 0; i < font.height; i++) {
        lines[i] = '';
    }

    for (const char of upperText) {
        const charLines = font.chars[char] || font.chars[' '];
        if (charLines) {
            for (let i = 0; i < font.height; i++) {
                lines[i] += (charLines[i] || ' '.repeat(font.chars[' '][i].length));
            }
        }
    }

    return lines.join('\n');
}

// Create ASCII box/frame
function createASCIIBox(text, style, padding) {
    const styles = {
        single: { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│' },
        double: { tl: '╔', tr: '╗', bl: '╚', br: '╝', h: '═', v: '║' },
        rounded: { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│' },
        bold: { tl: '┏', tr: '┓', bl: '┗', br: '┛', h: '━', v: '┃' },
        ascii: { tl: '+', tr: '+', bl: '+', br: '+', h: '-', v: '|' }
    };

    const chars = styles[style] || styles.single;
    const lines = text.split('\n');
    const maxLength = Math.max(...lines.map(l => l.length));
    const width = maxLength + (padding * 2);

    let result = '';

    // Top border
    result += chars.tl + chars.h.repeat(width) + chars.tr + '\n';

    // Padding rows above
    for (let i = 0; i < padding - 1; i++) {
        result += chars.v + ' '.repeat(width) + chars.v + '\n';
    }

    // Content lines
    for (const line of lines) {
        const paddedLine = line.padEnd(maxLength, ' ');
        result += chars.v + ' '.repeat(padding) + paddedLine + ' '.repeat(padding) + chars.v + '\n';
    }

    // Padding rows below
    for (let i = 0; i < padding - 1; i++) {
        result += chars.v + ' '.repeat(width) + chars.v + '\n';
    }

    // Bottom border
    result += chars.bl + chars.h.repeat(width) + chars.br;

    return result;
}

// ASCII Art Templates
function getASCIITemplate(templateName) {
    const templates = {
        'arrow-right': `
    ┌────────┐
    │        │
────►  NEXT  │
    │        │
    └────────┘`,
        'arrow-down': `
    │
    │
    ▼
  ┌──────┐
  │ NEXT │
  └──────┘`,
        'check': `
  ✓ Task completed
  ✓ All tests passed
  ✓ Ready to deploy
  ✓ Documentation updated`,
        'divider': `
═══════════════════════════════════════════════════════════
`,
        'header': `
╔═══════════════════════════════════════════════════╗
║              SECTION HEADER                       ║
╚═══════════════════════════════════════════════════╝`,
        'flowchart': `
┌─────────────┐
│    START    │
└──────┬──────┘
       │
       ▼
┌─────────────┐
│   PROCESS   │
└──────┬──────┘
       │
   ┌───┴───┐
   │ Check │
   └───┬───┘
       │
   ┌───▼──┬──────┐
   │ Yes  │  No  │
   ▼      ▼      │
┌────┐ ┌────┐   │
│ A  │ │ B  │   │
└─┬──┘ └─┬──┘   │
  │      │       │
  └──┬───┘       │
     │◄──────────┘
     ▼
┌─────────────┐
│     END     │
└─────────────┘`,
        'decision': `
       ┌─────────┐
       │ Check?  │
       └────┬────┘
            │
      ┌─────┴─────┐
      │           │
   Yes│           │No
      ▼           ▼
 ┌────────┐  ┌────────┐
 │  True  │  │  False │
 └────────┘  └────────┘`,
        'sequence': `
 User      System     Database
   │           │           │
   │  Request  │           │
   ├──────────►│           │
   │           │  Query    │
   │           ├──────────►│
   │           │           │
   │           │  Result   │
   │           │◄──────────┤
   │  Response │           │
   │◄──────────┤           │
   │           │           │`,
        'table-simple': `
┌──────────┬──────────┬──────────┐
│ Header 1 │ Header 2 │ Header 3 │
├──────────┼──────────┼──────────┤
│  Data 1  │  Data 2  │  Data 3  │
├──────────┼──────────┼──────────┤
│  Data 4  │  Data 5  │  Data 6  │
└──────────┴──────────┴──────────┘`,
        'timeline': `
  2020        2021        2022        2023
    │           │           │           │
    ●───────────●───────────●───────────●
    │           │           │           │
  Start    Milestone    Release    Current`,
        'network': `
            ┌──────────┐
            │  Server  │
            └────┬─────┘
                 │
       ┌─────────┼─────────┐
       │         │         │
   ┌───▼───┐ ┌──▼────┐ ┌──▼────┐
   │Client1│ │Client2│ │Client3│
   └───────┘ └───────┘ └───────┘`,
        'hierarchy': `
        ┌─────────┐
        │  Root   │
        └────┬────┘
             │
    ┌────────┴────────┐
    │                 │
┌───▼───┐         ┌───▼───┐
│Child 1│         │Child 2│
└───┬───┘         └───┬───┘
    │                 │
┌───▼───┐         ┌───▼───┐
│Grand 1│         │Grand 2│
└───────┘         └───────┘`,
        'process-flow': `
┌─────────┐     ┌─────────┐     ┌─────────┐
│  Input  │────►│Process 1│────►│  Output │
└─────────┘     └────┬────┘     └─────────┘
                     │
                ┌────▼────┐
                │Process 2│
                └─────────┘`,
        'note-box': `
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃  NOTE:                         ┃
┃  This is an important note     ┃
┃  that requires attention!      ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛`,
        'warning-box': `
╔════════════════════════════════════╗
║  ⚠ WARNING                         ║
║  Proceed with caution!             ║
╚════════════════════════════════════╝`,
        'info-box': `
╭────────────────────────────────────╮
│  ℹ  Information                    │
│  Additional context here           │
╰────────────────────────────────────╯`,
        'separator-fancy': `
╭──────────────────────────────────────────────────────╮
│                                                      │
╰──────────────────────────────────────────────────────╯`,
        'brackets': `
【  Important Text  】`,
        'banner-stars': `
************************************************************************
*                       IMPORTANT BANNER                              *
************************************************************************`,
        'progress-bar': `
Progress:  [████████████░░░░░░░░] 60%
           0%                    100%`
    };

    return templates[templateName] || '';
}

function loadASCIITemplate(templateName) {
    const template = getASCIITemplate(templateName);
    document.getElementById('ascii-preview').textContent = template;
}

function insertASCIIArt() {
    const asciiArt = document.getElementById('ascii-preview').textContent;

    if (!asciiArt || asciiArt === 'Select a template from the buttons above') {
        notifyUser('Generate ASCII art first.', 'warning');
        return;
    }

    // Insert using CodeMirror
    if (!tabManager) {
        notifyUser('No active editor found.', 'warning');
        return;
    }

    // Insert in code block for proper rendering
    const codeBlock = '\n```\n' + asciiArt + '\n```\n';
    tabManager.insertAtCursor(codeBlock);

    // Trigger update
    if (tabManager) {
        tabManager.handleEditorInput(tabManager.activeTabId);
    }

    // Close dialog
    hideASCIIGenerator();
}

// ASCII Art Event Listeners
document.getElementById('ascii-dialog-close').addEventListener('click', hideASCIIGenerator);
document.getElementById('ascii-cancel').addEventListener('click', hideASCIIGenerator);
document.getElementById('ascii-generate').addEventListener('click', generateASCIIPreview);
document.getElementById('ascii-insert').addEventListener('click', insertASCIIArt);

// Mode switching
document.getElementById('ascii-mode-text').addEventListener('click', () => switchASCIIMode('text'));
document.getElementById('ascii-mode-box').addEventListener('click', () => switchASCIIMode('box'));
document.getElementById('ascii-mode-templates').addEventListener('click', () => switchASCIIMode('templates'));

// Auto-update preview for text mode
document.getElementById('ascii-text-input').addEventListener('input', generateASCIIPreview);
document.getElementById('ascii-font-style').addEventListener('change', generateASCIIPreview);

// Auto-update preview for box mode
document.getElementById('ascii-box-text').addEventListener('input', generateASCIIPreview);
document.getElementById('ascii-box-style').addEventListener('change', generateASCIIPreview);
document.getElementById('ascii-box-padding').addEventListener('input', generateASCIIPreview);

// Template buttons
document.querySelectorAll('.ascii-template-btn').forEach(btn => {
    btn.addEventListener('click', function() {
        const template = this.getAttribute('data-template');
        loadASCIITemplate(template);
    });
});

// IPC listener for menu
ipcRenderer.on('show-ascii-generator', () => {
    showASCIIGenerator();
});

// ============================================================================
// PANE RESIZING
// ============================================================================

let isResizing = false;
let currentResizer = null;

document.addEventListener('mousedown', (e) => {
    if (e.target.classList.contains('pane-resizer')) {
        isResizing = true;
        currentResizer = e.target;
        document.body.style.cursor = 'col-resize';
        document.body.style.userSelect = 'none';
    }
});

document.addEventListener('mousemove', (e) => {
    if (!isResizing) return;

    const container = currentResizer.parentElement;
    const editorPane = currentResizer.previousElementSibling;
    const previewPane = currentResizer.nextElementSibling;

    const containerRect = container.getBoundingClientRect();
    const containerWidth = containerRect.width;
    const mouseX = e.clientX - containerRect.left;

    // Calculate percentages (minimum 20%, maximum 80% for each pane)
    let editorPercentage = (mouseX / containerWidth) * 100;
    editorPercentage = Math.max(20, Math.min(80, editorPercentage));

    const previewPercentage = 100 - editorPercentage;

    editorPane.style.flex = `0 0 ${editorPercentage}%`;
    previewPane.style.flex = `0 0 ${previewPercentage}%`;
});

document.addEventListener('mouseup', () => {
    if (isResizing) {
        isResizing = false;
        currentResizer = null;
        document.body.style.cursor = '';
        document.body.style.userSelect = '';
    }
});


// ============================================
// Insert Content from Generator Windows
// ============================================
ipcRenderer.on('insert-content', (event, content) => {
    if (tabManager) {
        tabManager.insertAtCursor(content);

        const activeTabId = tabManager.activeTabId;
        const tab = tabManager.tabs.get(activeTabId);
        if (tab) {
            tab.isDirty = true;
            tabManager.updatePreview(activeTabId);
            tabManager.updateTabBar();
        }
    }
});

// ============================================
// PDF VIEWER FUNCTIONALITY
// ============================================

// Legacy PDF viewer globals - kept for PDF editor dialogs that still use them
let pdfDoc = null;
let pdfCurrentPage = 1;
let pdfZoomLevel = 1.0;
let pdfRotation = 0;
let pdfFilePath = null;
let isPdfViewerActive = false;

// Initialize PDF.js
// Lazy-load pdfjs-dist only when PDF viewer is needed
let _pdfjsLib;
function getPdfjsLib() {
    if (!_pdfjsLib) {
        _pdfjsLib = require('pdfjs-dist');
        _pdfjsLib.GlobalWorkerOptions.workerSrc = require.resolve('pdfjs-dist/build/pdf.worker.mjs');
    }
    return _pdfjsLib;
}

// Open PDF file - now creates a tab instead of replacing the entire view
async function openPdfFile(filePath) {
    // Check if this PDF is already open in a tab
    for (const [tabId, tab] of tabManager.tabs) {
        if (tab.type === 'pdf' && tab.filePath === filePath) {
            // Just switch to the existing tab
            tabManager.switchToTab(tabId);
            return;
        }
    }

    // Create a new PDF tab
    tabManager.createPdfTab(filePath);
}

// Render PDF page
async function renderPdfPage(pageNum) {
    if (!pdfDoc) return;

    try {
        const page = await pdfDoc.getPage(pageNum);
        const canvas = document.getElementById('pdf-canvas');
        const ctx = canvas.getContext('2d');

        // Calculate viewport with zoom and rotation
        const viewport = page.getViewport({ scale: pdfZoomLevel, rotation: pdfRotation });

        canvas.width = viewport.width;
        canvas.height = viewport.height;

        const renderContext = {
            canvasContext: ctx,
            viewport: viewport
        };

        await page.render(renderContext).promise;

        // Update page input
        document.getElementById('pdf-page-input').value = pageNum;
    } catch (error) {
        console.error('Error rendering PDF page:', error);
    }
}

// PDF navigation handlers
document.getElementById('pdf-prev-page')?.addEventListener('click', async () => {
    if (pdfCurrentPage > 1) {
        pdfCurrentPage--;
        await renderPdfPage(pdfCurrentPage);
    }
});

document.getElementById('pdf-next-page')?.addEventListener('click', async () => {
    if (pdfDoc && pdfCurrentPage < pdfDoc.numPages) {
        pdfCurrentPage++;
        await renderPdfPage(pdfCurrentPage);
    }
});

document.getElementById('pdf-page-input')?.addEventListener('change', async (e) => {
    const pageNum = parseInt(e.target.value);
    if (pdfDoc && pageNum >= 1 && pageNum <= pdfDoc.numPages) {
        pdfCurrentPage = pageNum;
        await renderPdfPage(pdfCurrentPage);
    }
});

// PDF zoom handlers
document.getElementById('pdf-zoom-out')?.addEventListener('click', async () => {
    if (pdfZoomLevel > 0.25) {
        pdfZoomLevel -= 0.25;
        document.getElementById('pdf-zoom-level').textContent = Math.round(pdfZoomLevel * 100) + '%';
        await renderPdfPage(pdfCurrentPage);
    }
});

document.getElementById('pdf-zoom-in')?.addEventListener('click', async () => {
    if (pdfZoomLevel < 4.0) {
        pdfZoomLevel += 0.25;
        document.getElementById('pdf-zoom-level').textContent = Math.round(pdfZoomLevel * 100) + '%';
        await renderPdfPage(pdfCurrentPage);
    }
});

document.getElementById('pdf-fit-width')?.addEventListener('click', async () => {
    if (!pdfDoc) return;
    const page = await pdfDoc.getPage(pdfCurrentPage);
    const viewport = page.getViewport({ scale: 1, rotation: pdfRotation });
    const containerWidth = document.getElementById('pdf-viewer').clientWidth - 40;
    pdfZoomLevel = containerWidth / viewport.width;
    document.getElementById('pdf-zoom-level').textContent = Math.round(pdfZoomLevel * 100) + '%';
    await renderPdfPage(pdfCurrentPage);
});

document.getElementById('pdf-fit-page')?.addEventListener('click', async () => {
    if (!pdfDoc) return;
    const page = await pdfDoc.getPage(pdfCurrentPage);
    const viewport = page.getViewport({ scale: 1, rotation: pdfRotation });
    const container = document.getElementById('pdf-viewer');
    const containerWidth = container.clientWidth - 40;
    const containerHeight = container.clientHeight - 40;
    const scaleX = containerWidth / viewport.width;
    const scaleY = containerHeight / viewport.height;
    pdfZoomLevel = Math.min(scaleX, scaleY);
    document.getElementById('pdf-zoom-level').textContent = Math.round(pdfZoomLevel * 100) + '%';
    await renderPdfPage(pdfCurrentPage);
});

// PDF rotation handlers
document.getElementById('pdf-rotate-left')?.addEventListener('click', async () => {
    pdfRotation = (pdfRotation - 90 + 360) % 360;
    await renderPdfPage(pdfCurrentPage);
});

document.getElementById('pdf-rotate-right')?.addEventListener('click', async () => {
    pdfRotation = (pdfRotation + 90) % 360;
    await renderPdfPage(pdfCurrentPage);
});

// Close PDF viewer
document.getElementById('pdf-close')?.addEventListener('click', () => {
    closePdfViewer();
});

async function closePdfViewer() {
    // Legacy PDF viewer close - for backward compatibility with PDF editor dialogs
    if (pdfDoc) {
        try {
            await pdfDoc.destroy();
        } catch (e) {
            console.warn('Error destroying PDF:', e);
        }
    }

    pdfDoc = null;
    pdfFilePath = null;
    isPdfViewerActive = false;

    // If we're using the new tab-based system, close the current PDF tab
    if (tabManager) {
        const activeTab = tabManager.tabs.get(tabManager.activeTabId);
        if (activeTab && activeTab.type === 'pdf') {
            tabManager.closeTab(tabManager.activeTabId);
            return;
        }
    }

    // Legacy: Hide PDF viewer container
    document.getElementById('pdf-viewer-container')?.classList.add('hidden');

    // Show markdown tabs, tab bar, and toolbar
    document.getElementById('tab-bar')?.classList.remove('hidden');
    document.querySelectorAll('.tab-content').forEach(tc => tc.classList.remove('hidden'));
    document.querySelector('.toolbar')?.classList.remove('hidden');

    // Activate the correct markdown tab
    if (tabManager) {
        const activeTab = document.querySelector(`.tab-content[data-tab-id="${tabManager.activeTabId}"]`);
        if (activeTab) activeTab.classList.add('active');
        tabManager.updatePreview(tabManager.activeTabId);
    }

    document.getElementById('status-text').textContent = 'Ready';
}

// Handle PDF file open from main process
ipcRenderer.on('open-pdf-file', (event, filePath) => {
    openPdfFile(filePath);
});

// ============================================
// PDF EDITOR TOOLBAR BUTTONS
// ============================================

// Helper function to trigger PDF editor dialog
function openPdfEditorDialog(operation) {
    // Use the opened PDF file if available, otherwise prompt
    if (pdfFilePath) {
        ipcRenderer.send('show-pdf-editor-from-toolbar', { operation, filePath: pdfFilePath });
    } else {
        ipcRenderer.send('show-pdf-editor-from-toolbar', { operation, filePath: null });
    }
}

// PDF Editor toolbar button handlers
document.getElementById('pdf-tb-merge')?.addEventListener('click', () => {
    openPdfEditorDialog('merge');
});

document.getElementById('pdf-tb-split')?.addEventListener('click', () => {
    openPdfEditorDialog('split');
});

document.getElementById('pdf-tb-compress')?.addEventListener('click', () => {
    openPdfEditorDialog('compress');
});

document.getElementById('pdf-tb-rotate')?.addEventListener('click', () => {
    openPdfEditorDialog('rotate');
});

document.getElementById('pdf-tb-delete')?.addEventListener('click', () => {
    openPdfEditorDialog('delete');
});

document.getElementById('pdf-tb-reorder')?.addEventListener('click', () => {
    openPdfEditorDialog('reorder');
});

document.getElementById('pdf-tb-watermark')?.addEventListener('click', () => {
    openPdfEditorDialog('watermark');
});

document.getElementById('pdf-tb-encrypt')?.addEventListener('click', () => {
    openPdfEditorDialog('encrypt');
});

document.getElementById('pdf-tb-decrypt')?.addEventListener('click', () => {
    openPdfEditorDialog('decrypt');
});

// ============================================
// DYNAMIC PANE RESIZER
// ============================================

function initPaneResizer(tabId) {
    const resizer = document.getElementById(`pane-resizer-${tabId}`);
    const editorPane = document.getElementById(`editor-pane-${tabId}`);
    const previewPane = document.getElementById(`preview-pane-${tabId}`);
    const tabContent = document.getElementById(`tab-content-${tabId}`);

    if (!resizer || !editorPane || !previewPane) return;

    let isResizing = false;
    let startX = 0;
    let startEditorWidth = 0;

    resizer.addEventListener('mousedown', (e) => {
        isResizing = true;
        startX = e.clientX;
        startEditorWidth = editorPane.offsetWidth;
        document.body.style.cursor = 'col-resize';
        document.body.style.userSelect = 'none';
        e.preventDefault();
    });

    document.addEventListener('mousemove', (e) => {
        if (!isResizing) return;

        const containerWidth = tabContent.offsetWidth;
        const deltaX = e.clientX - startX;
        let newEditorWidth = startEditorWidth + deltaX;

        // Minimum widths
        const minWidth = 150;
        const maxWidth = containerWidth - minWidth - 6; // 6px for resizer

        newEditorWidth = Math.max(minWidth, Math.min(maxWidth, newEditorWidth));

        const editorPercent = (newEditorWidth / containerWidth) * 100;
        const previewPercent = 100 - editorPercent - 1; // 1% for resizer

        editorPane.style.flex = `0 0 ${editorPercent}%`;
        previewPane.style.flex = `0 0 ${previewPercent}%`;
    });

    document.addEventListener('mouseup', () => {
        if (isResizing) {
            isResizing = false;
            document.body.style.cursor = '';
            document.body.style.userSelect = '';
        }
    });
}

// Initialize resizer for first tab
document.addEventListener('DOMContentLoaded', () => {
    initPaneResizer(1);
});

// ============================================
// IMAGE/AUDIO/VIDEO CONVERTER HANDLERS
// These require external tools (ImageMagick, FFmpeg)
// ============================================

ipcRenderer.on('show-image-tool', (event, tool) => {
    notifyUser(
        `Image ${tool} requires ImageMagick. Install it from imagemagick.org to enable this tool.`,
        'info',
        { duration: 5000 }
    );
});

ipcRenderer.on('show-audio-tool', (event, tool) => {
    notifyUser(
        `Audio ${tool} requires FFmpeg. Install it from ffmpeg.org to enable this tool.`,
        'info',
        { duration: 5000 }
    );
});

ipcRenderer.on('show-video-tool', (event, tool) => {
    notifyUser(
        `Video ${tool} requires FFmpeg. Install it from ffmpeg.org to enable this tool.`,
        'info',
        { duration: 5000 }
    );
});

// ============================================
// PDF EDITOR VISUAL PAGE SIDEBAR HANDLERS
// ============================================
let pdfDocInstance = null;
let pdfPreviewState = { pages: [], filePath: '' };

function onPDFFileSelected(inputId, filePath) {
    const eligibleInputs = ['rotate-input-path', 'delete-input-path', 'reorder-input-path'];
    if (!eligibleInputs.includes(inputId)) {
        return;
    }

    const sidebar = document.getElementById('pdf-thumbnail-sidebar');
    if (sidebar) {
        sidebar.classList.remove('hidden');
    }
    const body = document.querySelector('.pdf-editor-body');
    if (body) {
        body.classList.add('side-by-side');
    }

    loadPDFThumbnails(filePath);
}

async function loadPDFThumbnails(filePath) {
    const grid = document.getElementById('pdf-thumbnail-grid');
    if (!grid) return;

    // Reset previous inputs
    const rotateInput = document.getElementById('rotate-pages');
    if (rotateInput) rotateInput.value = '';
    const deleteInput = document.getElementById('delete-pages');
    if (deleteInput) deleteInput.value = '';
    const reorderInput = document.getElementById('reorder-pages');
    if (reorderInput) reorderInput.value = '';

    grid.innerHTML = '<div class="loading-thumbnails">Loading page thumbnails...</div>';

    try {
        const pdfjs = getPdfjsLib();
        const loadingTask = pdfjs.getDocument(filePath);
        pdfDocInstance = await loadingTask.promise;

        pdfPreviewState.filePath = filePath;
        pdfPreviewState.pages = [];

        for (let i = 1; i <= pdfDocInstance.numPages; i++) {
            pdfPreviewState.pages.push({
                originalPageNum: i,
                rotation: 0,
                isDeleted: false
            });
        }

        renderThumbnailGrid();
    } catch (err) {
        console.error('Error loading PDF thumbnails:', err);
        grid.innerHTML = '<div class="thumbnail-error">Failed to load PDF thumbnails.</div>';
    }
}

function renderThumbnailGrid() {
    const grid = document.getElementById('pdf-thumbnail-grid');
    if (!grid || !pdfDocInstance) return;

    grid.innerHTML = '';

    pdfPreviewState.pages.forEach((pageInfo, index) => {
        const card = document.createElement('div');
        card.className = 'pdf-thumbnail-card';
        if (pageInfo.isDeleted) {
            card.classList.add('marked-delete');
        }

        const heading = document.createElement('div');
        heading.className = 'pdf-thumbnail-header';
        heading.innerHTML = `<span class="badge">Page ${pageInfo.originalPageNum}</span>`;

        const canvasContainer = document.createElement('div');
        canvasContainer.className = 'canvas-container';

        const canvas = document.createElement('canvas');
        canvas.className = 'pdf-thumbnail-canvas';
        if (pageInfo.rotation > 0) {
            canvas.classList.add('rot' + pageInfo.rotation);
        }
        canvasContainer.appendChild(canvas);

        // Render thumbnail canvas
        renderThumbnail(pdfDocInstance, pageInfo.originalPageNum, canvas, pageInfo.rotation);

        const controlsRow = document.createElement('div');
        controlsRow.className = 'pdf-thumbnail-controls';

        // Rotate Button
        const rotateBtn = document.createElement('button');
        rotateBtn.type = 'button';
        rotateBtn.className = 'btn-rotate-thumbnail';
        rotateBtn.innerHTML = '↻ Rotate 90°';
        rotateBtn.addEventListener('click', () => {
            pageInfo.rotation = (pageInfo.rotation + 90) % 360;
            canvas.className = 'pdf-thumbnail-canvas';
            if (pageInfo.rotation > 0) {
                canvas.classList.add('rot' + pageInfo.rotation);
            }
            renderThumbnail(pdfDocInstance, pageInfo.originalPageNum, canvas, pageInfo.rotation);
            syncRotateInput();
        });

        // Delete Checkbox
        const deleteLabel = document.createElement('label');
        deleteLabel.className = 'delete-thumbnail-checkbox';

        const deleteChk = document.createElement('input');
        deleteChk.type = 'checkbox';
        deleteChk.checked = pageInfo.isDeleted;
        deleteChk.addEventListener('change', (e) => {
            pageInfo.isDeleted = e.target.checked;
            card.classList.toggle('marked-delete', pageInfo.isDeleted);
            syncDeleteInput();
        });
        deleteLabel.appendChild(deleteChk);
        deleteLabel.appendChild(document.createTextNode(' Delete'));

        // Reorder buttons
        const reorderDiv = document.createElement('div');
        reorderDiv.className = 'pdf-thumbnail-reorder';

        const leftBtn = document.createElement('button');
        leftBtn.type = 'button';
        leftBtn.className = 'btn-reorder-left';
        leftBtn.innerHTML = '◀';
        leftBtn.disabled = (index === 0);
        leftBtn.addEventListener('click', () => {
            const temp = pdfPreviewState.pages[index];
            pdfPreviewState.pages[index] = pdfPreviewState.pages[index - 1];
            pdfPreviewState.pages[index - 1] = temp;
            renderThumbnailGrid();
            syncReorderInput();
        });

        const rightBtn = document.createElement('button');
        rightBtn.type = 'button';
        rightBtn.className = 'btn-reorder-right';
        rightBtn.innerHTML = '▶';
        rightBtn.disabled = (index === pdfPreviewState.pages.length - 1);
        rightBtn.addEventListener('click', () => {
            const temp = pdfPreviewState.pages[index];
            pdfPreviewState.pages[index] = pdfPreviewState.pages[index + 1];
            pdfPreviewState.pages[index + 1] = temp;
            renderThumbnailGrid();
            syncReorderInput();
        });

        reorderDiv.appendChild(leftBtn);
        reorderDiv.appendChild(rightBtn);

        controlsRow.appendChild(rotateBtn);
        controlsRow.appendChild(deleteLabel);
        controlsRow.appendChild(reorderDiv);

        card.appendChild(heading);
        card.appendChild(canvasContainer);
        card.appendChild(controlsRow);

        grid.appendChild(card);
    });
}

async function renderThumbnail(pdfDoc, originalPageNum, canvasElement, rotation) {
    try {
        const page = await pdfDoc.getPage(originalPageNum);
        const ctx = canvasElement.getContext('2d');

        // Render at a fixed width of 100px
        const unscaledViewport = page.getViewport({ scale: 1, rotation: 0 });
        const scale = 100 / unscaledViewport.width;
        const viewport = page.getViewport({ scale: scale, rotation: 0 });

        canvasElement.width = viewport.width;
        canvasElement.height = viewport.height;

        await page.render({
            canvasContext: ctx,
            viewport: viewport
        }).promise;
    } catch (err) {
        console.error('Error rendering page canvas:', err);
    }
}

function syncRotateInput() {
    const rotatedPages = pdfPreviewState.pages
        .filter(p => p.rotation > 0)
        .map(p => p.originalPageNum);

    const rotateInput = document.getElementById('rotate-pages');
    if (rotateInput) {
        rotateInput.value = rotatedPages.join(', ');
    }
}

function syncDeleteInput() {
    const deletedPages = pdfPreviewState.pages
        .filter(p => p.isDeleted)
        .map(p => p.originalPageNum);

    const deleteInput = document.getElementById('delete-pages');
    if (deleteInput) {
        deleteInput.value = deletedPages.join(', ');
    }
}

function syncReorderInput() {
    const order = pdfPreviewState.pages.map(p => p.originalPageNum);
    const reorderInput = document.getElementById('reorder-pages');
    if (reorderInput) {
        reorderInput.value = order.join(', ');
    }
}
