/**
 * Option Highlight Manager
 *
 * Manages LLM-based option highlighting for discrete annotation tasks.
 * Dims less-likely options while keeping top-k most likely options at full opacity.
 */

class OptionHighlightManager {
    constructor() {
        this.config = null;
        this.cache = new Map();  // Client-side cache: annotationId -> highlights
        this.loadingStates = new Set();  // Track loading states per annotation
        this.initialized = false;
    }

    /**
     * Initialize the manager with configuration from the server.
     */
    async initialize() {
        if (this.initialized) {
            return;
        }

        try {
            const response = await fetch('/api/option_highlights/config');
            if (!response.ok) {
                console.warn('[OptionHighlight] Failed to load config:', response.status);
                return;
            }

            this.config = await response.json();
            console.log('[OptionHighlight] Config loaded:', this.config);

            if (!this.config.enabled) {
                console.log('[OptionHighlight] Feature disabled');
                return;
            }

            this.initialized = true;

            // Apply highlights on page load if auto_apply is enabled
            if (this.config.auto_apply) {
                // Wait for DOM to be ready
                if (document.readyState === 'loading') {
                    document.addEventListener('DOMContentLoaded', () => this.applyAllHighlights());
                } else {
                    // Small delay to ensure annotation forms are rendered
                    setTimeout(() => this.applyAllHighlights(), 100);
                }
            }

            // Trigger prefetch for upcoming items
            this.triggerPrefetch();

        } catch (error) {
            console.error('[OptionHighlight] Error initializing:', error);
        }
    }

    /**
     * Check if a schema should have option highlighting applied.
     * @param {string} schemaName - The annotation schema name
     * @returns {boolean}
     */
    shouldApplyToSchema(schemaName) {
        if (!this.config || !this.config.enabled) {
            return false;
        }

        // If schemas filter is not set, apply to all discrete schemas
        if (this.config.schemas === null || this.config.schemas === undefined) {
            return true;
        }

        return this.config.schemas.includes(schemaName);
    }

    /**
     * Apply highlights to all annotation forms on the page.
     */
    async applyAllHighlights() {
        if (!this.config || !this.config.enabled) {
            return;
        }

        const forms = document.querySelectorAll('.annotation-form');
        console.log('[OptionHighlight] Applying to', forms.length, 'forms');

        for (const form of forms) {
            const annotationId = form.getAttribute('data-annotation-id');
            const schemaName = form.id || form.dataset.schemaName || '';
            const annotationType = form.dataset.annotationType || '';

            // Only apply to discrete option types
            const discreteTypes = ['radio', 'multiselect', 'likert', 'select'];
            if (!discreteTypes.includes(annotationType)) {
                continue;
            }

            if (this.shouldApplyToSchema(schemaName)) {
                await this.applyHighlightsToForm(form, annotationId);
            }
        }
    }

    /**
     * Apply highlights to a specific annotation form.
     * @param {HTMLElement} form - The annotation form element
     * @param {string|number} annotationId - The annotation ID
     */
    async applyHighlightsToForm(form, annotationId) {
        // Skip if already loading
        if (this.loadingStates.has(annotationId)) {
            return;
        }

        this.loadingStates.add(annotationId);

        try {
            // Check cache first
            let highlights = this.cache.get(annotationId);

            if (!highlights) {
                // Fetch from server
                highlights = await this.fetchHighlights(annotationId);
                if (highlights && !highlights.error) {
                    this.cache.set(annotationId, highlights);
                }
            }

            if (!highlights || highlights.error) {
                console.warn('[OptionHighlight] No highlights for annotation', annotationId, highlights?.error);
                return;
            }

            // Apply visual highlighting
            this.applyVisualHighlights(form, highlights);

        } catch (error) {
            console.error('[OptionHighlight] Error applying highlights:', error);
        } finally {
            this.loadingStates.delete(annotationId);
        }
    }

    /**
     * Fetch highlights from the server API.
     * @param {string|number} annotationId - The annotation ID
     * @returns {Promise<Object>} Highlight data
     */
    async fetchHighlights(annotationId) {
        try {
            const response = await fetch(`/api/option_highlights/${annotationId}`);
            if (!response.ok) {
                return { error: `HTTP ${response.status}` };
            }
            return await response.json();
        } catch (error) {
            return { error: error.message };
        }
    }

