/**
 * نظام المزامنة الأوفلاين
 * يدعم: IndexedDB + Sync Queue + Auto Sync
 */

class OfflineSync {
    constructor() {
        this.dbName = 'lab_lims_offline';
        this.dbVersion = 1;
        this.db = null;
        this.syncInProgress = false;
        this.syncInterval = null;
        this.csrfToken = this.resolveCsrfToken();
        
        this.init();
    }

    resolveCsrfToken() {
        const meta = document.querySelector('meta[name="csrf-token"]');
        return (window.APP_CSRF_TOKEN || (meta ? meta.getAttribute('content') : '') || '').trim();
    }
    
    async init() {
        try {
            this.db = await this.openDB();
            this.setupSyncListener();
            this.startAutoSync();
            this.updateConnectionStatus();
        } catch (error) {
            console.error('خطأ في تهيئة نظام الأوفلاين:', error);
        }
    }
    
    openDB() {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open(this.dbName, this.dbVersion);
            
            request.onerror = () => reject(request.error);
            request.onsuccess = () => resolve(request.result);
            
            request.onupgradeneeded = (event) => {
                const db = event.target.result;
                
                // جدول البيانات المرجعية
                if (!db.objectStoreNames.contains('reference_data')) {
                    const refStore = db.createObjectStore('reference_data', { keyPath: 'type' });
                }
                
                // جدول قائمة الانتظار للمزامنة
                if (!db.objectStoreNames.contains('sync_queue')) {
                    const queueStore = db.createObjectStore('sync_queue', { keyPath: 'id', autoIncrement: true });
                    queueStore.createIndex('type', 'type', { unique: false });
                    queueStore.createIndex('status', 'status', { unique: false });
                    queueStore.createIndex('created_at', 'created_at', { unique: false });
                }
                
                // جدول البيانات المحلية المؤقتة
                if (!db.objectStoreNames.contains('local_data')) {
                    const localStore = db.createObjectStore('local_data', { keyPath: 'key' });
                }
            };
        });
    }
    
    // حفظ البيانات المرجعية
    async saveReferenceData(data) {
        const tx = this.db.transaction(['reference_data'], 'readwrite');
        const store = tx.objectStore('reference_data');
        
        await store.put({ type: 'all', data: data, updated_at: Date.now() });
    }
    
    // جلب البيانات المرجعية
    async getReferenceData() {
        const tx = this.db.transaction(['reference_data'], 'readonly');
        const store = tx.objectStore('reference_data');
        const result = await store.get('all');
        return result ? result.data : null;
    }
    
    // إضافة عنصر لقائمة الانتظار
    async addToSyncQueue(type, data, tempId = null) {
        const tx = this.db.transaction(['sync_queue'], 'readwrite');
        const store = tx.objectStore('sync_queue');
        
        const item = {
            type: type, // 'patient', 'order', 'result'
            data: data,
            temp_id: tempId,
            status: 'pending',
            created_at: Date.now(),
            retry_count: 0
        };
        
        await store.add(item);
        this.updateQueueBadge();
        
        // محاولة مزامنة فورية إذا كان الاتصال متاحاً
        if (navigator.onLine) {
            this.syncQueue();
        }
        
        return item;
    }
    
    // جلب عناصر قائمة الانتظار
    async getSyncQueue(status = 'pending') {
        return new Promise((resolve, reject) => {
            const tx = this.db.transaction(['sync_queue'], 'readonly');
            const store = tx.objectStore('sync_queue');
            const index = store.index('status');
            const request = index.getAll(status);
            
            request.onsuccess = () => resolve(request.result || []);
            request.onerror = () => reject(request.error);
        });
    }
    
    // مزامنة قائمة الانتظار
    async syncQueue() {
        if (this.syncInProgress || !navigator.onLine) {
            return;
        }
        
        this.syncInProgress = true;
        const pending = await this.getSyncQueue('pending');
        
        if (pending.length === 0) {
            this.syncInProgress = false;
            this.updateQueueBadge();
            return;
        }
        
        // تجميع العناصر حسب النوع
        const grouped = {};
        pending.forEach(item => {
            if (!grouped[item.type]) {
                grouped[item.type] = [];
            }
            grouped[item.type].push(item);
        });
        
        // مزامنة كل نوع
        for (const [type, items] of Object.entries(grouped)) {
            try {
                await this.syncType(type, items);
            } catch (error) {
                console.error(`خطأ في مزامنة ${type}:`, error);
            }
        }
        
        this.syncInProgress = false;
        this.updateQueueBadge();
    }
    
    // مزامنة نوع معين
    async syncType(type, items) {
        const actionMap = {
            'patient': 'sync_patients',
            'order': 'sync_orders',
            'result': 'sync_results'
        };
        
        const action = actionMap[type];
        if (!action) return;
        
        const payload = items.map(item => ({
            ...item.data,
            temp_id: item.temp_id
        }));
        
        try {
            const payloadBody = { [type + 's']: payload };
            if (this.csrfToken) {
                payloadBody._csrf = this.csrfToken;
            }
            const response = await fetch(`api/offline_sync.php?action=${action}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-Token': this.csrfToken
                },
                body: JSON.stringify(payloadBody)
            });
            
            const result = await response.json();
            
            if (result.success) {
                // تحديث حالة العناصر كمكتملة
                const tx = this.db.transaction(['sync_queue'], 'readwrite');
                const store = tx.objectStore('sync_queue');
                
                items.forEach(item => {
                    store.delete(item.id);
                });
                
                // حفظ البيانات المرجعية المحدثة
                if (type === 'patient' || type === 'order') {
                    await this.refreshReferenceData();
                }
                
                // إظهار إشعار نجاح
                this.showNotification(`تمت مزامنة ${items.length} ${this.getTypeName(type)} بنجاح`, 'success');
            } else {
                throw new Error(result.error || 'خطأ في المزامنة');
            }
        } catch (error) {
            // زيادة عدد المحاولات
            const tx = this.db.transaction(['sync_queue'], 'readwrite');
            const store = tx.objectStore('sync_queue');
            
            for (const item of items) {
                const updated = await new Promise((resolve) => {
                    const getReq = store.get(item.id);
                    getReq.onsuccess = () => {
                        const data = getReq.result;
                        data.retry_count = (data.retry_count || 0) + 1;
                        data.status = data.retry_count >= 5 ? 'failed' : 'pending';
                        const putReq = store.put(data);
                        putReq.onsuccess = () => resolve(data);
                    };
                });
            }
            
            throw error;
        }
    }
    
    // تحديث البيانات المرجعية من السيرفر
    async refreshReferenceData() {
        if (!navigator.onLine) return;
        
        try {
            const response = await fetch('api/offline_sync.php?action=get_reference_data');
            const result = await response.json();
            
            if (result.success) {
                await this.saveReferenceData(result.data);
            }
        } catch (error) {
            console.error('خطأ في تحديث البيانات المرجعية:', error);
        }
    }
    
    // إعداد مستمع الاتصال
    setupSyncListener() {
        window.addEventListener('online', () => {
            this.updateConnectionStatus();
            this.syncQueue();
            this.refreshReferenceData();
        });
        
        window.addEventListener('offline', () => {
            this.updateConnectionStatus();
        });
    }
    
    // بدء المزامنة التلقائية
    startAutoSync() {
        // مزامنة كل 30 ثانية عند وجود اتصال
        this.syncInterval = setInterval(() => {
            if (navigator.onLine && !this.syncInProgress) {
                this.syncQueue();
            }
        }, 30000);
    }
    
    // تحديث حالة الاتصال في الواجهة
    updateConnectionStatus() {
        const isOnline = navigator.onLine;
        const statusEl = document.getElementById('offline-status');
        
        if (statusEl) {
            statusEl.className = isOnline ? 'online' : 'offline';
            statusEl.textContent = isOnline ? '🟢 متصل' : '🔴 أوفلاين';
        }
        
        // تحديث badge قائمة الانتظار
        this.updateQueueBadge();
    }
    
    // تحديث badge قائمة الانتظار
    async updateQueueBadge() {
        const pending = await this.getSyncQueue('pending');
        const badgeEl = document.getElementById('sync-queue-badge');
        
        if (badgeEl) {
            if (pending.length > 0) {
                badgeEl.textContent = pending.length;
                badgeEl.style.display = 'inline-block';
            } else {
                badgeEl.style.display = 'none';
            }
        }
    }
    
    // إظهار إشعار
    showNotification(message, type = 'info') {
        // إنشاء عنصر الإشعار
        const notification = document.createElement('div');
        notification.className = `offline-notification ${type}`;
        notification.textContent = message;
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: ${type === 'success' ? '#10b981' : '#ef4444'};
            color: white;
            padding: 12px 24px;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            z-index: 10000;
            font-size: 14px;
        `;
        
        document.body.appendChild(notification);
        
        setTimeout(() => {
            notification.style.opacity = '0';
            notification.style.transition = 'opacity 0.3s';
            setTimeout(() => notification.remove(), 300);
        }, 3000);
    }
    
    getTypeName(type) {
        const names = {
            'patient': 'مريض',
            'order': 'طلب',
            'result': 'نتيجة'
        };
        return names[type] || type;
    }
    
    // دالة مساعدة: إنشاء مريض أوفلاين
    async createPatientOffline(patientData) {
        const tempId = 'temp_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        await this.addToSyncQueue('patient', patientData, tempId);
        return tempId;
    }
    
    // دالة مساعدة: إنشاء طلب أوفلاين
    async createOrderOffline(orderData) {
        const tempId = 'temp_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        await this.addToSyncQueue('order', orderData, tempId);
        return tempId;
    }
    
    // دالة مساعدة: حفظ نتيجة أوفلاين
    async saveResultOffline(resultData) {
        const tempId = 'temp_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        await this.addToSyncQueue('result', resultData, tempId);
        return tempId;
    }
}

// تهيئة النظام عند تحميل الصفحة
let offlineSync;
if (typeof window !== 'undefined') {
    window.addEventListener('DOMContentLoaded', () => {
        offlineSync = new OfflineSync();
        window.offlineSync = offlineSync; // للوصول من الكود الخارجي
    });
}
