/**
 * Table of Contents generation and scroll functionality
 */

/**
 * Scroll to header service - uses line numbers for reliable targeting
 */
const ScrollToHeaderService = {
    /**
     * Scroll to a specific header in the editor by line number
     * @param {Object} editorInstance - Toast UI Editor instance
     * @param {string} headerText - Text content of the header (for highlighting)
     * @param {number} lineIndex - 0-based line index of the header in markdown
     */
    scrollToHeader(editorInstance, headerText, lineIndex) {
        if (!editorInstance) {
            console.warn('Editor instance not available for scrolling');
            return;
        }

        try {
            const editorElements = editorInstance.getEditorElements();
            const isWysiwygMode = editorInstance.isWysiwygMode();

            if (isWysiwygMode) {
                // In WYSIWYG mode, find header by text (no line numbers available)
                const wysiwygEditor = editorElements.wwEditor;
                if (wysiwygEditor) {
                    const headers = wysiwygEditor.querySelectorAll('h1, h2, h3, h4, h5, h6');
                    for (const header of headers) {
                        if (header.textContent.trim() === headerText.trim()) {
                            // Scroll the editor container directly with 10px offset
                            const headerPosition = header.getBoundingClientRect().top - wysiwygEditor.getBoundingClientRect().top;
                            const offset = 10; // Account for fixed headers or padding
                            wysiwygEditor.scrollTop = headerPosition - offset;
                            this._highlightHeader(header);
                            break;
                        }
                    }
                }
            } else {
                // In markdown mode, use line number to position cursor, then scroll preview
                const lineNumber = lineIndex + 1; // Convert to 1-based
                
                // Move cursor to the heading line in the editor
                try {
                    editorInstance.setSelection([lineNumber, 1], [lineNumber, 1]);
                } catch (e) {
                    if (DEBUG) console.debug('Could not set selection:', e);
                }

                // Scroll preview to matching header
                const previewElement = editorElements.mdPreview;
                if (previewElement) {
                    const headers = previewElement.querySelectorAll('h1, h2, h3, h4, h5, h6');
                    
                    for (const header of headers) {
                        if (header.textContent.trim() === headerText.trim()) {
                            // Scroll the preview container directly with 10px offset
                            const headerPosition = header.getBoundingClientRect().top - previewElement.getBoundingClientRect().top;
                            const offset = 10; // Account for fixed headers or padding
                            previewElement.scrollTop = headerPosition - offset;
                            this._highlightHeader(header);
                            break;
                        }
                    }
                }
            }
        } catch (error) {
            console.error('Error scrolling to header:', error);
        }
    },

    /**
     * Highlight header briefly for visual feedback
     * @param {HTMLElement} headerElement - Header to highlight
     */
    _highlightHeader(headerElement) {
        if (!headerElement) return;
        
        headerElement.style.transition = 'background-color 0.3s ease';
        headerElement.style.backgroundColor = '#fef3c7';
        
        setTimeout(() => {
            headerElement.style.backgroundColor = '';
            setTimeout(() => {
                headerElement.style.transition = '';
            }, 300);
        }, 1500);
    }
};

/**
 * Generate and update the TOC from markdown content
 * @param {string} content - Markdown content
 * @param {HTMLElement} tocContainer - Container for the TOC
 * @param {Object} editorInstance - Toast UI Editor instance
 * @param {number} maxDepth - Maximum heading level (1-6)
 */
