/**
 * OTIS Centralized JavaScript
 * Handling global AJAX, Toasts, and UX utilities
 */

const OTIS = {
    baseUri: '',

    init: function(baseUrl) {
        this.baseUri = baseUrl;
        this.initThemeToggle();
        this.initFrictionFreeEngine();
    },

    /**
     * Shows a Bootstrap Toast alert
     */
    toast: function(title, message, type = 'success') {
        const bgColors = {
            'success': '#198754',
            'warning': '#ffc107',
            'danger': '#dc3545',
            'info': '#0dcf0'
        };
        const bgColor = bgColors[type] || '#0d6efd';
        const textColor = type === 'warning' ? '#000' : '#fff';
        
        const toastId = 'sys-toast-' + Date.now();
        const toastHTML = `
            <div id="${toastId}" class="toast align-items-center border-0 shadow-lg show" role="alert" aria-live="assertive" aria-atomic="true" style="background-color:${bgColor}; color:${textColor};">
                <div class="d-flex">
                    <div class="toast-body">
                        <strong>${title}</strong><br>
                        <small>${message}</small>
                    </div>
                    <button type="button" class="btn-close ${type === 'warning' ? '' : 'btn-close-white'} me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
                </div>
            </div>`;
        
        const container = document.querySelector('.toast-container');
        if(container) {
            container.insertAdjacentHTML('beforeend', toastHTML);
            const el = document.getElementById(toastId);
            setTimeout(() => {
                el.classList.remove('show');
                setTimeout(() => el.remove(), 300);
            }, 6000);
        }
    },

    /**
     * Universal AJAX GET
     */
    get: async function(url) {
        try {
            const res = await fetch(this.baseUri + url, {
                headers: { 'X-Requested-With': 'XMLHttpRequest' }
            });
            return await res.json();
        } catch(e) {
            console.error(e);
            return { success: false, error: 'Network error' };
        }
    },

    /**
     * Universal AJAX POST
     */
    post: async function(url, data) {
        try {
            const res = await fetch(this.baseUri + url, {
                method: 'POST',
                headers: { 
                    'Content-Type': 'application/json',
                    'X-Requested-With': 'XMLHttpRequest'
                },
                body: JSON.stringify(data)
            });
            return await res.json();
        } catch(e) {
            console.error(e);
            return { success: false, error: 'Network error' };
        }
    },

    /**
     * Theme Toggling Logic
     */
    initThemeToggle: function() {
        const toggleBtn = document.getElementById('themeToggleBtn');
        if(!toggleBtn) return;

        toggleBtn.addEventListener('click', async (e) => {
            e.preventDefault();
            const body = document.body;
            const isDark = body.classList.contains('dark-mode');
            const newTheme = isDark ? 'light' : 'dark';
            
            // Visual instant toggle
            if(newTheme === 'dark') {
                body.classList.add('dark-mode');
                toggleBtn.innerHTML = '<i class="fa-solid fa-sun text-warning"></i>';
                localStorage.setItem('theme', 'dark');
            } else {
                body.classList.remove('dark-mode');
                toggleBtn.innerHTML = '<i class="fa-solid fa-moon"></i>';
                localStorage.setItem('theme', 'light');
            }
            
            // Background DB Sync
            try {
                const fd = new FormData();
                fd.append('theme', newTheme);
                await fetch(this.baseUri + '/system/toggleTheme', { method: 'POST', body: fd, headers:{'X-Requested-With': 'XMLHttpRequest'} });
            } catch(error) { console.error('Failed to sync theme', error); }
        });
    },

    /**
     * Friction-Free Action Engine (PJAX + Local Storage Memory)
     * Upgrades the entire app to a Single Page App (SPA) automatically.
     */
    initFrictionFreeEngine: function() {
        // === Bootstrap initial history state so popstate always has valid data ===
        history.replaceState({ pjax: true, url: location.href }, document.title, location.href);

        // 1. Intercept ALL Forms
        document.addEventListener('submit', async (e) => {
            if (window.innerWidth < 768) return; // Disable PJAX completely on mobile
            if (e.target.matches('form:not([data-no-pjax])')) {
                e.preventDefault();
                const form = e.target;
                const submitBtn = form.querySelector('[type="submit"]');
                let oText = '';
                
                if (submitBtn) {
                    oText = submitBtn.innerHTML;
                    submitBtn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i>';
                    submitBtn.disabled = true;
                }

                // Cache User Memory (Inputs & Selects)
                form.querySelectorAll('select, input:not([type="hidden"], [type="password"])').forEach(el => {
                    if (el.name) localStorage.setItem('otis_pref_' + el.name, el.value);
                });

                try {
                    const formData = new FormData(form);
                    let url = form.action;
                    let options = {
                        method: form.method || 'POST',
                        headers: { 'X-Requested-With': 'XMLHttpRequest' }
                    };

                    if (options.method.toUpperCase() === 'GET') {
                        const params = new URLSearchParams(formData).toString();
                        url += (url.indexOf('?') === -1 ? '?' : '&') + params;
                    } else {
                        options.body = formData;
                    }

                    const res = await fetch(url, options);

                    // Check if response is JSON
                    const contentType = res.headers.get("content-type");
                    if (contentType && contentType.indexOf("application/json") !== -1) {
                        const json = await res.json();
                        
                        // 🔥 Global Modal Freeze Fix for JSON responses
                        document.querySelectorAll('.modal.show').forEach(m => {
                            if(typeof bootstrap !== 'undefined') {
                                let bsModal = bootstrap.Modal.getInstance(m);
                                if (bsModal) bsModal.hide();
                            }
                        });
                        // Fallback cleanup
                        document.querySelectorAll('.modal-backdrop').forEach(el => el.remove());
                        document.body.classList.remove('modal-open');
                        document.body.style = '';

                        if (json.success && json.redirect) {
                            await OTIS.pjaxLoad(json.redirect, true);
                        } else if (json.success) {
                            OTIS.toast('نجاح ⚡', 'تم التنفيذ في لمح البصر');
                            setTimeout(() => OTIS.pjaxLoad(window.location.href, false), 500); // PJAX reload current tab (no pushState)
                        } else {
                            OTIS.toast('خطأ ⚠️', json.message || 'فشلت العملية', 'danger');
                            if (submitBtn) { submitBtn.innerHTML = oText; submitBtn.disabled = false; }
                        }
                    } else {
                        // Response is HTML (likely due to PHP redirect)
                        const html = await res.text();
                        
                        // 🔥 Global Modal Freeze Fix
                        document.querySelectorAll('.modal.show').forEach(m => {
                            if(typeof bootstrap !== 'undefined') {
                                let bsModal = bootstrap.Modal.getInstance(m);
                                if (bsModal) bsModal.hide();
                            }
                        });
                        // Fallback cleanup
                        document.querySelectorAll('.modal-backdrop').forEach(el => el.remove());
                        document.body.classList.remove('modal-open');
                        document.body.style = '';

                        const parser = new DOMParser();
                        const newDoc = parser.parseFromString(html, 'text/html');
                        const newContent = newDoc.querySelector('.content-wrapper');

                        if (newContent) {
                            document.querySelector('.content-wrapper').innerHTML = newContent.innerHTML;
                            OTIS.reinitDOM();
                            OTIS.toast('نجاح ⚡', 'تم التنفيذ بنجاح');
                            
                            const finalUrl = res.url || window.location.href;
                            if (finalUrl !== window.location.href) {
                                history.pushState({ pjax: true, url: finalUrl }, newDoc.title, finalUrl);
                            } else {
                                // Same URL: replace state to keep title/state in sync
                                history.replaceState({ pjax: true, url: finalUrl }, newDoc.title, finalUrl);
                            }
                        } else {
                            window.location.href = res.url || window.location.href;
                        }
                    }
                } catch(err) {
                    console.error('Friction-Free Form Error:', err);
                    // Fallback: navigate normally — don't show fake network error
                    window.location.href = form.action;
                }
            }
        });

        // 1. Intercept ALL internal Links
        document.addEventListener('click', async (e) => {
            if (window.innerWidth < 768) return; // Disable PJAX completely on mobile
            let a = e.target.closest('a');

            if (!a) return;

            // 🚫 NEVER touch navbar links
            if (a.closest('.sidebar-wrapper') || a.closest('.offcanvas')) {
                return; // allow normal navigation
            }

            if (
                a.href &&
                a.host === window.location.host &&
                !a.hasAttribute('data-no-pjax') &&
                !a.target &&
                !a.href.includes('#') &&
                !a.href.includes('/auth/logout')
            ) {
                e.preventDefault();
                await OTIS.pjaxLoad(a.href, true);
            }
        });

        // FORCE CLEAN NAVBAR BEHAVIOR
        document.querySelectorAll('.sidebar-wrapper a').forEach(link => {
            link.onclick = null;
        });

        // 3. Handle Browser Back/Forward buttons
        // CRITICAL: pass pushState=false — popstate already changed the URL,
        // we must NOT push a duplicate state entry on top.
        window.addEventListener('popstate', async (e) => {
            const url = (e.state && e.state.url) ? e.state.url : location.href;
            await this.pjaxLoad(url, false);
        });

        // 4. Initial DOM fill from User Memory
        this.applyFrictionFreeDefaults();
    },

    pjaxLoad: async function(url, pushState = false) {
        try {
            const res = await fetch(url, {
                headers: { 'X-PJAX': 'true', 'X-Requested-With': 'XMLHttpRequest' }
            });
            const html = await res.text();
            
            // Build temporary DOM to extract the new content
            const parser = new DOMParser();
            const newDoc = parser.parseFromString(html, 'text/html');
            const newContent = newDoc.querySelector('.content-wrapper');

            if (newContent) {
                // Update specific layout pieces
                document.querySelector('.content-wrapper').innerHTML = newContent.innerHTML;
                document.title = newDoc.title;
                
                // Update Active Link State in Sidebar
                document.querySelectorAll('.dashboard-nav .nav-link').forEach(n => n.classList.remove('active'));
                const newActive = newDoc.querySelector('.dashboard-nav .nav-link.active');
                if (newActive) {
                    // Find corresponding nav link in current DOM by href
                    const match = document.querySelector(`.dashboard-nav .nav-link[href="${newActive.getAttribute('href')}"]`);
                    if(match) match.classList.add('active');
                }

                if (pushState) {
                    // Only push if the URL actually changed to prevent history bloat
                    if (window.location.href !== url) {
                        history.pushState({ pjax: true, url: url }, newDoc.title, url);
                    }
                } else {
                    // On popstate or same-page reload: sync state without adding history entry
                    history.replaceState({ pjax: true, url: url }, newDoc.title, url);
                }

                // Scroll to top on new page load
                window.scrollTo(0, 0);

                // Re-initialize scripts inside the new content
                this.reinitDOM();
            } else {
                // Fallback for fatal errors or blank pages
                window.location.href = url;
            }
        } catch(err) {
            console.error('PJAX Error:', err);
            // Fallback: full reload if AJAX fails
            if (url !== window.location.href) {
                window.location.href = url;
            } else {
                window.location.reload();
            }
        }
    },

    reinitDOM: function() {
        // Run nested inline scripts safely
        const scripts = document.querySelector('.content-wrapper').querySelectorAll('script');
        scripts.forEach(s => {
            if (s.src) {
                // Prevent duplicate loading of external scripts
                if (document.querySelector(`script[src="${s.src}"]`)) return; 
                
                const newScript = document.createElement('script');
                newScript.src = s.src;
                document.body.appendChild(newScript);
            } else {
                const newScript = document.createElement('script');
                newScript.textContent = s.textContent;
                document.body.appendChild(newScript);
                document.body.removeChild(newScript);
            }
        });

        this.applyFrictionFreeDefaults();
        
        // Re-init Tooltips/Modals/Datepickers if they exist
        if (typeof bootstrap !== 'undefined') {
            document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => new bootstrap.Tooltip(el));
        }
    },

    applyFrictionFreeDefaults: function() {
        // Auto-recall ONLY select dropdowns from Memory (NOT text inputs — avoids stale form data)
        document.querySelectorAll('select').forEach(function(el) {
            if (el.name) {
                const mem = localStorage.getItem('otis_pref_' + el.name);
                if (mem !== null && mem !== '') {
                    let ok = Array.from(el.options).some(function(o) { return o.value == mem; });
                    if (ok) el.value = mem;
                }
            }
        });
    }

};
