/**
 * Previewer - Handles live preview for all content types
 */
import { markdownConverter } from '../utils/markdown.js';

export class Previewer {
    constructor() {
        this.previewTimeout = null;
        this.activeContext = null;
        this.resizeObserver = null;
        this.onHeightChange = null;
    }

    /**
     * Set the active editing context for preview
     */
    setActiveContext(context) {
        this.clearPreview();
        this.activeContext = context;
        this.startResizeObserver();
    }

    /**
     * Schedule a preview update with debouncing
     */
    schedulePreview(context, content) {
        // Clear existing timeout
        if (this.previewTimeout) {
            clearTimeout(this.previewTimeout);
        }

        // Schedule new preview with 500ms debounce
        this.previewTimeout = setTimeout(() => {
            this.updatePreview(context, content);
        }, 500);
    }

    /**
     * Update preview with new content
     */
    updatePreview(context, content) {
        // Store original content if first preview
        if (!context.originalContent) {
            context.storeOriginalContent();
        }

        // Apply preview content to elements
        this.applyPreviewContent(context, content);
        context.applyPreviewStyling();
    }

    /**
     * Apply preview content to context elements
     */
    applyPreviewContent(context, content) {
        if (context.elements.length === 1) {
            const element = context.elements[0];
            
            // Handle links specially
            if (element.tagName.toLowerCase() === 'a') {
                if (typeof content === 'object') {
                    // Update link text (markdown to HTML)
                    if (content.text !== undefined) {
                        const html = markdownConverter.markdownToHtml(content.text);
                        element.innerHTML = html;
                    }
                    // Update link URL
                    if (content.url !== undefined && content.url.trim()) {
                        element.href = content.url;
                    }
                } else if (content && content.trim()) {
                    // Just markdown content for link text
                    const html = markdownConverter.markdownToHtml(content);
                    element.innerHTML = html;
                }
                return;
            }
            
            // Regular single element
            if (content && content.trim()) {
                const html = markdownConverter.markdownToHtml(content);
                element.innerHTML = html;
            }
        } else {
            // Multiple elements - use group update
            if (content && content.trim()) {
                markdownConverter.updateGroupElements(context.elements, content);
            }
        }
    }

    /**
     * Clear all preview state and restore original content
     */
    clearPreview() {
        if (this.activeContext) {
            this.activeContext.restoreOriginalContent();
            this.activeContext.removePreviewStyling();
            this.activeContext = null;
        }

        if (this.previewTimeout) {
            clearTimeout(this.previewTimeout);
            this.previewTimeout = null;
        }

        this.stopResizeObserver();
    }

    /**
     * Start observing element size changes for modal repositioning
     */
    startResizeObserver() {
        this.stopResizeObserver();

        if (this.activeContext) {
            this.resizeObserver = new ResizeObserver(() => {
                // Handle height changes for modal repositioning
                if (this.onHeightChange) {
                    this.onHeightChange(this.activeContext.primaryElement);
                }
            });

            // Observe all elements in the context
            this.activeContext.elements.forEach(el => {
                this.resizeObserver.observe(el);
            });
        }
    }

    /**
     * Stop observing element size changes
     */
    stopResizeObserver() {
        if (this.resizeObserver) {
            this.resizeObserver.disconnect();
            this.resizeObserver = null;
        }
    }

    /**
     * Set callback for height changes (for modal repositioning)
     */
    setHeightChangeCallback(callback) {
        this.onHeightChange = callback;
    }

    /**
     * Get unique element ID for tracking
     */
    getElementId(element) {
        if (!element._insertrId) {
            element._insertrId = 'insertr_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        }
        return element._insertrId;
    }
}