/**
 * Modal System for MPV.Rocks Installer
 * Provides custom confirmation modals to replace browser confirm dialogs
 * 
 * Accessibility features:
 * - Focus trapping within modal
 * - Initial focus on first focusable element
 * - Focus restoration on close
 * - Keyboard navigation (Tab, Shift+Tab, Escape)
 * - ARIA attributes for screen readers
 */

(function() {
    'use strict';

    // Modal state
    let modalOverlay = null;
    let modalContainer = null;
    let pendingAction = null;
    let previousActiveElement = null;

    // Initialize modal when DOM is ready
    function initModal() {
        // Check if modal already exists
        if (document.getElementById('modal-overlay')) {
            modalOverlay = document.getElementById('modal-overlay');
            modalContainer = modalOverlay.querySelector('.modal-container');
            return;
        }

        // Create modal HTML structure
        const modalHTML = `
            <div id="modal-overlay" class="modal-overlay fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50" 
                 style="display: none;" role="dialog" aria-modal="true" aria-labelledby="modal-title">
                <div class="modal-container bg-gray-800 rounded-lg shadow-2xl max-w-md w-full mx-4">
                    <div class="modal-header p-6 border-b border-gray-700">
                        <div class="flex items-center justify-between">
                            <h3 id="modal-title" class="modal-title text-xl font-semibold text-white">Confirm Action</h3>
                            <button id="modal-close" class="text-gray-400 hover:text-white transition focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 focus:ring-offset-gray-800 rounded" aria-label="Close modal">
                                <i class="bx bx-x text-2xl" aria-hidden="true"></i>
                            </button>
                        </div>
                    </div>

                    <div class="modal-body p-6">
                        <p id="modal-message" class="modal-message text-gray-300">Are you sure you want to continue?</p>
                    </div>

                    <div class="modal-footer p-6 border-t border-gray-700 flex justify-end gap-3">
                        <button id="modal-cancel-btn" class="modal-cancel-btn bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded transition focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 focus:ring-offset-gray-800">
                            Cancel
                        </button>
                        <button id="modal-confirm-btn" class="modal-confirm-btn bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded transition focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 focus:ring-offset-gray-800">
                            Confirm
                        </button>
                    </div>
                </div>
            </div>
        `;

        // Append modal to body
        document.body.insertAdjacentHTML('beforeend', modalHTML);

        // Get references
        modalOverlay = document.getElementById('modal-overlay');
        modalContainer = modalOverlay.querySelector('.modal-container');

        // Attach event listeners
        attachEventListeners();
    }

    // Attach event listeners to modal elements
    function attachEventListeners() {
        const closeBtn = document.getElementById('modal-close');
        const cancelBtn = document.getElementById('modal-cancel-btn');
        const confirmBtn = document.getElementById('modal-confirm-btn');

        // Close button
        if (closeBtn) {
            closeBtn.addEventListener('click', hideModal);
        }

        // Cancel button
        if (cancelBtn) {
            cancelBtn.addEventListener('click', hideModal);
        }

        // Click outside modal
        modalOverlay.addEventListener('click', (e) => {
            if (e.target === modalOverlay) {
                hideModal();
            }
        });

        // Keyboard event handler for focus trapping and escape
        document.addEventListener('keydown', handleKeyDown);

        // Confirm button
        if (confirmBtn) {
            confirmBtn.addEventListener('click', executeModalAction);
        }
    }

    // Handle keyboard events for accessibility
    function handleKeyDown(e) {
        // Only handle when modal is visible
        if (!modalOverlay || modalOverlay.style.display === 'none') {
            return;
        }

        // Escape key closes modal
        if (e.key === 'Escape') {
            hideModal();
            return;
        }

        // Tab key - trap focus within modal
        if (e.key === 'Tab') {
            const focusableElements = getFocusableElements();
            if (focusableElements.length === 0) return;

            const firstElement = focusableElements[0];
            const lastElement = focusableElements[focusableElements.length - 1];

            if (e.shiftKey) {
                // Shift+Tab: if on first element, go to last
                if (document.activeElement === firstElement) {
                    e.preventDefault();
                    lastElement.focus();
                }
            } else {
                // Tab: if on last element, go to first
                if (document.activeElement === lastElement) {
                    e.preventDefault();
                    firstElement.focus();
                }
            }
        }
    }

    // Get all focusable elements within the modal
    function getFocusableElements() {
        if (!modalContainer) return [];
        
        const selector = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
        const elements = modalContainer.querySelectorAll(selector);
        return Array.from(elements).filter(el => el.offsetParent !== null); // Filter out hidden elements
    }

    // Show modal with data
    function showModal(data) {
        // Store the currently focused element to restore later
        previousActiveElement = document.activeElement;

        // Update title
        const titleEl = document.getElementById('modal-title');
        if (titleEl && data.title) {
            titleEl.textContent = data.title;
        }

        // Update message
        const messageEl = document.getElementById('modal-message');
        if (messageEl && data.message) {
            messageEl.innerHTML = data.message; // Use innerHTML to support icons/HTML
        }

        // Update cancel button text and visibility
        const cancelBtn = document.getElementById('modal-cancel-btn');
        if (cancelBtn) {
            if (data.cancel_text) {
                cancelBtn.textContent = data.cancel_text;
                cancelBtn.style.display = '';
            } else {
                // Hide cancel button for success modals
                cancelBtn.style.display = 'none';
            }
        }

        // Update confirm button
        const confirmBtn = document.getElementById('modal-confirm-btn');
        if (confirmBtn) {
            // Reset button state (in case previous action left it disabled)
            confirmBtn.disabled = false;
            
            if (data.confirm_text) {
                confirmBtn.textContent = data.confirm_text;
            }

            // Store callback function if provided (for custom actions)
            if (typeof data.on_confirm === 'function') {
                pendingAction = data.on_confirm;
                confirmBtn.dataset.confirmUrl = '';
                confirmBtn.dataset.confirmData = '';
            } else {
                // URL-based action (existing behavior)
                pendingAction = null;
                confirmBtn.dataset.confirmUrl = data.confirm_url || '';
                // Dataset only stores strings, so stringify objects
                if (typeof data.confirm_data === 'object' && data.confirm_data !== null) {
                    confirmBtn.dataset.confirmData = JSON.stringify(data.confirm_data);
                } else {
                    confirmBtn.dataset.confirmData = data.confirm_data || '';
                }
            }

            // Clear HTMX refresh configuration if using callback
            if (pendingAction) {
                delete confirmBtn.dataset.htmxRefresh;
                delete confirmBtn.dataset.htmxTarget;
            } else if (data.htmx_refresh && data.htmx_target) {
                // Store HTMX refresh configuration
                confirmBtn.dataset.htmxRefresh = data.htmx_refresh;
                confirmBtn.dataset.htmxTarget = data.htmx_target;
            } else {
                // Clear previous HTMX refresh data if present
                delete confirmBtn.dataset.htmxRefresh;
                delete confirmBtn.dataset.htmxTarget;
            }

            // Update button styling based on danger/success
            confirmBtn.classList.remove('bg-purple-600', 'hover:bg-purple-700', 'focus:ring-purple-500',
                                        'bg-red-600', 'hover:bg-red-700', 'focus:ring-red-500',
                                        'bg-green-600', 'hover:bg-green-700', 'focus:ring-green-500');
            
            if (data.success) {
                // Success modal - green button
                confirmBtn.classList.add('bg-green-600', 'hover:bg-green-700', 'focus:ring-green-500');
            } else if (data.danger) {
                confirmBtn.classList.add('bg-red-600', 'hover:bg-red-700', 'focus:ring-red-500');
            } else {
                confirmBtn.classList.add('bg-purple-600', 'hover:bg-purple-700', 'focus:ring-purple-500');
            }
        }

        // Show modal
        modalOverlay.style.display = 'flex';
        modalContainer.classList.remove('modal-closing');

        // Set initial focus to first focusable element (usually cancel button for safety)
        setTimeout(() => {
            const focusableElements = getFocusableElements();
            if (focusableElements.length > 0) {
                // Focus cancel button by default (safer option), or confirm button if cancel is hidden
                const cancelBtn = document.getElementById('modal-cancel-btn');
                if (cancelBtn && cancelBtn.style.display !== 'none') {
                    cancelBtn.focus();
                } else {
                    focusableElements[0].focus();
                }
            }
        }, 50);

        // Announce modal to screen readers
        announceModal(data.title || 'Dialog', data.message);
    }

    // Announce modal to screen readers
    function announceModal(title, message) {
        const announcer = document.getElementById('status-announcer');
        if (announcer) {
            announcer.textContent = `${title}: ${message}`;
        }
    }

    // Hide modal with animation
    function hideModal() {
        modalContainer.classList.add('modal-closing');
        setTimeout(() => {
            modalOverlay.style.display = 'none';
            pendingAction = null;

            // Restore focus to the previously focused element
            if (previousActiveElement && typeof previousActiveElement.focus === 'function') {
                previousActiveElement.focus();
            }
        }, 200);
    }

    // Execute the modal action
    async function executeModalAction() {
        const confirmBtn = document.getElementById('modal-confirm-btn');
        const originalContent = confirmBtn.innerHTML;
        let skipFinallyHide = false;
        
        // Show loading state on confirm button
        confirmBtn.disabled = true;
        confirmBtn.innerHTML = '<i class="bx bx-loader-alt bx-spin"></i> Processing...';

        // Check if we have a callback function
        if (pendingAction && typeof pendingAction === 'function') {
            try {
                await pendingAction();
                hideModal();
            } catch (error) {
                console.error('[Modal] Error executing callback:', error);
                alert('Error: ' + error.message);
            } finally {
                // Restore button state
                confirmBtn.disabled = false;
                confirmBtn.innerHTML = originalContent;
            }
            pendingAction = null;
            return;
        }

        // URL-based action (existing behavior)
        const confirmUrl = confirmBtn.dataset.confirmUrl;
        const confirmData = confirmBtn.dataset.confirmData;

        if (!confirmUrl) {
            console.error('[Modal] Missing confirm URL');
            confirmBtn.disabled = false;
            confirmBtn.innerHTML = originalContent;
            hideModal();
            return;
        }

        // Check if HTMX refresh is configured
        const useHTMXRefresh = confirmBtn.dataset.htmxRefresh && confirmBtn.dataset.htmxTarget;
        const htmxRefreshUrl = confirmBtn.dataset.htmxRefresh || '';
        const htmxTargetId = confirmBtn.dataset.htmxTarget || '';

        try {
            const options = {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                }
            };

        if (confirmData) {
            options.body = confirmData;
            console.log('[Modal] Sending data:', confirmData);
            console.log('[Modal] Data type:', typeof confirmData);
            console.log('[Modal] Data length:', confirmData.length);
        } else {
            console.log('[Modal] No data to send');
        }

        console.log('[Modal] Executing action:', confirmUrl);
        console.log('[Modal] Request options:', options);
        const response = await fetch(confirmUrl, options);

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            // Parse response JSON
            const responseData = await response.json();
            console.log('[Modal] Response data:', responseData);

            // Check for show_modal action - fetch and show a new modal
            if (responseData.action === 'show_modal' && responseData.modal_type) {
                console.log('[Modal] Server requested to show modal:', responseData.modal_type);
                hideModal();
                skipFinallyHide = true; // Don't hide again in finally block
                
                // Fetch the modal config and show it
                try {
                    const modalConfig = await fetchModalConfig(responseData.modal_type, new URLSearchParams());
                    showModal(modalConfig);
                } catch (error) {
                    console.error('[Modal] Failed to fetch modal config:', error);
                    alert('Update successful! Please restart the application manually.');
                }
                // Restore button state
                confirmBtn.disabled = false;
                confirmBtn.innerHTML = originalContent;
                return;
            }

            console.log('[Modal] Action successful');

            // Special handling for shutdown: show countdown then attempt to close tab
            if (confirmUrl === '/api/shutdown') {
                hideModal();
                // Show shutdown message with countdown
                const shutdownDiv = document.createElement('div');
                shutdownDiv.id = 'shutdown-overlay';
                shutdownDiv.className = 'fixed inset-0 bg-gray-900 bg-opacity-95 z-[100] flex items-center justify-center';
                shutdownDiv.innerHTML = `
                    <div class="bg-gray-800 rounded-lg shadow-2xl max-w-md w-full mx-4 p-8 text-center">
                        <i class="bx bx-check-circle text-6xl text-green-400 mb-4"></i>
                        <h2 class="text-2xl font-semibold text-white mb-2">Server Shutting Down</h2>
                        <p class="text-gray-400 mb-6">The MPV.Rocks Installer server is shutting down.</p>
                        <p id="shutdown-countdown" class="text-lg text-purple-400 font-medium">Closing in 5 seconds...</p>
                    </div>
                `;
                document.body.appendChild(shutdownDiv);

                // Start 5-second countdown
                let countdown = 5;
                const countdownEl = document.getElementById('shutdown-countdown');
                
                const countdownInterval = setInterval(() => {
                    countdown--;
                    if (countdown > 0) {
                        countdownEl.textContent = `Closing in ${countdown} second${countdown !== 1 ? 's' : ''}...`;
                    } else {
                        clearInterval(countdownInterval);
                        // Attempt to close the tab (only works for tabs opened by script)
                        try {
                            window.close();
                            // If we get here, window.close() didn't work (browser prevented it)
                            countdownEl.textContent = 'You can now close this tab manually.';
                            countdownEl.className = 'text-lg text-gray-300 font-medium';
                        } catch (e) {
                            // window.close() threw an error
                            countdownEl.textContent = 'You can now close this tab manually.';
                            countdownEl.className = 'text-lg text-gray-300 font-medium';
                        }
                    }
                }, 1000);

                return;
            }

            // Use HTMX partial refresh if configured
            if (useHTMXRefresh && typeof htmx !== 'undefined') {
                console.log('[Modal] Using HTMX partial refresh:', htmxRefreshUrl, '→', htmxTargetId);

                // Use HTMX to perform partial refresh
                htmx.ajax('GET', htmxRefreshUrl, {
                    target: htmxTargetId,
                    swap: 'innerHTML',
                }).then(function() {
                    console.log('[Modal] HTMX partial refresh complete');
                }).catch(function(error) {
                    console.error('[Modal] HTMX refresh failed:', error);
                    // Fallback to full page reload if HTMX fails
                    console.log('[Modal] Falling back to full page reload');
                    window.location.reload();
                });
            } else {
                // Fallback to full page reload for actions without HTMX refresh configured
                console.log('[Modal] No HTMX refresh configured, using full page reload');
                setTimeout(() => {
                    window.location.reload();
                }, 500);
            }


        } catch (error) {
            console.error('[Modal] Error executing action:', error);
            alert('Error executing action: ' + error.message);
            // Restore button state on error
            confirmBtn.disabled = false;
            confirmBtn.innerHTML = originalContent;
        } finally {
            if (!skipFinallyHide) {
                hideModal();
            }
        }
    }

    // Handle data-modal attribute clicks globally
    function handleModalClicks(e) {
        const button = e.target.closest('[data-modal]');
        if (!button) return;

        e.preventDefault();
        e.stopPropagation(); // Stop event from reaching HTMX

        const modalType = button.dataset.modal;
        const modalParamsRaw = button.dataset.modalParams || '';
        const modalParams = new URLSearchParams(modalParamsRaw);

        console.log('[Modal] Raw params from button:', modalParamsRaw);
        console.log('[Modal] Parsed params:', modalParams.toString());
        console.log('[Modal] Loading modal type:', modalType);

        fetchModalConfig(modalType, modalParams)
            .then(modalData => {
                showModal(modalData);
            })
            .catch(error => {
                console.error('[Modal] Error loading modal:', error);
                // Fallback to browser confirm
                fallbackToBrowserConfirm(button, error);
            });
    }

    // Fetch modal configuration from API
    async function fetchModalConfig(modalType, params) {
        const url = `/api/modal?type=${encodeURIComponent(modalType)}&${params.toString()}`;

        console.log('[Modal] Fetching config from:', url);

        const response = await fetch(url);

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        console.log('[Modal] Received data:', data);

        // Parse confirm_data if it's a JSON string
        if (data.confirm_data) {
            console.log('[Modal] confirm_data before parse:', data.confirm_data);
            try {
                data.confirm_data = JSON.parse(data.confirm_data);
                console.log('[Modal] confirm_data after parse:', data.confirm_data);
            } catch (e) {
                console.warn('[Modal] Failed to parse confirm_data as JSON:', e);
            }
        }

        return data;
    }

    // Fallback to browser confirm if modal system fails
    function fallbackToBrowserConfirm(button, error) {
        console.warn('[Modal] Falling back to browser confirm due to error:', error);

        // Check for data-modal-fallback attribute (set by setupFallbacks)
        // or fall back to hx-confirm if available
        let confirmMsg = button.dataset.modalFallback;
        if (!confirmMsg && button.hasAttribute('hx-confirm')) {
            confirmMsg = button.getAttribute('hx-confirm');
        }

        if (confirmMsg && confirm(confirmMsg)) {
            // Trigger the HTMX request directly since we've confirmed
            if (typeof htmx !== 'undefined') {
                htmx.trigger(button, 'htmx:trigger');
            }
        }
    }

    // Store original modal types for fallback
    function setupFallbacks() {
        document.querySelectorAll('[data-modal]').forEach(button => {
            button.dataset.modalTypeBackup = button.dataset.modal;

            if (button.hasAttribute('hx-confirm')) {
                button.dataset.modalFallback = button.getAttribute('hx-confirm');
            }
        });
    }

    // Public API
    window.MPVRocksModal = {
        show: showModal,
        hide: hideModal,
        init: initModal,
        // Convenience method for confirmation dialogs with callbacks
        confirm: function(title, message, confirmText, cancelText, onConfirm, isDanger = true) {
            showModal({
                title: title,
                message: message,
                confirm_text: confirmText,
                cancel_text: cancelText,
                danger: isDanger,
                on_confirm: onConfirm
            });
        }
    };

    // Initialize on DOM ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            initModal();
            setupFallbacks();
            document.addEventListener('click', handleModalClicks);
        });
    } else {
        initModal();
        setupFallbacks();
        document.addEventListener('click', handleModalClicks);
    }

})();
