/**
 * UI Fallback Utilities
 * Basic implementations of UI utilities that can be used if the main UI module is not available
 */
(function() {
    // Only initialize if window.ui is not already defined
    if (window.ui) {
        SafeLogger.log('Main UI utilities already available, skipping fallback');
        return;
    }

    SafeLogger.log('Initializing fallback UI utilities');

    /**
     * Inline fallback for HTML escaping - provides XSS protection even if
     * xss-protection.js fails to load.
     * NOTE: This declaration is safe because it is INSIDE an IIFE (function scope).
     * Do NOT move it to top-level scope — it would conflict with the global
     * escapeHtmlFallback in services/ui.js and crash the page.
     */
    // bearer:disable javascript_lang_manual_html_sanitization
    const escapeHtmlFallback = (str) => String(str).replace(/[&<>"']/g, (m) => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[m]);

    /**
     * Show a loading spinner
     * @param {HTMLElement} container - Container element for spinner
     * @param {string} message - Optional loading message
     */
    function showSpinner(container, message) {
        if (!container) container = document.body;
        // Escape message to prevent XSS
        const escapedMessage = message ? (window.escapeHtml || escapeHtmlFallback)(message) : '';
        const spinnerHtml = `
            <div class="ldr-loading-spinner ldr-centered">
                <div class="ldr-spinner"></div>
                ${escapedMessage ? `<div class="spinner-message">${escapedMessage}</div>` : ''}
            </div>
        `;
        // bearer:disable javascript_lang_dangerous_insert_html
        // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: variable built from escaped/numeric values above
        container.innerHTML = spinnerHtml;
    }

    /**
     * Hide loading spinner
     * @param {HTMLElement} container - Container with spinner
     */
    function hideSpinner(container) {
        if (!container) container = document.body;
        const spinner = container.querySelector('.ldr-loading-spinner');
        if (spinner) {
            spinner.remove();
        }
    }

    /**
     * Show an error message
     * @param {string} message - Error message to display
     */
    function showError(message) {
        SafeLogger.error(message);

        // Escape message to prevent XSS
        // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: plugin bug — LogicalExpression callee (github.com/mozilla/eslint-plugin-no-unsanitized/issues/263)
        const escapedMessage = (window.escapeHtml || escapeHtmlFallback)(message);

        // Create a notification element
        const notification = document.createElement('div');
        notification.className = 'ldr-notification ldr-error';
        // bearer:disable javascript_lang_dangerous_insert_html
        // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: variable built from escaped/numeric values above
        notification.innerHTML = `
            <i class="fas fa-exclamation-circle"></i>
            <span>${escapedMessage}</span>
            <button class="ldr-close-notification"><i class="fas fa-times"></i></button>
        `;

        // Add to the page if a notification container exists, otherwise use alert
        const container = document.querySelector('.ldr-notifications-container');
        if (container) {
            container.appendChild(notification);

            // Remove after a delay
            setTimeout(() => {
                notification.classList.add('ldr-removing');
                setTimeout(() => notification.remove(), 500);
            }, 5000);

            // Set up close button
            const closeBtn = notification.querySelector('.ldr-close-notification');
            if (closeBtn) {
                closeBtn.addEventListener('click', () => {
                    notification.classList.add('ldr-removing');
                    setTimeout(() => notification.remove(), 500);
                });
            }
        } else {
            // Fallback to alert
            alert(message);
        }
    }

    /**
     * Show a success/info message
     * @param {string} message - Message to display
     */
    function showMessage(message) {
        SafeLogger.log(message);

        // Escape message to prevent XSS
        // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: plugin bug — LogicalExpression callee (github.com/mozilla/eslint-plugin-no-unsanitized/issues/263)
        const escapedMessage = (window.escapeHtml || escapeHtmlFallback)(message);

        // Create a notification element
        const notification = document.createElement('div');
        notification.className = 'ldr-notification ldr-success';
        // bearer:disable javascript_lang_dangerous_insert_html
        // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: variable built from escaped/numeric values above
        notification.innerHTML = `
            <i class="fas fa-check-circle"></i>
            <span>${escapedMessage}</span>
            <button class="ldr-close-notification"><i class="fas fa-times"></i></button>
        `;

        // Add to the page if a notification container exists, otherwise use alert
        const container = document.querySelector('.ldr-notifications-container');
        if (container) {
            container.appendChild(notification);

            // Remove after a delay
            setTimeout(() => {
                notification.classList.add('ldr-removing');
                setTimeout(() => notification.remove(), 500);
            }, 5000);

            // Set up close button
            const closeBtn = notification.querySelector('.ldr-close-notification');
            if (closeBtn) {
                closeBtn.addEventListener('click', () => {
                    notification.classList.add('ldr-removing');
                    setTimeout(() => notification.remove(), 500);
                });
            }
        } else {
            // Fallback to alert
            alert(message);
        }
    }

    /**
     * Simple markdown renderer fallback
     * @param {string} markdown - Markdown content
     * @returns {string} HTML content (escaped for security)
     */
    function renderMarkdown(markdown) {
        if (!markdown) return '';

        // Fallback: escape all HTML and display as preformatted text for security
        // Using regex-based partial markdown is fragile and a security risk,
        // so we escape all HTML and display as preformatted text with a warning
        SafeLogger.warn('Fallback UI: Marked library not available. Displaying as plaintext for security.');
        const escaped = (window.escapeHtml || escapeHtmlFallback)(markdown);

        return `<div class="ldr-markdown-content">
            <div class="alert alert-warning" style="margin-bottom: 1rem;">
                <i class="fas fa-exclamation-triangle"></i> Markdown rendering unavailable. Displaying as plaintext.
            </div>
            <pre style="white-space: pre-wrap; word-wrap: break-word; font-family: inherit;">${escaped}</pre>
        </div>`;
    }

    /**
     * Update favicon to indicate status
     * @param {string} status - Status to indicate (active, complete, error)
     */
    function updateFavicon(status) {
        try {
            const faviconLink = document.querySelector('link[rel="icon"]') ||
                document.querySelector('link[rel="shortcut icon"]');

            if (!faviconLink) {
                SafeLogger.warn('Favicon link not found');
                return;
            }

            let iconPath;
            switch (status) {
                case 'active':
                    iconPath = '/static/img/favicon-active.ico';
                    break;
                case 'complete':
                    iconPath = '/static/img/favicon-complete.ico';
                    break;
                case 'error':
                    iconPath = '/static/img/favicon-error.ico';
                    break;
                default:
                    iconPath = '/static/img/favicon.ico';
            }

            // Add cache busting parameter to force reload
            const faviconUrl = iconPath + '?v=' + new Date().getTime();
            if (typeof URLValidator !== 'undefined' && URLValidator.safeAssign) {
                URLValidator.safeAssign(faviconLink, 'href', faviconUrl);
            } else {
                faviconLink.href = faviconUrl;
            }
            SafeLogger.log('Updated favicon to:', status);
        } catch (error) {
            SafeLogger.error('Failed to update favicon:', error);
        }
    }

    /**
     * Show an inline error message inside a container element (fallback stub)
     * Uses DOM API exclusively for XSS safety.
     * @param {string|Element} container - The container ID or element
     * @param {string} message - The error message
     * @param {Object} options - Options { dismissible: true }
     * @returns {HTMLElement|null} The created error element
     */
    function showInlineError(container, message, options = {}) {
        const containerEl = typeof container === 'string' ? document.getElementById(container) : container;
        if (!containerEl) {
            SafeLogger.warn('[fallback ui.showInlineError] Container not found:', container);
            return null;
        }

        const { dismissible = true } = options || {};

        clearInlineError(containerEl);

        const errorEl = document.createElement('div');
        errorEl.className = 'ldr-inline-error';
        errorEl.setAttribute('role', 'alert');

        const icon = document.createElement('i');
        icon.className = 'fas fa-exclamation-circle';
        errorEl.appendChild(icon);

        const span = document.createElement('span');
        span.textContent = message;
        errorEl.appendChild(span);

        if (dismissible) {
            const closeBtn = document.createElement('button');
            closeBtn.type = 'button';
            closeBtn.className = 'ldr-inline-error-close';
            closeBtn.setAttribute('aria-label', 'Dismiss error');
            closeBtn.textContent = '\u00d7';
            closeBtn.addEventListener('click', () => {
                errorEl.remove();
            });
            errorEl.appendChild(closeBtn);
        }

        containerEl.appendChild(errorEl);
        return errorEl;
    }

    /**
     * Clear inline errors from a container (fallback stub)
     * @param {string|Element} container - The container ID or element
     */
    function clearInlineError(container) {
        const containerEl = typeof container === 'string' ? document.getElementById(container) : container;
        if (containerEl) {
            const errors = containerEl.querySelectorAll('.ldr-inline-error');
            errors.forEach(el => el.remove());
        }
    }

    // Export utilities to window.ui
    window.ui = {
        showSpinner,
        hideSpinner,
        showError,
        showMessage,
        showInlineError,
        clearInlineError,
        renderMarkdown,
        updateFavicon
    };
})();