function updateToc(content, tocContainer, editorInstance, maxDepth = 6) {
    if (content === undefined || content === null || !tocContainer) {
        console.warn('Missing required params for updateToc');
        return;
    }

    tocContainer.innerHTML = '';

    const tocList = document.createElement('ul');
    tocList.className = 'toc-list pl-0 text-sm';

    if (!content.trim()) {
        const emptyMessage = document.createElement('p');
        emptyMessage.className = 'text-gray-500 p-4';
        emptyMessage.textContent = 'This file is empty.';
        tocContainer.appendChild(emptyMessage);
        return;
    }

    const headings = [];
    const lines = content.split('\n');
    
    lines.forEach((line, index) => {
        const match = line.match(/^(#{1,6})\s+(.+)$/);
        if (match) {
            const level = match[1].length;
            let text = match[2].trim();
            
            // Clean markdown formatting
            text = text
                .replace(/\\(.)/g, '$1')
                .replace(/\*\*(.*?)\*\*/g, '$1')
                .replace(/\*(.*?)\*/g, '$1')
                .replace(/`(.*?)`/g, '$1')
                .replace(/\[(.*?)\]\(.*?\)/g, '$1')
                .replace(/~~(.*?)~~/g, '$1')
                .trim();
            
            const id = text.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
            
            headings.push({
                level,
                text,
                id,
                lineIndex: index
            });
        }
    });

    let currentList = tocList;
    let currentLevel = 0;
    let listsStack = [tocList];

    const filteredHeadings = headings.filter(heading => heading.level <= maxDepth);

    if (filteredHeadings.length === 0) {
        const noHeadings = document.createElement('p');
        noHeadings.className = 'text-gray-500 p-4';
        noHeadings.textContent = maxDepth === 6 ? 'No headings found in this document.' :
            'No headings at or below level H' + maxDepth + ' found.';
        tocContainer.appendChild(noHeadings);
        return;
    }

    filteredHeadings.forEach(heading => {
        const li = document.createElement('li');
        li.className = `toc-item toc-level-${heading.level} py-1`;

        const a = document.createElement('a');
        a.innerHTML = heading.text;
        a.href = '#';
        a.className = 'text-blue-600 hover:text-blue-800 hover:underline cursor-pointer';
        a.dataset.headerText = heading.text;
        a.dataset.lineIndex = heading.lineIndex;

        a.addEventListener('click', function(e) {
            e.preventDefault();
            
            if (editorInstance && ScrollToHeaderService) {
                try {
                    ScrollToHeaderService.scrollToHeader(
                        editorInstance, 
                        heading.text, 
                        parseInt(heading.lineIndex)
                    );
                } catch (error) {
                    console.error('Error in ScrollToHeaderService.scrollToHeader:', error);
                }
            }
        });

        li.appendChild(a);

        if (heading.level > currentLevel) {
            const nestedUl = document.createElement('ul');
            nestedUl.className = 'pl-4 mt-1';
            listsStack[listsStack.length - 1].appendChild(nestedUl);
            listsStack.push(nestedUl);
            currentList = nestedUl;
            currentLevel = heading.level;
        } else if (heading.level < currentLevel) {
            while (heading.level < currentLevel && listsStack.length > 1) {
                listsStack.pop();
                currentLevel--;
            }
            currentList = listsStack[listsStack.length - 1];
        }

        currentList.appendChild(li);
    });

    tocContainer.appendChild(tocList);
    clearActiveTocItem(tocContainer);
}

/**
 * Clear active TOC item from all items within the container
 * @param {HTMLElement} tocContainer - Container element holding the TOC
 */
function clearActiveTocItem(tocContainer) {
    if (!tocContainer) return;
    
    const activeItems = tocContainer.querySelectorAll('.toc-active');
    activeItems.forEach(item => {
        item.classList.remove('toc-active');
    });
}

/**
 * Set active TOC item by finding the link matching the header text
 * @param {HTMLElement} tocContainer - Container element holding the TOC
 * @param {string} headerText - Text of the header to match and activate
 */
function setActiveTocItem(tocContainer, headerText) {
    if (!tocContainer || !headerText) return;
    
    // First clear any existing active items
    clearActiveTocItem(tocContainer);
    
    // Find the link matching the header text
    const links = tocContainer.querySelectorAll('a[data-header-text]');
    for (const link of links) {
        if (link.dataset.headerText === headerText) {
            // Add toc-active class to the parent li element
            const li = link.parentElement;
            if (li) {
                li.classList.add('toc-active');
            }
            break;
        }
    }
}

// Reachable at top-level scope to other concatenated mdedit JS files via the
// build's flat-IIFE-less module pattern; no window.* exports needed.