    /**
     * Apply visual highlighting to form options.
     * @param {HTMLElement} form - The annotation form element
     * @param {Object} highlights - The highlight data from the server
     */
    applyVisualHighlights(form, highlights) {
        const highlightedOptions = highlights.highlighted || [];
        const dimOpacity = this.config?.dim_opacity || 0.4;

        console.log('[OptionHighlight] Applying visual highlights:', highlightedOptions);

        // Find all option elements in the form
        const optionContainers = form.querySelectorAll(
            '.shadcn-radio-option, .shadcn-checkbox-option, .shadcn-span-option, ' +
            '.option-item, .likert-option, .form-check'
        );

        // Add AI highlighting active indicator to the form
        form.classList.add('ai-highlighting-active');

        optionContainers.forEach(container => {
            // Get the input element
            const input = container.querySelector('input[type="radio"], input[type="checkbox"]');
            if (!input) return;

            const value = input.value;
            const labelElement = container.querySelector('label') || container;
            const labelText = labelElement.textContent?.trim() || '';

            // Check if this option should be highlighted
            const isHighlighted = highlightedOptions.some(opt => {
                const optLower = String(opt).toLowerCase();
                const valueLower = String(value).toLowerCase();
                const labelLower = labelText.toLowerCase();
                return optLower === valueLower ||
                       labelLower.includes(optLower) ||
                       optLower.includes(valueLower);
            });

            // Apply appropriate classes
            if (isHighlighted) {
                container.classList.add('option-highlighted');
                container.classList.remove('option-dimmed');
            } else {
                container.classList.add('option-dimmed');
                container.classList.remove('option-highlighted');
                container.style.setProperty('--dim-opacity', dimOpacity);
            }
        });
    }

    /**
     * Clear all highlights from the page.
     */
    clearAllHighlights() {
        // Remove classes from all option containers
        document.querySelectorAll('.option-highlighted, .option-dimmed').forEach(el => {
            el.classList.remove('option-highlighted', 'option-dimmed');
            el.style.removeProperty('--dim-opacity');
        });

        // Remove active indicator from forms
        document.querySelectorAll('.ai-highlighting-active').forEach(el => {
            el.classList.remove('ai-highlighting-active');
        });

        // Clear cache
        this.cache.clear();
    }

    /**
     * Clear highlights for a specific annotation.
     * @param {string|number} annotationId - The annotation ID
     */
    clearHighlights(annotationId) {
        const form = document.querySelector(`.annotation-form[data-annotation-id="${CSS.escape(String(annotationId))}"]`);
        if (!form) return;

        form.querySelectorAll('.option-highlighted, .option-dimmed').forEach(el => {
            el.classList.remove('option-highlighted', 'option-dimmed');
            el.style.removeProperty('--dim-opacity');
        });

        form.querySelectorAll('.option-highlight-indicator').forEach(el => {
            el.remove();
        });

        form.classList.remove('ai-highlighting-active');
        this.cache.delete(annotationId);
    }

    /**
     * Trigger server-side prefetching of upcoming items.
     */
    async triggerPrefetch() {
        if (!this.config || !this.config.enabled) {
            return;
        }

        try {
            await fetch('/api/option_highlights/prefetch', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ count: this.config.prefetch_count })
            });
            console.log('[OptionHighlight] Prefetch triggered');
        } catch (error) {
            console.warn('[OptionHighlight] Prefetch trigger failed:', error);
        }
    }

    /**
     * Refresh highlights (e.g., after navigation).
     */
    async refresh() {
        if (!this.config || !this.config.enabled) {
            return;
        }

        // Clear existing highlights
        this.clearAllHighlights();

        // Re-apply if auto_apply is enabled
        if (this.config.auto_apply) {
            await this.applyAllHighlights();
        }

        // Trigger prefetch for next items
        this.triggerPrefetch();
    }

    /**
     * Toggle highlighting on/off for the current page.
     */
    toggle() {
        if (!this.config) {
            return;
        }

        const hasHighlights = document.querySelector('.option-highlighted, .option-dimmed');

        if (hasHighlights) {
            this.clearAllHighlights();
        } else {
            this.applyAllHighlights();
        }
    }
}

// Create global instance
window.optionHighlightManager = new OptionHighlightManager();

// Initialize when DOM is ready
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        window.optionHighlightManager.initialize();
    });
} else {
    window.optionHighlightManager.initialize();
}
