// Loading Overlay Functions
var map, infoWindow, directionsService;
var currentLang = "ar"; // اللغة الافتراضية

/**
 * Enhanced Loading Overlay with smooth animations
 */
function showLoading(message = 'جاري التحميل...') {
  const overlay = document.getElementById('loadingOverlay');
  const loadingText = document.getElementById('loadingText');
  if (overlay) {
    overlay.style.display = 'flex';
    if (loadingText) {
      loadingText.textContent = message;
      loadingText.style.animation = 'fadeInOverlay 0.3s ease';
    }
    // Smooth fade-in animation
    requestAnimationFrame(() => {
      overlay.style.opacity = '0';
      overlay.style.transition = 'opacity 0.3s ease';
      requestAnimationFrame(() => {
        overlay.style.opacity = '1';
      });
    });
  }
}

/**
 * Enhanced hide loading with smooth fade-out
 */
function hideLoading() {
  const overlay = document.getElementById('loadingOverlay');
  if (overlay) {
    overlay.style.opacity = '0';
    overlay.style.transition = 'opacity 0.3s ease';
    setTimeout(() => {
      overlay.style.display = 'none';
    }, 300);
  }
}

function updateLoadingText(message) {
  const loadingText = document.getElementById('loadingText');
  if (loadingText) loadingText.textContent = message;
}

/** محاولة تحليل نص كـ JSON (مع إزالة BOM والمسافات) - للتعامل مع استجابة السيرفر */
function safeParseJson(text) {
  if (typeof text !== 'string') return null;
  const trimmed = text.replace(/^\s+|\s+$/g, '').replace(/^\uFEFF/, '');
  try { return JSON.parse(trimmed); } catch (e) { return null; }
}

// Call hideLoading when page resources are fully loaded
window.addEventListener('load', hideLoading);

// إضافة مستمع لحدث تغيير التاريخ لإظهار/إخفاء عناصر التحكم بالوقت
document.addEventListener('DOMContentLoaded', () => {
    const dateSelect = document.getElementById('dateSelect');
    if (dateSelect) {
        dateSelect.addEventListener('change', () => {
            document.getElementById('timeControls').style.display = dateSelect.value ? 'flex' : 'none'; // إظهار/إخفاء عناصر التحكم بالوقت
        });
    }
});

// تم تعطيل التحقق التلقائي من الأجهزة الجديدة لتجنب إعادة تحميل الصفحة المستمرة
// يمكن تحديث قائمة الأجهزة يدوياً عبر تحديث الصفحة
//************************************************
//                    CONSTANTS & ICONS
//************************************************

// أنماط الخرائط المخصصة
const darkMapStyle = [ // نمط الخريطة الداكن
    { elementType: "geometry", stylers: [{ color: "#242f3e" }] },
    { elementType: "labels.text.stroke", stylers: [{ color: "#242f3e" }] },
    { elementType: "labels.text.fill", stylers: [{ color: "#746855" }] },
    { featureType: "administrative.locality", elementType: "labels.text.fill", stylers: [{ color: "#d59563" }] },
    { featureType: "poi", elementType: "labels.text.fill", stylers: [{ color: "#d59563" }] },
    { featureType: "poi.park", elementType: "geometry", stylers: [{ color: "#263c3f" }] },
    { featureType: "poi.park", elementType: "labels.text.fill", stylers: [{ color: "#6b9a76" }] },
    { featureType: "road", elementType: "geometry", stylers: [{ color: "#38414e" }] },
    { featureType: "road", elementType: "geometry.stroke", stylers: [{ color: "#212a37" }] },
    { featureType: "road", elementType: "labels.text.fill", stylers: [{ color: "#9ca5b3" }] },
    { featureType: "road.highway", elementType: "geometry", stylers: [{ color: "#746855" }] },
    { featureType: "road.highway", elementType: "geometry.stroke", stylers: [{ color: "#1f2835" }] },
    { featureType: "road.highway", elementType: "labels.text.fill", stylers: [{ color: "#f3d19c" }] },
    { featureType: "transit", elementType: "geometry", stylers: [{ color: "#2f3948" }] },
    { featureType: "transit.station", elementType: "labels.text.fill", stylers: [{ color: "#d59563" }] },
    { featureType: "water", elementType: "geometry", stylers: [{ color: "#17263c" }] },
    { featureType: "water", elementType: "labels.text.fill", stylers: [{ color: "#515c6d" }] },
    { featureType: "water", elementType: "labels.text.stroke", stylers: [{ color: "#17263c" }] },
];

var trafficLayer = null; // طبقة حركة المرور

// معالج فشل مصادقة خرائط Google (مثل قيود المفتاح/المصدر)
// يتم استدعاؤها تلقائياً بواسطة Google Maps API في حالة وجود خطأ
window.gm_authFailure = function() {
    try {
        const errorMsg = `
⚠️ خطأ في تحميل خرائط Google

الأسباب المحتملة:
1. مفتاح API غير صالح أو منتهي الصلاحية
2. قيود النطاق (Domain Restrictions) لا تتطابق مع هذا الموقع
3. لم يتم تفعيل واجهات برمجة التطبيقات المطلوبة:
   - Maps JavaScript API
   - Geocoding API
   - Places API
4. مشكلة في الفوترة (Billing) في Google Cloud Console

الحلول:
1. تحقق من مفتاح API في ملف config.php
2. تأكد من تفعيل جميع واجهات برمجة التطبيقات المطلوبة
3. تحقق من قيود النطاق في Google Cloud Console
4. تأكد من تفعيل الفوترة في المشروع
        `;
        alert(errorMsg);
        
        // إظهار رسالة على الصفحة
        const mapContainer = document.getElementById('map');
        if (mapContainer) {
            mapContainer.innerHTML = `
                <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; background: #f5f5f5; padding: 20px; text-align: center; direction: rtl;">
                    <div style="font-size: 48px; margin-bottom: 20px;">⚠️</div>
                    <h2 style="color: #d32f2f; margin-bottom: 15px;">تعذّر تحميل خرائط Google</h2>
                    <div style="color: #666; max-width: 600px; line-height: 1.8; margin-bottom: 20px;">
                        <p><strong>الأسباب المحتملة:</strong></p>
                        <ul style="text-align: right; list-style-position: inside;">
                            <li>مفتاح API غير صالح أو منتهي الصلاحية</li>
                            <li>قيود النطاق (Domain Restrictions) لا تتطابق مع هذا الموقع</li>
                            <li>لم يتم تفعيل واجهات برمجة التطبيقات المطلوبة</li>
                            <li>مشكلة في الفوترة (Billing) في Google Cloud Console</li>
                        </ul>
                        <p style="margin-top: 20px;"><strong>الحلول:</strong></p>
                        <ol style="text-align: right; list-style-position: inside;">
                            <li>تحقق من مفتاح API في ملف config.php</li>
                            <li>تأكد من تفعيل جميع واجهات برمجة التطبيقات المطلوبة</li>
                            <li>تحقق من قيود النطاق في Google Cloud Console</li>
                            <li>تأكد من تفعيل الفوترة في المشروع</li>
                        </ol>
                    </div>
                    <a href="https://console.cloud.google.com/google/maps-apis" target="_blank" 
                       style="padding: 10px 20px; background: #4285F4; color: white; text-decoration: none; border-radius: 4px; margin-top: 10px;">
                        فتح Google Cloud Console
                    </a>
                </div>
            `;
        }
    } catch (e) {
        console.error('Error in gm_authFailure:', e);
    }
};

// رصد أخطاء تحميل سكربت خرائط Google
window.addEventListener('error', function(e) {
    try {
        if (e && e.filename && e.filename.includes('maps.googleapis.com')) {
            console.error('Google Maps API loading error:', e);
            const errorMsg = 'تعذّر تحميل مكتبة خرائط Google. تحقّق من الاتصال وصلاحية المفتاح.';
            alert(errorMsg);
            
            // إظهار رسالة على الصفحة
            const mapContainer = document.getElementById('map');
            if (mapContainer && !mapContainer.querySelector('div[style*="flex-direction"]')) {
                mapContainer.innerHTML = `
                    <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; background: #f5f5f5; padding: 20px; text-align: center; direction: rtl;">
                        <div style="font-size: 48px; margin-bottom: 20px;">❌</div>
                        <h2 style="color: #d32f2f; margin-bottom: 15px;">خطأ في تحميل خرائط Google</h2>
                        <p style="color: #666;">تحقق من الاتصال بالإنترنت وصلاحية مفتاح API</p>
                    </div>
                `;
            }
        }
    } catch (err) {
        console.error('Error in error handler:', err);
    }
});

// فحص تحميل Google Maps API بعد فترة زمنية
setTimeout(function() {
    if (typeof google === 'undefined' || typeof google.maps === 'undefined') {
        console.error('Google Maps API failed to load after timeout');
        const mapContainer = document.getElementById('map');
        if (mapContainer && !mapContainer.querySelector('div[style*="flex-direction"]')) {
            mapContainer.innerHTML = `
                <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; background: #f5f5f5; padding: 20px; text-align: center; direction: rtl;">
                    <div style="font-size: 48px; margin-bottom: 20px;">⏱️</div>
                    <h2 style="color: #d32f2f; margin-bottom: 15px;">انتهت مهلة تحميل خرائط Google</h2>
                    <p style="color: #666;">يرجى تحديث الصفحة أو التحقق من مفتاح API</p>
                </div>
            `;
        }
    }
}, 10000); // 10 ثواني

//---------------------------------------------------
// مجموعة متغيرات عامة
//---------------------------------------------------
var markers  = []; // لتخزين جميع علامات الخريطة
var circles  = []; // لتخزين الدوائر (إذا استخدمت)
var polylines = []; // لتخزين جميع خطوط المسار
var logs     = []; // لتخزين بيانات المخطط الزمني
var markerCounter = 1; // عداد لأسماء العلامات (قد لا يكون ضرورياً الآن)
var latestMarker  = null; // علامة آخر موقع مباشر
var latestLocationTimer = null; // مؤقت تحديث آخر موقع مباشر
var lastTimestamp = null; // آخر طابع زمني تم جلبه
var stopMarkersIndex = new Map(); // فهرس سريع لعلامات التوقف حسب الإحداثيات
var userInteractedWithMap = false; // لتتبع ما إذا كان المستخدم قام بتحريك الخريطة يدوياً

// مسار محاذٍ للطريق: علم لتحديد توفره لتجنّب ازدواجية الرسم
var snappedRouteAvailable = false;

// للأنيميشن
var animationMarker = null;
var animationTimeout = null;
var currentAnimationIndex = 0;
var animationIsPlaying = false;
var routeCoordinates = [];
var analyticsGroups  = [];
var animationPrepared = false;
var animationLabel = null;

// تخزين مؤقت للمسارات الذكية
var routeCache = new Map(); // كاش لنتائج Google Directions API
var pendingRoutes = new Set(); // لتتبع طلبات Directions API المعلقة

// أيقونات - سيتم تهيئتها بعد تحميل Google Maps API
var parkIcon, hiddenIcon, startIcon, endIcon, latestIcon;

// دالة لتهيئة الأيقونات بعد تحميل Google Maps
function initializeMapIcons() {
    if (typeof google === 'undefined' || typeof google.maps === 'undefined') {
        console.warn('⚠️ Google Maps API غير محمّل بعد، سيتم إعادة المحاولة...');
        setTimeout(initializeMapIcons, 100);
        return;
    }
    
    parkIcon = {
        url: 'https://almanara.space/gps_tracker/uploads/image.png', // أيقونة التوقف
        scaledSize: new google.maps.Size(32, 32),
        anchor: new google.maps.Point(16, 32)
    };
    hiddenIcon = {
        url: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=', // أيقونة شفافة (لإخفاء العلامات)
        scaledSize: new google.maps.Size(1, 1),
    };
    startIcon = {
        url: 'https://almanara.space/gps_tracker/uploads/start.png', // أيقونة نقطة البداية
        scaledSize: new google.maps.Size(60, 60),
        anchor: new google.maps.Point(16, 32)
    };
    endIcon = {
        url: 'https://almanara.space/gps_tracker/uploads/end.png', // أيقونة نقطة النهاية
        scaledSize: new google.maps.Size(60, 60),
        anchor: new google.maps.Point(16, 32)
    };
    latestIcon = {
        url: 'https://cdn-icons-png.flaticon.com/512/684/684908.png',
        scaledSize: new google.maps.Size(32, 32),
        anchor: new google.maps.Point(16, 32)
    };
    
    console.log('✅ تم تهيئة أيقونات الخريطة');
}

// محاولة تهيئة الأيقونات فوراً (إذا كان Google Maps محمّل)
if (typeof google !== 'undefined' && typeof google.maps !== 'undefined') {
    initializeMapIcons();
} else {
    // إضافة مستمع لتهيئة الأيقونات عند تحميل Google Maps
    window.addEventListener('load', function() {
        setTimeout(initializeMapIcons, 500);
    });
}

// ====================================================================================
// إعدادات التصنيف (Classification Settings)
// ====================================================================================
// هذا القسم يحتوي على جميع الدوال المتعلقة بإعدادات تصنيف النشاط (توقف/قيادة)
// يتم استخدام هذه الإعدادات لتحديد ما إذا كان الجهاز متوقفاً أم في حالة قيادة
// بناءً على معايير محددة: المدة، المسافة، السرعة، والانتشار الجغرافي
// ====================================================================================

/**
 * الحصول على إعدادات العتبات (Thresholds) من التخزين المحلي
 * 
 * @description
 * هذه الدالة تجلب إعدادات التصنيف من localStorage وتعيد القيم الافتراضية
 * في حالة عدم وجود إعدادات محفوظة أو حدوث خطأ في القراءة.
 * 
 * @returns {Object} كائن يحتوي على جميع إعدادات العتبات:
 *   - stopMinDurationMin: أقل مدة للتوقف بالدقائق (افتراضي: 5)
 *   - stationaryThresholdM: أقصى انتشار للتوقف بالمتر (افتراضي: 30)
 *   - stopMaxSpeedKmh: أقصى سرعة للتوقف بالكم/ساعة (افتراضي: 4)
 *   - drivingMinSpeedKmh: أدنى سرعة للقيادة بالكم/ساعة (افتراضي: 7)
 *   - drivingMinSegmentMin: أقل مدة قيادة بالدقائق (افتراضي: 2)
 *   - drivingMinDistanceM: أقل مسافة قيادة بالمتر (افتراضي: 120)
 * 
 * @example
 * const config = getThresholdsConfig();
 * console.log(config.stopMinDurationMin); // 5
 */
function getThresholdsConfig() {
  try {
    // محاولة قراءة الإعدادات من التخزين المحلي
    const raw = localStorage.getItem('trackingThresholds');
    
    // تحليل البيانات من JSON إلى كائن JavaScript
    const cfg = raw ? JSON.parse(raw) : {};
    
    // إرجاع الإعدادات مع القيم الافتراضية في حالة عدم وجود قيمة محفوظة
    return {
      // ========== إعدادات التوقف (Stop Settings) ==========
      /**
       * أقل مدة للتوقف (بالدقائق)
       * المدة الدنيا التي يجب أن يبقى فيها الجهاز في نفس المكان
       * ليتم تصنيفه كـ "توقف" بدلاً من "تحرك"
       * القيمة الافتراضية: 5 دقائق
       */
      stopMinDurationMin: cfg.stopMinDurationMin ?? 5,
      
      /**
       * أقصى انتشار للتوقف (بالمتر)
       * الحد الأقصى للمسافة التي يمكن أن يتحركها الجهاز من نقطة المركز
       * ليتم اعتباره لا يزال في حالة توقف
       * القيمة الافتراضية: 30 متر
       */
      stationaryThresholdM: cfg.stationaryThresholdM ?? 30,
      
      /**
       * أقصى سرعة للتوقف (بالكم/ساعة)
       * السرعة القصوى التي يمكن أن يتحرك بها الجهاز
       * ليتم اعتباره لا يزال في حالة توقف
       * القيمة الافتراضية: 4 كم/ساعة
       */
      stopMaxSpeedKmh: cfg.stopMaxSpeedKmh ?? 4,
      
      // ========== إعدادات القيادة (Driving Settings) ==========
      /**
       * أدنى سرعة للقيادة (بالكم/ساعة)
       * السرعة الدنيا التي يجب أن يتحرك بها الجهاز
       * ليتم تصنيفه كـ "قيادة" بدلاً من "توقف"
       * القيمة الافتراضية: 7 كم/ساعة
       */
      drivingMinSpeedKmh: cfg.drivingMinSpeedKmh ?? 7,
      
      /**
       * أقل مدة قيادة (بالدقائق)
       * المدة الدنيا التي يجب أن يستمر فيها الجهاز في الحركة
       * ليتم اعتبارها "قطعة قيادة" صالحة
       * القيمة الافتراضية: 2 دقيقة
       */
      drivingMinSegmentMin: cfg.drivingMinSegmentMin ?? 2,
      
      /**
       * أقل مسافة قيادة (بالمتر)
       * المسافة الدنيا التي يجب أن يقطعها الجهاز
       * ليتم اعتبارها "قطعة قيادة" صالحة
       * القيمة الافتراضية: 120 متر
       */
      drivingMinDistanceM: cfg.drivingMinDistanceM ?? 120
    };
  } catch (e) {
    // في حالة حدوث خطأ في قراءة أو تحليل البيانات
    // إرجاع القيم الافتراضية مع تسجيل الخطأ في وحدة التحكم
    console.error('❌ خطأ في قراءة إعدادات التصنيف من localStorage:', e);
    
    // إرجاع القيم الافتراضية
    return {
      stopMinDurationMin: 5,
      stationaryThresholdM: 30,
      stopMaxSpeedKmh: 4,
      drivingMinSpeedKmh: 7,
      drivingMinSegmentMin: 2,
      drivingMinDistanceM: 120
    };
  }
}

/**
 * تطبيق إعدادات العتبات على واجهة المستخدم
 * 
 * @description
 * هذه الدالة تقرأ الإعدادات المحفوظة وتطبقها على حقول الإدخال في نموذج الإعدادات.
 * يتم استدعاؤها عند فتح لوحة الإعدادات لضمان عرض القيم الحالية.
 * 
 * @returns {void}
 * 
 * @example
 * applyThresholdsToUI(); // يملأ جميع حقول الإدخال بالقيم المحفوظة
 */
function applyThresholdsToUI() {
  try {
    // الحصول على الإعدادات الحالية
    const config = getThresholdsConfig();
    
    // دالة مساعدة للحصول على عنصر HTML بواسطة المعرف
    const byId = (id) => document.getElementById(id);
    
    // تطبيق القيم على حقول الإدخال (مع التحقق من وجود العنصر)
    // ========== إعدادات التوقف ==========
    const stopMinDurationInput = byId('th_stopMinDuration');
    if (stopMinDurationInput) {
      stopMinDurationInput.value = config.stopMinDurationMin;
    }
    
    const stationaryThresholdInput = byId('th_stationaryThreshold');
    if (stationaryThresholdInput) {
      stationaryThresholdInput.value = config.stationaryThresholdM;
    }
    
    const stopMaxSpeedInput = byId('th_stopMaxSpeed');
    if (stopMaxSpeedInput) {
      stopMaxSpeedInput.value = config.stopMaxSpeedKmh;
    }
    
    // ========== إعدادات القيادة ==========
    const drivingMinSpeedInput = byId('th_drivingMinSpeed');
    if (drivingMinSpeedInput) {
      drivingMinSpeedInput.value = config.drivingMinSpeedKmh;
    }
    
    const drivingMinSegmentInput = byId('th_drivingMinSegment');
    if (drivingMinSegmentInput) {
      drivingMinSegmentInput.value = config.drivingMinSegmentMin;
    }
    
    const drivingMinDistanceInput = byId('th_drivingMinDistance');
    if (drivingMinDistanceInput) {
      drivingMinDistanceInput.value = config.drivingMinDistanceM;
    }
    
    console.log('✅ تم تطبيق إعدادات التصنيف على واجهة المستخدم');
  } catch (error) {
    console.error('❌ خطأ في تطبيق إعدادات التصنيف على واجهة المستخدم:', error);
    showToast('⚠️ حدث خطأ في تحميل الإعدادات');
  }
}

/**
 * التحقق من صحة قيمة الإدخال
 * 
 * @description
 * دالة مساعدة للتحقق من أن القيمة المدخلة صالحة (رقم موجب)
 * 
 * @param {string|number} value - القيمة المراد التحقق منها
 * @param {number} defaultValue - القيمة الافتراضية في حالة عدم الصلاحية
 * @param {number} minValue - القيمة الدنيا المسموحة (افتراضي: 0)
 * @param {number} maxValue - القيمة القصوى المسموحة (افتراضي: Infinity)
 * @returns {number} القيمة الصالحة
 * 
 * @example
 * validateInput('5.5', 5, 0, 100); // 5.5
 * validateInput('-10', 5, 0, 100); // 5 (القيمة الافتراضية)
 */
function validateThresholdInput(value, defaultValue, minValue = 0, maxValue = Infinity) {
  // تحويل القيمة إلى رقم
  const numValue = parseFloat(value);
  
  // التحقق من أن القيمة رقم صالح وموجب
  if (isNaN(numValue) || numValue < minValue || numValue > maxValue) {
    return defaultValue;
  }
  
  return numValue;
}

/**
 * حفظ إعدادات العتبات من واجهة المستخدم
 * 
 * @description
 * هذه الدالة تقرأ القيم من حقول الإدخال في نموذج الإعدادات،
 * تتحقق من صحتها، ثم تحفظها في localStorage.
 * بعد الحفظ، يتم إعادة بناء المخطط الزمني والخريطة بالإعدادات الجديدة.
 * 
 * @returns {void}
 * 
 * @example
 * saveThresholdsFromUI(); // يحفظ الإعدادات ويطبقها
 */
function saveThresholdsFromUI() {
  try {
    // دالة مساعدة للحصول على عنصر HTML بواسطة المعرف
    const byId = (id) => document.getElementById(id);
    
    // قراءة القيم من حقول الإدخال مع التحقق من الصحة
    // ========== إعدادات التوقف ==========
    const stopMinDuration = validateThresholdInput(
      byId('th_stopMinDuration')?.value,
      5,      // القيمة الافتراضية
      0.1,    // الحد الأدنى: 0.1 دقيقة
      1440    // الحد الأقصى: 1440 دقيقة (24 ساعة)
    );
    
    const stationaryThreshold = validateThresholdInput(
      byId('th_stationaryThreshold')?.value,
      30,     // القيمة الافتراضية
      1,      // الحد الأدنى: 1 متر
      10000   // الحد الأقصى: 10000 متر (10 كم)
    );
    
    const stopMaxSpeed = validateThresholdInput(
      byId('th_stopMaxSpeed')?.value,
      4,      // القيمة الافتراضية
      0,      // الحد الأدنى: 0 كم/ساعة
      200     // الحد الأقصى: 200 كم/ساعة
    );
    
    // ========== إعدادات القيادة ==========
    const drivingMinSpeed = validateThresholdInput(
      byId('th_drivingMinSpeed')?.value,
      7,      // القيمة الافتراضية
      0,      // الحد الأدنى: 0 كم/ساعة
      300     // الحد الأقصى: 300 كم/ساعة
    );
    
    const drivingMinSegment = validateThresholdInput(
      byId('th_drivingMinSegment')?.value,
      2,      // القيمة الافتراضية
      0.1,    // الحد الأدنى: 0.1 دقيقة
      1440    // الحد الأقصى: 1440 دقيقة (24 ساعة)
    );
    
    const drivingMinDistance = validateThresholdInput(
      byId('th_drivingMinDistance')?.value,
      120,    // القيمة الافتراضية
      1,      // الحد الأدنى: 1 متر
      100000  // الحد الأقصى: 100000 متر (100 كم)
    );
    
    // إنشاء كائن الإعدادات
    const config = {
      stopMinDurationMin: stopMinDuration,
      stationaryThresholdM: stationaryThreshold,
      stopMaxSpeedKmh: stopMaxSpeed,
      drivingMinSpeedKmh: drivingMinSpeed,
      drivingMinSegmentMin: drivingMinSegment,
      drivingMinDistanceM: drivingMinDistance
    };
    
    // حفظ الإعدادات في localStorage
    localStorage.setItem('trackingThresholds', JSON.stringify(config));
    
    // إظهار رسالة نجاح
    showToast('✅ تم حفظ الإعدادات وتطبيقها بنجاح');
    
    console.log('✅ تم حفظ إعدادات التصنيف:', config);
    
    // إعادة بناء المخطط الزمني والخريطة بالإعدادات الجديدة
    // نتحقق من وجود البيانات المطلوبة قبل الاستدعاء لتجنب خطأ 400
    try {
      // التحقق من وجود جهاز محدد وتاريخ قبل محاولة جلب البيانات
      const deviceSelect = document.getElementById('deviceSelect');
      const dateSelect = document.getElementById('dateSelect');
      
      if (deviceSelect && dateSelect) {
        const deviceId = deviceSelect.value;
        const date = dateSelect.value;
        
        // فقط إذا كان هناك جهاز محدد وتاريخ محدد، نعيد جلب البيانات
        if (deviceId && date) {
          if (typeof fetchTimelineAndRoute === 'function') {
            fetchTimelineAndRoute();
          } else if (typeof fetchLocations === 'function') {
            fetchLocations();
          }
        } else {
          // إذا لم تكن هناك بيانات محددة، نخبر المستخدم أنه يمكنه البحث يدوياً
          console.log('ℹ️ لم يتم إعادة جلب البيانات تلقائياً - يرجى اختيار جهاز وتاريخ ثم الضغط على زر البحث');
        }
      }
    } catch (fetchError) {
      console.warn('⚠️ لم يتم إعادة بناء البيانات تلقائياً:', fetchError);
      // لا نعرض خطأ للمستخدم لأن الحفظ نجح
    }
    
  } catch (error) {
    // في حالة حدوث خطأ غير متوقع
    console.error('❌ خطأ في حفظ إعدادات التصنيف:', error);
    showToast('❌ حدث خطأ في حفظ الإعدادات. يرجى المحاولة مرة أخرى.');
  }
}

/**
 * إعادة تعيين إعدادات التصنيف إلى القيم الافتراضية
 * 
 * @description
 * هذه الدالة تحذف الإعدادات المحفوظة وتعيد القيم الافتراضية.
 * بعد إعادة التعيين، يتم تحديث واجهة المستخدم وإعادة بناء البيانات.
 * 
 * @returns {void}
 * 
 * @example
 * resetThresholdsToDefault(); // يعيد الإعدادات إلى القيم الافتراضية
 */
function resetThresholdsToDefault() {
  try {
    // التحقق من رغبة المستخدم في إعادة التعيين
    const confirmMessage = 'هل أنت متأكد من إعادة تعيين جميع إعدادات التصنيف إلى القيم الافتراضية؟';
    if (!confirm(confirmMessage)) {
      return; // إلغاء العملية إذا لم يؤكد المستخدم
    }
    
    // حذف الإعدادات المحفوظة من localStorage
    localStorage.removeItem('trackingThresholds');
    
    // تحديث واجهة المستخدم بالقيم الافتراضية
    applyThresholdsToUI();
    
    // إظهار رسالة نجاح
    showToast('✅ تم إعادة تعيين الإعدادات إلى القيم الافتراضية');
    
    console.log('✅ تم إعادة تعيين إعدادات التصنيف إلى القيم الافتراضية');
    
    // ملاحظة: لا نعيد جلب البيانات تلقائياً لأن:
    // 1. قد لا يكون المستخدم قد اختار جهازاً أو تاريخاً بعد
    // 2. دالة fetchTimelineAndRoute() تحتاج معاملات محددة (device_id, date, etc.)
    // 3. المستخدم يمكنه الضغط على زر "بحث" يدوياً لتطبيق الإعدادات الجديدة
    // إذا كانت هناك بيانات معروضة حالياً، يمكن للمستخدم إعادة البحث لتطبيق الإعدادات الجديدة
    
  } catch (error) {
    console.error('❌ خطأ في إعادة تعيين إعدادات التصنيف:', error);
    showToast('❌ حدث خطأ في إعادة تعيين الإعدادات. يرجى المحاولة مرة أخرى.');
  }
}

/**
 * تبديل عرض/إخفاء لوحة إعدادات التصنيف
 * 
 * @description
 * هذه الدالة تتحكم في إظهار وإخفاء لوحة إعدادات التصنيف.
 * عند فتح اللوحة، يتم تحميل الإعدادات الحالية وتطبيقها على الحقول.
 * 
 * @returns {void}
 * 
 * @example
 * toggleThresholdSettings(); // يفتح أو يغلق لوحة الإعدادات
 */
function toggleThresholdSettings() {
  try {
    // الحصول على عنصر لوحة الإعدادات
    const settingsPanel = document.getElementById('thresholdSettingsPanel');
    
    // التحقق من وجود اللوحة
    if (!settingsPanel) {
      console.error('❌ لم يتم العثور على لوحة إعدادات التصنيف');
      return;
    }
    
    // التحقق من حالة العرض الحالية
    const isHidden = settingsPanel.style.display === 'none' || 
                     settingsPanel.style.display === '' ||
                     !settingsPanel.style.display;
    
    if (isHidden) {
      // فتح اللوحة: تحميل الإعدادات الحالية وتطبيقها على الحقول
      applyThresholdsToUI();
      settingsPanel.style.display = 'flex';
      
      // إضافة تأثير بسيط للفتح (اختياري)
      settingsPanel.style.opacity = '0';
      setTimeout(() => {
        settingsPanel.style.opacity = '1';
        settingsPanel.style.transition = 'opacity 0.3s ease-in-out';
      }, 10);
      
      console.log('✅ تم فتح لوحة إعدادات التصنيف');
    } else {
      // إغلاق اللوحة
      settingsPanel.style.display = 'none';
      console.log('✅ تم إغلاق لوحة إعدادات التصنيف');
    }
  } catch (error) {
    console.error('❌ خطأ في تبديل لوحة إعدادات التصنيف:', error);
    showToast('⚠️ حدث خطأ في فتح/إغلاق الإعدادات');
  }
}

/**
 * إظهار/إخفاء القائمة الجانبية (للموبايل)
 */
function toggleSidebar() {
    const sidebar = document.getElementById('sidebar');
    const overlay = document.getElementById('sidebarOverlay');
    const toggleBtn = document.getElementById('sidebarToggle');
    const toggleIcon = document.getElementById('sidebarToggleIcon');
    
    if (sidebar) {
        const isOpen = sidebar.classList.contains('mobile-open');
        
        if (isOpen) {
            // إغلاق القائمة
            sidebar.classList.remove('mobile-open');
            if (overlay) overlay.classList.remove('active');
            if (toggleIcon) toggleIcon.textContent = '☰';
            document.body.style.overflow = ''; // إعادة تفعيل التمرير
        } else {
            // فتح القائمة
            sidebar.classList.add('mobile-open');
            if (overlay) overlay.classList.add('active');
            if (toggleIcon) toggleIcon.textContent = '✕';
            document.body.style.overflow = 'hidden'; // منع التمرير عند فتح القائمة
        }
    }
}

// التأكد من أن toggleSidebar متاح في النطاق العام
window.toggleSidebar = toggleSidebar;

/**
 * إغلاق القائمة عند النقر خارجها (للاستخدام المستقبلي)
 */
function closeSidebarOnOutsideClick(event) {
    const sidebar = document.getElementById('sidebar');
    const toggleBtn = document.getElementById('sidebarToggle');
    
    if (sidebar && toggleBtn && 
        !sidebar.contains(event.target) && 
        !toggleBtn.contains(event.target)) {
        toggleSidebar();
    }
}

function toggleTimelineSidebar() {
  const sidebar = document.querySelector('.timeline-sidebar');
  const toggleBtn = document.getElementById('timelineToggleBtn');
  const controlsToggleBtn = document.getElementById('btnToggleTimeline');
  if (!sidebar) return;
  
  const isCollapsed = sidebar.classList.contains('collapsed');
  sidebar.classList.toggle('collapsed');
  const nowCollapsed = sidebar.classList.contains('collapsed');
  
  // تحديث الزر داخل المخطط الزمني (إن كان مرئياً)
  if (toggleBtn) {
    if (nowCollapsed) {
      toggleBtn.textContent = '►';
      toggleBtn.title = 'إظهار المخطط الزمني';
    } else {
      toggleBtn.textContent = '◄';
      toggleBtn.title = 'إخفاء المخطط الزمني';
    }
  }
  
  // تحديث الزر في قسم controls
  if (controlsToggleBtn) {
    if (nowCollapsed) {
      controlsToggleBtn.textContent = '📊 إظهار المخطط';
      controlsToggleBtn.title = 'إظهار المخطط الزمني';
    } else {
      controlsToggleBtn.textContent = '📊 إخفاء المخطط';
      controlsToggleBtn.title = 'إخفاء المخطط الزمني';
    }
  }
}

/**
 * تهيئة أحداث إعدادات التصنيف عند تحميل الصفحة
 * 
 * @description
 * يتم استدعاء هذه الدالة تلقائياً عند تحميل الصفحة (DOMContentLoaded)
 * لتسجيل مستمعات الأحداث على أزرار إعدادات التصنيف
 */
document.addEventListener('DOMContentLoaded', function() {
  // ========== تهيئة زر حفظ الإعدادات ==========
  const saveBtn = document.getElementById('btnSaveThresholds');
  if (saveBtn) {
    saveBtn.addEventListener('click', function(event) {
      event.preventDefault(); // منع السلوك الافتراضي للزر
      saveThresholdsFromUI();
    });
    console.log('✅ تم تسجيل مستمع حدث لزر حفظ إعدادات التصنيف');
  } else {
    console.warn('⚠️ لم يتم العثور على زر حفظ إعدادات التصنيف');
  }
  
  // ========== تهيئة حقول الإدخال للتحقق من الصحة ==========
  // إضافة مستمعات للتحقق من صحة القيم أثناء الكتابة
  const thresholdInputs = [
    'th_stopMinDuration',
    'th_stationaryThreshold',
    'th_stopMaxSpeed',
    'th_drivingMinSpeed',
    'th_drivingMinSegment',
    'th_drivingMinDistance'
  ];
  
  thresholdInputs.forEach(inputId => {
    const input = document.getElementById(inputId);
    if (input) {
      // التحقق من صحة القيمة عند فقدان التركيز (blur)
      input.addEventListener('blur', function() {
        const value = parseFloat(this.value);
        if (isNaN(value) || value < 0) {
          this.style.borderColor = '#f44336'; // لون أحمر للخطأ
          this.title = 'يرجى إدخال قيمة صالحة (رقم موجب)';
        } else {
          this.style.borderColor = ''; // إعادة اللون الافتراضي
          this.title = '';
        }
      });
      
      // إزالة تحذير الخطأ عند البدء بالكتابة
      input.addEventListener('input', function() {
        if (this.style.borderColor === 'rgb(244, 67, 54)') {
          const value = parseFloat(this.value);
          if (!isNaN(value) && value >= 0) {
            this.style.borderColor = '';
            this.title = '';
          }
        }
      });
    }
  });
  
  // ========== تهيئة حالة زر المخطط الزمني في controls ==========
  const sidebar = document.querySelector('.timeline-sidebar');
  const controlsToggleBtn = document.getElementById('btnToggleTimeline');
  if (sidebar && controlsToggleBtn) {
    if (sidebar.classList.contains('collapsed')) {
      controlsToggleBtn.textContent = '📊 إظهار المخطط';
      controlsToggleBtn.title = 'إظهار المخطط الزمني';
    } else {
      controlsToggleBtn.textContent = '📊 إخفاء المخطط';
      controlsToggleBtn.title = 'إخفاء المخطط الزمني';
    }
  }
  
  // مستمع حدث لاختيار الجهاز - جلب آخر قيمة بطارية
  const deviceSelect = document.getElementById('deviceSelect');
  if (deviceSelect) {
    deviceSelect.addEventListener('change', function() {
      const deviceId = this.value;
      if (deviceId) {
        // جلب آخر موقع للجهاز المحدد لعرض البطارية
        fetch(`get_latest_location.php?device_id=${deviceId}&t=${Date.now()}`)
          .then(res => res.text().then(text => {
            if (!res.ok) {
              const err = safeParseJson(text);
              const msg = (err && err.message) ? err.message : `خطأ من السيرفر (${res.status})`;
              throw new Error(msg);
            }
            const data = safeParseJson(text);
            if (data === null) {
              console.warn("Empty or invalid JSON when fetching latest location for battery:", text ? text.substring(0, 200) : "(empty)");
              // اعتبره عدم وجود بيانات حديثة بدلاً من خطأ
              return { status: "error", data: null };
            }
            return data;
          }))
          .then(data => {
            if (data.status === "success" && data.data && data.data.battery !== null && data.data.battery !== undefined) {
              updateBatteryDisplay(data.data.battery);
            } else {
              updateBatteryDisplay(null);
            }
          })
          .catch(() => updateBatteryDisplay(null));
      } else {
        updateBatteryDisplay(null);
      }
    });
  }
});
document.addEventListener('DOMContentLoaded', setupAnimationControls);
// ملاحظة: تم نقل استدعاء initializeMap إلى الـ callback في رابط Google Maps API


//*********************************************
//   دوال UI عامة (Toast رسائل)
//*********************************************
function updateBatteryDisplay(battery) {
  const batteryDisplay = document.getElementById('batteryDisplay');
  if (!batteryDisplay) return;
  
  if (battery !== null && battery !== undefined && !isNaN(battery)) {
    const batteryIcon = battery > 80 ? '🔋' : (battery > 20 ? '🪫' : '🔌');
    batteryDisplay.value = `${batteryIcon} ${battery}%`;
    batteryDisplay.style.color = battery > 80 ? '#28a745' : (battery > 20 ? '#ffc107' : '#dc3545');
  } else {
    batteryDisplay.value = '❔ --';
    batteryDisplay.style.color = 'var(--text-secondary)';
  }
}

/**
 * Enhanced Toast Notification System
 * Displays beautiful, accessible toast messages with improved animations
 */
function showToast(message, type = 'info', duration = 3500) {
  const container = document.getElementById("toastContainer");
  if (!container) return;
  
  const toast = document.createElement("div");
  toast.className = `toast toast-${type}`;
  
  // Add icon based on type
  const icons = {
    success: '✅',
    error: '❌',
    warning: '⚠️',
    info: 'ℹ️'
  };
  
  const icon = icons[type] || icons.info;
  toast.innerHTML = `<span class="toast-icon">${icon}</span><span class="toast-message">${message}</span>`;
  
  container.appendChild(toast);
  
  // Trigger animation
  requestAnimationFrame(() => {
    toast.style.animation = 'fadein 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
  });
  
  // Auto-remove after duration
  setTimeout(() => {
    if (container.contains(toast)) {
      toast.style.animation = 'fadeout 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards';
      setTimeout(() => {
        if (container.contains(toast)) {
          container.removeChild(toast);
        }
      }, 400);
    }
  }, duration);
}

// ===================================================
// Favorite Places Modal Functions
// ===================================================
function openFavoritePlaceModal(latLng) {
    const modal = document.getElementById('favoritePlaceModal');
    if (!modal) return;

    // تعبئة الإحداثيات في الحقول المخفية
    document.getElementById('placeLat').value = latLng.lat();
    document.getElementById('placeLng').value = latLng.lng();

    // إعادة تعيين الحقول الأخرى
    document.getElementById('placeName').value = ''; // مسح الاسم
    document.getElementById('placeRadius').value = '100';

    modal.style.display = 'flex';
    document.getElementById('placeName').focus();
}

function closeFavoritePlaceModal() {
    const modal = document.getElementById('favoritePlaceModal');
    if (modal) {
        modal.style.display = 'none';
    }
}

async function saveFavoritePlace() {
    const placeName = document.getElementById('placeName').value;
    const radius = document.getElementById('placeRadius').value;
    const lat = document.getElementById('placeLat').value;
    const lng = document.getElementById('placeLng').value; // جلب الإحداثيات

    if (!placeName.trim()) {
        showToast('❌ يرجى إدخال اسم للمكان.');
        return;
    }

    showLoading('جاري حفظ المكان...');

    try {
        const response = await fetch('add_user_place.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ place_name: placeName, latitude: lat, longitude: lng, radius: radius })
        });

        if (!response.ok) {
            const errorText = await response.text();
            console.error('Server error response:', errorText);
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const text = await response.text();
        let result;
        try {
            result = JSON.parse(text);
        } catch (e) {
            console.error('Failed to parse JSON:', text);
            throw new Error('Invalid JSON response');
        }
        hideLoading();

        if (response.ok && result.status === 'success') {
            showToast('✅ ' + result.message);
            closeFavoritePlaceModal();
            fetchLocations(); // إعادة جلب البيانات لتعكس التغيير فوراً (لتظهر في المخطط الزمني)
        } else {
            showToast('❌ ' + (result.message || 'حدث خطأ غير متوقع.'));
        }
    } catch (error) {
        hideLoading();
        showToast('❌ خطأ في الاتصال بالخادم.');
        console.error('Save favorite place error:', error);
    }
}

//----------------------------------------------------
//   تغيير طبقة الخريطة (Map Style)
//----------------------------------------------------
function changeMapStyle() { // تغيير نمط الخريطة
  var styleSelect = document.getElementById("mapStyleSelect");
  var styleValue = styleSelect.value;
  localStorage.setItem('preferredMapStyle', styleValue);

  // إزالة طبقة حركة المرور القديمة إذا كانت موجودة
  if (trafficLayer) {
      trafficLayer.setMap(null);
  }

  map.setOptions({ styles: null }); // إعادة تعيين الأنماط المخصصة

  if (styleValue === "satellite") {
      map.setMapTypeId(google.maps.MapTypeId.SATELLITE);
  } else if (styleValue === "dark") {
      map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
      map.setOptions({ styles: darkMapStyle });
  } else if (styleValue === "traffic") {
      map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
      trafficLayer = new google.maps.TrafficLayer();
      trafficLayer.setMap(map);
  } else {
      map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
  }
}

// استعادة تفضيلات المستخدم من localStorage عند تحميل الصفحة (نمط الخريطة)
document.addEventListener('DOMContentLoaded', function() {
  var savedStyle = localStorage.getItem('preferredMapStyle');
  const mapStyleSelect = document.getElementById("mapStyleSelect");
  if (savedStyle && mapStyleSelect) {
    mapStyleSelect.value = savedStyle;
    changeMapStyle(); // Apply the saved style
  }
});


//----------------------------------------------------
// دوال تنظيف الخريطة والبيانات
//----------------------------------------------------
function clearMap() { // مسح جميع العناصر من الخريطة
  markers.forEach(m => m.setMap(null));
  markers = [];
  stopMarkersIndex.clear();
  circles.forEach(c => c.setMap(null));
  circles = [];
  polylines.forEach(p => p.setMap(null));
  polylines = [];
  if (latestMarker) {
    latestMarker.setMap(null);
    latestMarker = null;
  }
  if (animationMarker) {
    animationMarker.setMap(null);
    animationMarker = null;
  }
  animationIsPlaying = false;
  if (latestLocationTimer) {
    clearInterval(latestLocationTimer);
    latestLocationTimer = null;
  }
  if (animationTimeout) {
    clearTimeout(animationTimeout);
    animationTimeout = null;
  }
  logs = [];
  markerCounter = 1;
  routeCoordinates = [];
  analyticsGroups  = [];
  lastTimestamp    = null;
  animationPrepared = false;
  hideAnimationLabel();
  updateAnimationAvailability(false);

  updateLogsTable(); // تحديث جدول السجلات
  hideLoading(); // Hide loading after clearing
}

function resetFilters() {
  const deviceSelect = document.getElementById("deviceSelect");
  const dateSelect = document.getElementById("dateSelect");
  const timeFrom = document.getElementById("timeFrom");
  const timeTo = document.getElementById("timeTo");
  const selectedDeviceName = document.getElementById("selectedDeviceName");

  if(deviceSelect) deviceSelect.value = "";
  if(dateSelect) dateSelect.value   = ""; // مسح التاريخ
  if(timeFrom) timeFrom.value     = "";
  if(timeTo) timeTo.value       = "";
  if(selectedDeviceName) selectedDeviceName.textContent = "لا يوجد جهاز محدد";
  updateBatteryDisplay(null); // مسح حقل البطارية

  clearMap(); // This will also hide loading
  showToast("تمت إعادة تعيين الفلاتر");
}

//----------------------------------------------------
// دوال جلب البيانات
//----------------------------------------------------
async function fetchTimelineAndRoute() {
  showLoading('جاري جلب البيانات...');
  clearMap();
  const deviceSel = document.getElementById("deviceSelect");
  if (!deviceSel) { hideLoading(); return; }

  var deviceId  = deviceSel.value;
  var deviceName = (deviceSel.selectedIndex >= 0 && deviceSel.options[deviceSel.selectedIndex])
                   ? deviceSel.options[deviceSel.selectedIndex].text
                   : "غير محدد";

  const selectedDeviceNameEl = document.getElementById("selectedDeviceName");
  if (selectedDeviceNameEl) selectedDeviceNameEl.textContent = deviceName;

  // جلب التاريخ والوقت من عناصر التحكم
  const date = document.getElementById("dateSelect")?.value || "";
  const timeFrom = document.getElementById("timeFrom") ? convertTo24Hour(document.getElementById("timeFrom").value.trim()) : "";
  const timeTo = document.getElementById("timeTo") ? convertTo24Hour(document.getElementById("timeTo").value.trim()) : "";

  const payload = {
    device_id: deviceId,
    date: date,
    from_date: timeFrom ? `${date} ${timeFrom}` : null,
    to_date: timeTo ? `${date} ${timeTo}` : null,
    config: getThresholdsConfig()
  };

  try {
    const response = await fetch('get_timeline_and_route.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });

    const text = await response.text();
    if (!response.ok) {
      const err = safeParseJson(text);
      const msg = (err && err.message) ? err.message : `خطأ من السيرفر (${response.status})`;
      console.error('Server error response:', text ? text.substring(0, 400) : '(empty)');
      throw new Error(msg);
    }

    let result = safeParseJson(text);
    if (result === null) {
      console.error('Failed to parse JSON (get_timeline_and_route):', text ? text.substring(0, 200) : '(empty)');
      throw new Error('استجابة غير صالحة من السيرفر - تأكد من أن التوقفات والمسار من MySQL (phpMyAdmin)');
    }

    hideLoading();

    if (result.status !== 'success') {
      showToast(`⚠️ ${result.message || 'حدث خطأ غير متوقع'}`);
      return;
    }

    logs = result.timeline || [];
    analyticsGroups = result.timeline || []; // استخدام نفس البيانات للتحليلات

    if (logs.length === 0) {
      showToast(result.meta?.message || "لا توجد بيانات ضمن الشروط المحددة.");
      return;
    }

    showToast(`تم جلب ${result.meta?.raw_points || 'بعض'} نقطة وتحليلها.`);

    // عرض المخطط الزمني
    updateLogsTable();

    // عرض المسار على الخريطة
    const routeAvailable = (
      result.route &&
      result.route.geometry &&
      Array.isArray(result.route.geometry.coordinates) &&
      result.route.geometry.coordinates.length >= 2
    );

    // ✅ استخدام النقاط الفعلية من قاعدة البيانات مع الأوقات الصحيحة
    let routePoints = [];
    
    if (result.route_points && Array.isArray(result.route_points) && result.route_points.length > 0) {
      // ✅ استخدام النقاط الفعلية من الخادم (مع الأوقات الصحيحة من قاعدة البيانات)
      routePoints = result.route_points
        .map(point => ({
          lat: parseFloat(point.lat),
          lng: parseFloat(point.lng),
          time: point.time || null // ✅ الوقت الفعلي من قاعدة البيانات
        }))
        .filter(p => !isNaN(p.lat) && !isNaN(p.lng) && p.time) // ✅ التأكد من وجود وقت
        .sort((a, b) => {
          // ✅ ترتيب حسب الوقت
          if (a.time && b.time) {
            try {
              return new Date(a.time) - new Date(b.time);
            } catch (e) {
              return 0;
            }
          }
          return 0;
        });
    } else {
      // ✅ احتياطي: بناء من timeline إذا لم تكن route_points متوفرة
      (logs || []).forEach((l) => {
        const lat = parseFloat(l.lat);
        const lng = parseFloat(l.lng);
        if (isNaN(lat) || isNaN(lng)) return;
        
        if (l.entryTime) {
          routePoints.push({ lat, lng, time: l.entryTime });
        }
        if (l.exitTime && l.exitTime !== l.entryTime) {
          routePoints.push({ lat, lng, time: l.exitTime });
        }
      });
      
      routePoints.sort((a, b) => {
        if (a.time && b.time) {
          try {
            return new Date(a.time) - new Date(b.time);
          } catch (e) {
            return 0;
          }
        }
        return 0;
      });
    }

    let animationPath = [];

    if (routeAvailable && routePoints.length > 0) {
      // المسار القادم من الخادم (Mapbox/raw)
      drawRoute(result.route);
      const routeCoords = (result.route.geometry.coordinates || [])
        .map(coord => ({ lat: parseFloat(coord[1]), lng: parseFloat(coord[0]) }))
        .filter(pt => !isNaN(pt.lat) && !isNaN(pt.lng));
      
      // ✅ ربط نقاط المسار بأوقات من routePoints الأصلية (النقاط الفعلية من قاعدة البيانات)
      animationPath = routeCoords.map((coord, idx) => {
        // ✅ استخدام الاستيفاء الزمني الخطي بناءً على موضع النقطة في المسار
        // بدلاً من البحث عن أقرب نقطة (أكثر دقة)
        const ratio = idx / Math.max(1, routeCoords.length - 1);
        const timeIndex = ratio * (routePoints.length - 1);
        const lowerIndex = Math.floor(timeIndex);
        const upperIndex = Math.min(Math.ceil(timeIndex), routePoints.length - 1);
        const fraction = timeIndex - lowerIndex;
        
        let time = null;
        
        if (lowerIndex === upperIndex || fraction === 0) {
          // ✅ استخدام الوقت من النقطة الأقرب مباشرة
          time = routePoints[lowerIndex]?.time || null;
        } else if (routePoints[lowerIndex]?.time && routePoints[upperIndex]?.time) {
          // ✅ استيفاء زمني خطي بين النقطتين
          try {
            const lowerTime = new Date(routePoints[lowerIndex].time);
            const upperTime = new Date(routePoints[upperIndex].time);
            
            if (!isNaN(lowerTime.getTime()) && !isNaN(upperTime.getTime())) {
              const interpolatedTime = lowerTime.getTime() + (upperTime.getTime() - lowerTime.getTime()) * fraction;
              time = toSqlDateTime(new Date(interpolatedTime));
            } else {
              time = routePoints[lowerIndex].time;
            }
          } catch (e) {
            time = routePoints[lowerIndex].time;
          }
        } else {
          time = routePoints[lowerIndex]?.time || routePoints[upperIndex]?.time || null;
        }
        
        return {
          lat: coord.lat,
          lng: coord.lng,
          time: time
        };
      });
    } else if (routePoints.length >= 2) {
      // fallback: حاول رسم المسار الذكي أولاً ثم ارجع للخطوط المباشرة
      try {
        await drawIntelligentRoute(routePoints, analyticsGroups);
      } catch (e) {
        console.warn('تعذّر رسم المسار الذكي، سيتم استخدام خط مستقيم:', e);
        drawFallbackRoute(routePoints, analyticsGroups);
      }
      animationPath = routePoints;
    } else {
      showToast('لا توجد نقاط كافية لرسم المسار.');
    }

    // عرض نقاط البداية والنهاية والتوقفات
    displayMarkers(logs);

    prepareRouteAnimation(animationPath, logs);

    // تحديث قسم التحليلات

  } catch (error) {
    hideLoading();
    console.error("Fetch error:", error);
    showToast("⚠️ خطأ في الاتصال بالخادم: " + error.message);
  }
}

function drawRoute(routeData) {
    if (!routeData || !routeData.geometry || !Array.isArray(routeData.geometry.coordinates) || routeData.geometry.coordinates.length < 2) {
        console.warn('لا توجد بيانات مسار كافية للرسم.');
        return;
    }

    const path = routeData.geometry.coordinates.map(coord => ({ lat: parseFloat(coord[1]), lng: parseFloat(coord[0]) }))
        .filter(p => !isNaN(p.lat) && !isNaN(p.lng)); // ✅ تصفية النقاط غير الصالحة

    if (path.length < 2) {
        console.warn('لا توجد نقاط صالحة كافية للرسم.');
        return;
    }

    // ✅ تحسين: استخدام geodesic: true لرسم مسار منحني على الكرة الأرضية (مهم في الاستدارات)
    const routePolyline = new google.maps.Polyline({
        path,
        geodesic: true, // ✅ مهم جداً: يجعل الخط يتبع منحنى الأرض بدلاً من خط مستقيم
        strokeColor: routeData.provider === 'mapbox' ? '#1976D2' : '#FF0000', // أزرق لـ Mapbox، أحمر للخام
        strokeOpacity: 0.9,
        strokeWeight: 5,
        map: map
    });
    polylines.push(routePolyline);

    const bounds = new google.maps.LatLngBounds();
    path.forEach(p => bounds.extend(p));
    if (!bounds.isEmpty()) {
        map.fitBounds(bounds);
    }
}

function displayMarkers(timeline) {
    if (timeline.length === 0) return;

    stopMarkersIndex.clear();

    // نقطة البداية
    const startLog = timeline[0];
    const startMarker = new google.maps.Marker({
        position: { lat: startLog.lat, lng: startLog.lng },
        map: map,
        icon: startIcon,
        title: `بداية المسار: ${formatTo12Hour(startLog.entryTime)}`
    });
    markers.push(startMarker);

    // نقطة النهاية
    const endLog = timeline[timeline.length - 1];
    const endMarker = new google.maps.Marker({
        position: { lat: endLog.lat, lng: endLog.lng },
        map: map,
        icon: endIcon,
        title: `نهاية المسار: ${formatTo12Hour(endLog.exitTime)}`
    });
    markers.push(endMarker);

    // نقاط التوقف
    const cfg = getThresholdsConfig();
    timeline.forEach(log => {
        if (log.type === 'stop' && log.duration >= cfg.stopMinDurationMin) {
            const stopMarker = new google.maps.Marker({
                position: { lat: log.lat, lng: log.lng },
                map: map,
                icon: parkIcon,
                title: log.place_name
            });
            
            // تنسيق أوقات الدخول والخروج
            const enterStr = log.entryTime ? formatTimeOnly12Hour(log.entryTime) : '';
            const exitStr = log.exitTime ? formatTimeOnly12Hour(log.exitTime) : '';
            const enterFullTime = log.entryTime || '';
            const exitFullTime = log.exitTime || '';
            
            const content = `
                <div style="direction: rtl; text-align: right; min-width: 240px; padding: 4px;">
                    <b style="font-size: 15px; color: #1e293b; display: block; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid #e2e8f0;">${htmlspecialchars(log.place_name)}</b>
                    <div style="margin-top: 8px;">
                        ${enterStr ? `
                            <div style="
                                display: flex;
                                align-items: center;
                                justify-content: space-between;
                                margin-bottom: 8px;
                                padding: 6px 8px;
                                background: rgba(33, 150, 243, 0.05);
                                border-radius: 6px;
                                border-right: 3px solid #2196F3;
                            ">
                                <div style="display: flex; align-items: center; gap: 6px; flex: 1;">
                                    <span style="font-size: 16px;">⏰</span>
                                    <span style="color: #64748b; font-size: 13px;">دخول:</span>
                                    <span style="font-weight: 600; color: #2196F3; font-size: 14px;">${enterStr}</span>
                                </div>
                                <button 
                                    onclick="copyStopTime('${htmlspecialchars(enterFullTime)}', '${htmlspecialchars(enterStr)}', 'دخول')"
                                    style="
                                        background: rgba(33, 150, 243, 0.1);
                                        border: 1px solid rgba(33, 150, 243, 0.3);
                                        color: #2196F3;
                                        border-radius: 5px;
                                        padding: 4px 8px;
                                        cursor: pointer;
                                        font-size: 13px;
                                        display: flex;
                                        align-items: center;
                                        justify-content: center;
                                        transition: all 0.2s ease;
                                        min-width: 32px;
                                        height: 28px;
                                        margin-right: 4px;
                                    "
                                    onmouseover="this.style.background='rgba(33, 150, 243, 0.2)'; this.style.borderColor='rgba(33, 150, 243, 0.5)'; this.style.transform='scale(1.05)';"
                                    onmouseout="this.style.background='rgba(33, 150, 243, 0.1)'; this.style.borderColor='rgba(33, 150, 243, 0.3)'; this.style.transform='scale(1)';"
                                    title="نسخ وقت الدخول"
                                >
                                    📋
                                </button>
                            </div>
                        ` : ''}
                        ${exitStr ? `
                            <div style="
                                display: flex;
                                align-items: center;
                                justify-content: space-between;
                                margin-bottom: 8px;
                                padding: 6px 8px;
                                background: rgba(244, 67, 54, 0.05);
                                border-radius: 6px;
                                border-right: 3px solid #F44336;
                            ">
                                <div style="display: flex; align-items: center; gap: 6px; flex: 1;">
                                    <span style="font-size: 16px;">⏰</span>
                                    <span style="color: #64748b; font-size: 13px;">خروج:</span>
                                    <span style="font-weight: 600; color: #F44336; font-size: 14px;">${exitStr}</span>
                                </div>
                                <button 
                                    onclick="copyStopTime('${htmlspecialchars(exitFullTime)}', '${htmlspecialchars(exitStr)}', 'خروج')"
                                    style="
                                        background: rgba(244, 67, 54, 0.1);
                                        border: 1px solid rgba(244, 67, 54, 0.3);
                                        color: #F44336;
                                        border-radius: 5px;
                                        padding: 4px 8px;
                                        cursor: pointer;
                                        font-size: 13px;
                                        display: flex;
                                        align-items: center;
                                        justify-content: center;
                                        transition: all 0.2s ease;
                                        min-width: 32px;
                                        height: 28px;
                                        margin-right: 4px;
                                    "
                                    onmouseover="this.style.background='rgba(244, 67, 54, 0.2)'; this.style.borderColor='rgba(244, 67, 54, 0.5)'; this.style.transform='scale(1.05)';"
                                    onmouseout="this.style.background='rgba(244, 67, 54, 0.1)'; this.style.borderColor='rgba(244, 67, 54, 0.3)'; this.style.transform='scale(1)';"
                                    title="نسخ وقت الخروج"
                                >
                                    📋
                                </button>
                            </div>
                        ` : ''}
                        <div style="
                            margin-top: 8px;
                            padding: 6px 8px;
                            background: rgba(76, 175, 80, 0.05);
                            border-radius: 6px;
                            border-right: 3px solid #4CAF50;
                            display: flex;
                            align-items: center;
                            gap: 6px;
                        ">
                            <span style="font-size: 16px;">⏱️</span>
                            <span style="color: #64748b; font-size: 13px;">المدة:</span>
                            <span style="font-weight: 600; color: #4CAF50; font-size: 14px;">${formatDuration(log.duration)}</span>
                        </div>
                    </div>
                </div>
            `;
            stopMarker.addListener('click', () => { infoWindow.setContent(content); infoWindow.open(map, stopMarker); });
            markers.push(stopMarker);

            const key = buildCoordinateKey(log.lat, log.lng);
            if (key) {
                stopMarkersIndex.set(key, { marker: stopMarker, content });
            }
        }
    });
}

// جلب آخر موقع مباشر
function fetchLatestLocation() { // جلب آخر موقع مباشر
  showLoading('جاري جلب آخر موقع مباشر...');
  var deviceSel = document.getElementById("deviceSelect");
  if (!deviceSel) { hideLoading(); return; }
  var deviceId  = deviceSel.value;

  if (!deviceId) {
    showToast("⚠️ يرجى اختيار جهاز لجلب أحدث موقع");
    hideLoading();
    return;
  }

  if (latestLocationTimer) {
    clearInterval(latestLocationTimer);
  }

  // إعادة تفعيل التمركز التلقائي عند بدء جلب جديد
  // عندما يضغط المستخدم على زر "جلب آخر موقع مباشر" مرة أخرى، يعود التمركز التلقائي للعمل
  userInteractedWithMap = false;

  function getLatest() { // دالة جلب آخر موقع من السيرفر (MySQL/phpMyAdmin)
    fetch(`get_latest_location.php?device_id=${deviceId}&t=${Date.now()}`)
      .then(res => res.text().then(text => {
        if (!res.ok) {
          const err = safeParseJson(text);
          const msg = (err && err.message) ? err.message : `خطأ من السيرفر (${res.status})`;
          console.error('Server error response:', text ? text.substring(0, 300) : '(empty)');
          throw new Error(msg);
        }
        const data = safeParseJson(text);
        if (data === null) {
          console.warn("Empty or invalid JSON when fetching latest live location:", text ? text.substring(0, 200) : "(empty)");
          // اعتبره عدم وجود موقع حديث بدلاً من خطأ تقني
          return { status: "error", data: null, message: "لم يتم العثور على موقع حديث من السيرفر." };
        }
        return data;
      }))
      .then(data => {
        hideLoading();
        if (data.status === "success" && data.data) {
          var lat       = parseFloat(data.data.latitude);
          var lng       = parseFloat(data.data.longitude);
          var timestamp = data.data.timestamp;
          var battery   = data.data.battery;
          var deviceName = data.data.device_name || "الجهاز المحدد";

          const selectedDeviceNameEl = document.getElementById("selectedDeviceName");
          if (selectedDeviceNameEl) selectedDeviceNameEl.textContent = deviceName;

          // تحديث حقل البطارية
          updateBatteryDisplay(battery);

          // تحديث أو إنشاء علامة آخر موقع
          if (!isNaN(lat) && !isNaN(lng)) {
            if (!latestMarker) {
                latestMarker = new google.maps.Marker({
                position: { lat: lat, lng: lng },
                map: map,
                icon: latestIcon
            });
            } else {
                latestMarker.setPosition({ lat: lat, lng: lng });
            }

            const batteryIcon = battery ? (battery > 80 ? '🔋' : (battery > 20 ? '🪫' : '🔌')) : '❔'; // أيقونة البطارية
            const batteryText = battery ? `${battery}%` : 'غير معروف';
            const content = `
                <div style="font-family: 'Segoe UI', sans-serif; font-size: 13px; color: #333; min-width: 210px; padding: 5px; text-align: right;">
                    <h4 style="margin: 0 0 8px 0; padding-bottom: 4px; border-bottom: 1px solid #eee; color: #007bff;">
                        📡 ${htmlspecialchars(deviceName)}
                    </h4>
                    <table style="width: 100%; border-spacing: 0 4px;">
                        <tr>
                            <td style="width: 20px;">🕒</td>
                            <td>${formatTo12Hour(timestamp)}</td>
                        </tr>
                        <tr>
                            <td style="width: 20px;">${batteryIcon}</td>
                            <td>${batteryText}</td>
                        </tr>
                    </table>
                    <div style="margin-top: 10px; padding-top: 8px; border-top: 1px solid #eee; text-align: center;">
                        <a href="https://www.google.com/maps/dir/?api=1&destination=${lat},${lng}" target="_blank"
                           style="display: inline-block; padding: 6px 12px; background-color: #007bff; color: white; text-decoration: none; border-radius: 5px; font-size: 12px; font-weight: bold;">
                           افتح في خرائط جوجل
                        </a>
                    </div>
                </div>`;
            infoWindow.setContent(content);
            infoWindow.open(map, latestMarker);
            
            // فقط تمركز الخريطة إذا لم يقم المستخدم بتحريكها يدوياً
            // هذا يمنع إعادة التمركز التلقائي عندما يحاول المستخدم استكشاف الخريطة
            if (!userInteractedWithMap) {
                map.setCenter({ lat: lat, lng: lng });
                map.setZoom(15);
            }

            lastTimestamp = timestamp;
          } else {
             showToast("⚠️ بيانات الموقع غير صالحة.");
          }
        } else {
            showToast(data.message || "⚠️ لم يتم العثور على موقع حديث.");
        }
      })
      .catch(err => {
        console.error("خطأ في جلب الموقع:", err);
        showToast("⚠️ خطأ: " + err.message);
        hideLoading();
      });
  }

  getLatest();
  // تم تعطيل التحديث التلقائي - التحديث فقط عند الضغط على زر "آخر موقع"
  // latestLocationTimer = setInterval(getLatest, 10000);
}

//----------------------------------------------------
//   واجهة التحكم بالحركة (أنيميشن)
//----------------------------------------------------
function setupAnimationControls() {
  const playBtn = document.getElementById('animationPlayPause');
  const resetBtn = document.getElementById('animationReset');
  const speedRange = document.getElementById('animationSpeedRange');
  const progressRange = document.getElementById('animationProgressRange');

  if (playBtn) {
    playBtn.addEventListener('click', () => {
      if (playBtn.disabled) return;
      const panel = document.getElementById('animationPanel');
      const state = panel ? panel.getAttribute('data-state') : 'disabled';
      if (state === 'playing') {
        stopAnimation();
      } else {
        playAnimation();
      }
    });
  }

  if (resetBtn) {
    resetBtn.addEventListener('click', () => {
      if (!resetBtn.disabled) {
        resetAnimationToStart();
      }
    });
  }

  if (speedRange) {
    speedRange.addEventListener('input', updateAnimationSpeedLabel);
    updateAnimationSpeedLabel();
  }

  if (progressRange) {
    progressRange.addEventListener('input', onAnimationProgressChange);
  }

  updateAnimationAvailability(false);
}

function updateAnimationAvailability(enabled) {
  const panel = document.getElementById('animationPanel');
  const playBtn = document.getElementById('animationPlayPause');
  const resetBtn = document.getElementById('animationReset');
  const speedRange = document.getElementById('animationSpeedRange');
  const progressRange = document.getElementById('animationProgressRange');

  animationPrepared = !!enabled;

  if (panel) {
    panel.classList.toggle('is-disabled', !enabled);
    if (!enabled) {
      panel.setAttribute('data-state', 'disabled');
    }
  }

  if (playBtn) playBtn.disabled = !enabled;
  if (resetBtn) resetBtn.disabled = !enabled;
  if (speedRange) speedRange.disabled = !enabled;
  if (progressRange) {
    progressRange.disabled = !enabled;
    if (!enabled) progressRange.value = 0;
  }

  setAnimationState(enabled ? 'ready' : 'disabled');
  if (!enabled) {
    updateAnimationTimeLabel(null);
    hideAnimationLabel();
  }
}

function setAnimationState(state) {
  const panel = document.getElementById('animationPanel');
  const statusEl = document.getElementById('animationStatusLabel');
  const playBtn  = document.getElementById('animationPlayPause');

  if (panel) {
    panel.setAttribute('data-state', state);
  }

  let statusText = 'الحركة غير متاحة';
  let playText   = '▶️ تشغيل';

  switch (state) {
    case 'playing':
      statusText = 'الحركة قيد التشغيل';
      playText = '⏸ إيقاف مؤقت';
      break;
    case 'paused':
      statusText = 'تم الإيقاف مؤقتاً';
      playText = '▶️ استئناف';
      break;
    case 'finished':
      statusText = 'انتهت الحركة';
      playText = '▶️ إعادة التشغيل';
      break;
    case 'ready':
      statusText = 'جاهز للتشغيل';
      playText = '▶️ تشغيل';
      break;
    default:
      statusText = 'الحركة غير متاحة';
      playText = '▶️ تشغيل';
  }

  if (statusEl) statusEl.textContent = statusText;
  if (playBtn) playBtn.textContent = playText;
}

function updateAnimationSpeedLabel() {
  const speedRange = document.getElementById('animationSpeedRange');
  const speedLabel = document.getElementById('animationSpeedLabel');
  if (!speedRange || !speedLabel) return;
  const multiplier = parseFloat(speedRange.value || '1');
  const formatted = Number.isInteger(multiplier) ? multiplier.toString() : multiplier.toFixed(2);
  speedLabel.textContent = `${formatted}x`;
}

/**
 * Get Animation Delay - Enhanced with slower base speed
 * Returns delay in milliseconds between animation steps
 */
function getAnimationDelay() {
  const speedRange = document.getElementById('animationSpeedRange');
  const multiplier = speedRange ? parseFloat(speedRange.value || '1') : 1;
  
  // ✅ Increased base delay for slower, more visible movement
  // Base delay of 2000ms (2 seconds) per point for 1x speed
  const baseDelay = 2000;
  const safeMultiplier = (isFinite(multiplier) && multiplier > 0) ? multiplier : 1;
  
  // Calculate delay: slower multiplier = longer delay
  // At 1x: 2000ms, At 2x: 1000ms, At 0.5x: 4000ms
  const calculatedDelay = Math.round(baseDelay / safeMultiplier);
  
  // Minimum delay of 100ms to prevent too fast movement
  // Maximum delay of 5000ms to prevent too slow movement
  return Math.max(100, Math.min(calculatedDelay, 5000));
}

function updateAnimationTimeLabel(timeValue) {
  const timeEl = document.getElementById('animationTimeLabel');
  if (!timeEl) return;
  timeEl.textContent = timeValue ? formatTimeOnly12Hour(timeValue) : '--:--';
}

function prepareRouteAnimation(pathPoints, timeline) {
  routeCoordinates = [];
  currentAnimationIndex = 0;
  stopAnimation(true);
  hideAnimationLabel();

  if (!Array.isArray(pathPoints) || pathPoints.length === 0) {
    updateAnimationAvailability(false);
    return;
  }

  // ✅ الحفاظ على الأوقات من النقاط الأصلية وترتيبها حسب الوقت
  const sanitizedPoints = pathPoints
    .map(point => ({
      lat: parseFloat(point.lat),
      lng: parseFloat(point.lng),
      time: point.time || null // الحفاظ على الوقت الأصلي
    }))
    .filter(point => !isNaN(point.lat) && !isNaN(point.lng))
    // ✅ ترتيب النقاط حسب الوقت لضمان الاستيفاء الصحيح
    .sort((a, b) => {
      if (a.time && b.time) {
        try {
          const aDate = new Date(a.time);
          const bDate = new Date(b.time);
          if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) {
            return aDate.getTime() - bDate.getTime();
          }
        } catch (e) {
          // تجاهل الأخطاء
        }
      }
      return 0;
    });

  if (!sanitizedPoints.length) {
    updateAnimationAvailability(false);
    return;
  }

  // ✅ استخدام دالة جديدة تحافظ على الأوقات عند إضافة نقاط كثيفة
  const densePoints = densifyRoutePointsWithTime(sanitizedPoints);
  const totalPoints = densePoints.length;

  densePoints.forEach((pt, idx) => {
    routeCoordinates.push({
      lat: pt.lat,
      lng: pt.lng,
      time: pt.time || null, // استخدام الوقت الفعلي من النقطة
      minBattery: null,
      maxBattery: null
    });
  });

  if (!routeCoordinates.length) {
    updateAnimationAvailability(false);
    return;
  }

  updateAnimationAvailability(true);
  updateAnimationTimeLabel(routeCoordinates[0]?.time);
  resetAnimationToStart(true);
  updateAnimationProgressSlider(0, routeCoordinates.length);
}

function getTimelineBounds(timeline) {
  let startTs = Date.now();
  let endTs = startTs + 600000; // افتراضي 10 دقائق

  if (timeline && timeline.length) {
    const firstEntry = timeline[0]?.entryTime || timeline[0]?.time || timeline[0]?.timestamp;
    const lastExit = timeline[timeline.length - 1]?.exitTime || timeline[timeline.length - 1]?.entryTime;

    const firstDate = firstEntry ? new Date(firstEntry.replace(' ', 'T')) : null;
    const lastDate = lastExit ? new Date(lastExit.replace(' ', 'T')) : null;

    if (firstDate && !isNaN(firstDate)) {
      startTs = firstDate.getTime();
    }
    if (lastDate && !isNaN(lastDate)) {
      endTs = lastDate.getTime();
    }
  }

  if (endTs <= startTs) {
    endTs = startTs + 300000; // 5 دقائق احتياطية لتجنب القيم المتساوية
  }

  return { startTs, endTs };
}

function interpolateTimestamp(startTs, endTs, index, total) {
  if (total <= 1) {
    return toSqlDateTime(new Date(startTs));
  }
  const ratio = index / (total - 1);
  const timestamp = startTs + (endTs - startTs) * ratio;
  return toSqlDateTime(new Date(timestamp));
}

/**
 * ربط نقطة الحركة بأقرب وقت حقيقي من المخطط الزمني
 * بحيث تظهر أوقات الأيقونة/الشريط مطابقة للأوقات المخزنة في قاعدة البيانات.
 */
function mapIndexToTimelineTime(pointIndex, totalPoints, timelineTimes) {
  if (!Array.isArray(timelineTimes) || timelineTimes.length === 0) {
    // في حال عدم توفر أوقات في المخطط الزمني، نرجع قيمة تقريبية باستخدام التوقيت الحالي
    return toSqlDateTime(new Date());
  }

  if (totalPoints <= 1 || timelineTimes.length === 1) {
    return timelineTimes[0];
  }

  const ratio = pointIndex / Math.max(1, totalPoints - 1);
  const mappedIndex = Math.round(ratio * (timelineTimes.length - 1));
  const safeIndex = Math.max(0, Math.min(mappedIndex, timelineTimes.length - 1));
  return timelineTimes[safeIndex];
}

function toSqlDateTime(dateObj) {
  if (!(dateObj instanceof Date) || isNaN(dateObj)) {
    return new Date().toISOString();
  }
  const pad = (num) => (num < 10 ? `0${num}` : `${num}`);
  const year = dateObj.getFullYear();
  const month = pad(dateObj.getMonth() + 1);
  const day = pad(dateObj.getDate());
  const hours = pad(dateObj.getHours());
  const minutes = pad(dateObj.getMinutes());
  const seconds = pad(dateObj.getSeconds());
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

function densifyRoutePoints(points, maxStepMeters = 30) {
  if (!Array.isArray(points) || points.length < 2) return points || [];
  const dense = [points[0]];
  for (let i = 0; i < points.length - 1; i++) {
    const start = points[i];
    const end = points[i + 1];
    const distance = haversineDistanceMeters(start.lat, start.lng, end.lat, end.lng);
    const segments = Math.max(1, Math.ceil(distance / maxStepMeters));
    for (let s = 1; s < segments; s++) {
      const ratio = s / segments;
      dense.push({
        lat: start.lat + (end.lat - start.lat) * ratio,
        lng: start.lng + (end.lng - start.lng) * ratio
      });
    }
    dense.push(end);
  }
  return dense;
}

/**
 * ✅ دالة جديدة لإضافة نقاط كثيفة مع الحفاظ على الأوقات
 * تستخدم الاستيفاء الزمني بين النقاط الأصلية
 */
function densifyRoutePointsWithTime(points, maxStepMeters = 30) {
  if (!Array.isArray(points) || points.length < 2) return points || [];
  
  // ✅ التأكد من أن النقاط مرتبة حسب الوقت قبل الاستيفاء
  const sortedPoints = [...points].sort((a, b) => {
    if (a.time && b.time) {
      try {
        const aDate = new Date(a.time);
        const bDate = new Date(b.time);
        if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) {
          return aDate.getTime() - bDate.getTime();
        }
      } catch (e) {
        // تجاهل الأخطاء
      }
    }
    return 0;
  });
  
  const dense = [{ ...sortedPoints[0] }]; // نسخ النقطة الأولى مع وقتها
  
  for (let i = 0; i < sortedPoints.length - 1; i++) {
    const start = sortedPoints[i];
    const end = sortedPoints[i + 1];
    const distance = haversineDistanceMeters(start.lat, start.lng, end.lat, end.lng);
    const segments = Math.max(1, Math.ceil(distance / maxStepMeters));
    
    // ✅ حساب الفرق الزمني بين النقطتين
    let timeDiff = 0;
    
    if (start.time && end.time) {
      try {
        const startDate = new Date(start.time);
        const endDate = new Date(end.time);
        if (!isNaN(startDate.getTime()) && !isNaN(endDate.getTime())) {
          timeDiff = endDate.getTime() - startDate.getTime();
          // ✅ إذا كان الوقت متساوياً أو سالباً، نجعله صفراً (نفس الوقت)
          if (timeDiff < 0) {
            timeDiff = 0;
          }
        }
      } catch (e) {
        // تجاهل خطأ التحويل
        timeDiff = 0;
      }
    }
    
    // إضافة النقاط الكثيفة بين النقطتين
    for (let s = 1; s < segments; s++) {
      const ratio = s / segments;
      const newPoint = {
        lat: start.lat + (end.lat - start.lat) * ratio,
        lng: start.lng + (end.lng - start.lng) * ratio
      };
      
      // ✅ استيفاء الوقت بين النقطتين بشكل خطي
      if (start.time && end.time) {
        try {
          const startDate = new Date(start.time);
          const endDate = new Date(end.time);
          
          if (!isNaN(startDate.getTime()) && !isNaN(endDate.getTime())) {
            // استيفاء خطي للوقت حتى لو كان timeDiff === 0
            const interpolatedTimestamp = startDate.getTime() + (timeDiff * ratio);
            const interpolatedDate = new Date(interpolatedTimestamp);
            newPoint.time = toSqlDateTime(interpolatedDate);
          } else if (!isNaN(startDate.getTime())) {
            // إذا كان startDate صحيحاً لكن endDate غير صحيح، استخدم startDate
            newPoint.time = start.time;
          } else if (!isNaN(endDate.getTime())) {
            // إذا كان endDate صحيحاً لكن startDate غير صحيح، استخدم endDate
            newPoint.time = end.time;
          } else {
            // إذا كانا غير صحيحين، استخدم start.time كاحتياطي
            newPoint.time = start.time;
          }
        } catch (e) {
          // في حالة الخطأ، استخدم وقت البداية
          newPoint.time = start.time || end.time || null;
        }
      } else if (start.time) {
        // إذا كان فقط start.time موجوداً، استخدمه
        newPoint.time = start.time;
      } else if (end.time) {
        // إذا كان فقط end.time موجوداً، استخدمه
        newPoint.time = end.time;
      } else {
        // إذا لم يكن هناك وقت، استخدم null
        newPoint.time = null;
      }
      
      dense.push(newPoint);
    }
    
    // إضافة النقطة النهائية مع وقتها
    dense.push({ ...end });
  }
  
  return dense;
}

function haversineDistanceMeters(lat1, lon1, lat2, lon2) {
  const toRad = (val) => (val * Math.PI) / 180;
  const R = 6371000;
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c;
}

//----------------------------------------------------
//   دوال الحركة (أنيميشن)
//----------------------------------------------------
/**
 * Enhanced Play Animation with smooth start
 */
function playAnimation() {
  if (!animationPrepared || !routeCoordinates.length) {
    showToast("❌ لا يوجد مسار لتشغيل الحركة.", 'error');
    return;
  }
  stopAnimation(true);
  if (currentAnimationIndex >= routeCoordinates.length) {
    currentAnimationIndex = 0; // Restart if at end
  }
  animationIsPlaying = true;
  setAnimationState('playing');
  lastAnimationTime = performance.now();
  currentInterpolationIndex = 0;
  interpolationProgress = 0;
  
  // Start smooth animation
  animateStep();
}

/**
 * Enhanced Stop Animation with cleanup
 */
function stopAnimation(skipStateUpdate = false) {
  if (animationTimeout) {
    clearTimeout(animationTimeout);
    animationTimeout = null;
  }
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId);
    animationFrameId = null;
  }
  // Keep marker visible when paused, just stop movement
  // if (animationMarker) {
  //   animationMarker.setMap(null);
  //   animationMarker = null;
  // }
  animationIsPlaying = false;
  lastAnimationTime = 0;
  currentInterpolationIndex = 0;
  interpolationProgress = 0;
  if (!skipStateUpdate) {
    setAnimationState('paused');
  }
}

/**
 * Enhanced Smooth Animation with Interpolation
 * Uses requestAnimationFrame for smooth 60fps movement
 */
let animationFrameId = null;
let lastAnimationTime = 0;
let currentInterpolationIndex = 0;
let interpolationProgress = 0;

/**
 * Enhanced Smooth Animation with Slower, More Visible Movement
 * Uses proper timing for better visibility
 */
function animateStep() {
  if (currentAnimationIndex >= routeCoordinates.length) {
    stopAnimation(true);
    setAnimationState('finished');
    return;
  }

  const pt = routeCoordinates[currentAnimationIndex];
  const speed = getAnimationDelay();
  
  // Update marker with custom icon
  if (!animationMarker) {
    const icon = createAnimationIcon();
    animationMarker = new google.maps.Marker({
      position: { lat: pt.lat, lng: pt.lng },
      map: map,
      icon: icon || undefined,
      optimized: false,
      zIndex: 1000
    });
  } else {
    // Smooth position update with animation
    const currentPos = animationMarker.getPosition();
    if (currentPos) {
      const currentLat = currentPos.lat();
      const currentLng = currentPos.lng();
      
      // Smooth transition to new position
      const steps = 10; // Number of interpolation steps
      let stepCount = 0;
      
      const smoothMove = () => {
        stepCount++;
        const progress = stepCount / steps;
        const easeProgress = progress < 0.5 
          ? 2 * progress * progress 
          : 1 - Math.pow(-2 * progress + 2, 2) / 2; // Ease-in-out
        
        const interpolatedLat = currentLat + (pt.lat - currentLat) * easeProgress;
        const interpolatedLng = currentLng + (pt.lng - currentLng) * easeProgress;
        
        animationMarker.setPosition({ lat: interpolatedLat, lng: interpolatedLng });
        
        // Smooth pan with easing
        if (map.getCenter()) {
          const currentCenter = map.getCenter();
          const targetLat = interpolatedLat;
          const targetLng = interpolatedLng;
          const smoothLat = currentCenter.lat() + (targetLat - currentCenter.lat()) * 0.15;
          const smoothLng = currentCenter.lng() + (targetLng - currentCenter.lng()) * 0.15;
          map.panTo({ lat: smoothLat, lng: smoothLng });
        }
        
        if (stepCount < steps) {
          requestAnimationFrame(smoothMove);
        } else {
          // Final position
          animationMarker.setPosition({ lat: pt.lat, lng: pt.lng });
          map.panTo({ lat: pt.lat, lng: pt.lng });
        }
      };
      
      // Start smooth movement
      requestAnimationFrame(smoothMove);
    } else {
      animationMarker.setPosition({ lat: pt.lat, lng: pt.lng });
      map.panTo({ lat: pt.lat, lng: pt.lng });
    }
  }
  
  // Update labels
  updateAnimationTimeLabel(pt.time);
  updateAnimationLabel(pt);
  
  currentAnimationIndex++;
  updateAnimationProgressSlider(currentAnimationIndex, routeCoordinates.length);

  if (currentAnimationIndex < routeCoordinates.length) {
    // Use setTimeout with proper delay for slower, more visible movement
    animationTimeout = setTimeout(animateStep, speed);
  } else {
    showToast("🏁 انتهت الحركة", 'success');
    setAnimationState('finished');
  }
}

function resetAnimationToStart(silent = false) {
  stopAnimation(true);
  currentAnimationIndex = 0;
  if (routeCoordinates.length > 0) {
    var pt = routeCoordinates[0];
    if (map && window.google && google.maps) {
      if (!animationMarker) {
        const icon = createAnimationIcon();
        animationMarker = new google.maps.Marker({
          position: { lat: pt.lat, lng: pt.lng },
          map: map,
          icon: icon || undefined, // Use custom icon if available, otherwise default
          optimized: false,
          zIndex: 1000
        });
      } else {
        animationMarker.setPosition({ lat: pt.lat, lng: pt.lng });
      }
      map.panTo({ lat: pt.lat, lng: pt.lng }); // تحريك الخريطة إلى نقطة البداية
    }
    updateAnimationTimeLabel(pt.time);
    setAnimationState('ready');
    updateAnimationProgressSlider(0, routeCoordinates.length);
    if (!silent) showToast("تمت إعادة الحركة إلى نقطة البداية");
  } else {
    updateAnimationAvailability(false);
    if (!silent) showToast("لا يوجد مسار للعودة إلى بدايته.");
  }
}


/**
 * Enhanced Animation Marker with Custom Icon
 * Beautiful animated marker with smooth movement
 */
let animationIconCache = null;

const createAnimationIcon = () => {
  // Return cached icon if available
  if (animationIconCache && window.google && window.google.maps) {
    return animationIconCache;
  }
  
  // Check if Google Maps is loaded
  if (!window.google || !window.google.maps) {
    // Return default marker if Google Maps not loaded yet
    return null;
  }
  
  // Create a beautiful custom SVG icon for the animation marker
  const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
      <defs>
        <linearGradient id="markerGradient" x1="0%" y1="0%" x2="0%" y2="100%">
          <stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
          <stop offset="100%" style="stop-color:#2563eb;stop-opacity:1" />
        </linearGradient>
        <filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
          <feOffset dx="0" dy="2" result="offsetblur"/>
          <feComponentTransfer>
            <feFuncA type="linear" slope="0.3"/>
          </feComponentTransfer>
          <feMerge>
            <feMergeNode/>
            <feMergeNode in="SourceGraphic"/>
          </feMerge>
        </filter>
      </defs>
      <!-- Outer pulse ring -->
      <circle cx="24" cy="24" r="20" fill="rgba(59, 130, 246, 0.2)" opacity="0.6">
        <animate attributeName="r" values="20;24;20" dur="2s" repeatCount="indefinite"/>
        <animate attributeName="opacity" values="0.6;0.2;0.6" dur="2s" repeatCount="indefinite"/>
      </circle>
      <!-- Main marker circle -->
      <circle cx="24" cy="24" r="14" fill="url(#markerGradient)" filter="url(#shadow)"/>
      <!-- Inner highlight -->
      <circle cx="24" cy="24" r="8" fill="rgba(255, 255, 255, 0.4)"/>
      <!-- Center dot -->
      <circle cx="24" cy="24" r="4" fill="#ffffff"/>
      <!-- Direction arrow -->
      <path d="M 24 8 L 20 16 L 24 14 L 28 16 Z" fill="#ffffff" opacity="0.9"/>
    </svg>
  `;
  
  // Cache the icon
  animationIconCache = {
    url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg),
    scaledSize: new google.maps.Size(48, 48),
    anchor: new google.maps.Point(24, 24),
    optimized: false
  };
  
  return animationIconCache;
};

/**
 * Enhanced Animation Label with Beautiful Design
 * Shows time above marker with elegant styling
 */
function updateAnimationLabel(point) {
  if (!map || !point || !window.google || !google.maps) return;
  
  if (!animationLabel) {
    animationLabel = new google.maps.InfoWindow({ 
      disableAutoPan: true,
      pixelOffset: new google.maps.Size(0, -60) // Position above marker
    });
  }
  
  const timeStr = formatTimeOnly12Hour(point.time) || formatTo12Hour(point.time) || '--:--';
  const dateStr = point.time ? formatDateOnly(point.time) : '';
  const fullTimeStr = point.time || '';
  
  // Beautiful label design with gradient and shadow
  const labelHtml = `
    <div style="
      background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
      color: #ffffff;
      padding: 8px 14px;
      border-radius: 12px;
      font-size: 14px;
      font-weight: 600;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.2);
      border: 1px solid rgba(255, 255, 255, 0.1);
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      min-width: 140px;
      text-align: center;
      direction: rtl;
      font-family: 'Segoe UI', 'Roboto', sans-serif;
      position: relative;
    ">
      <!-- Time display with copy button -->
      <div style="
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        margin-bottom: ${dateStr ? '4px' : '0'};
      ">
        <span style="font-size: 16px;">🕒</span>
        <span style="
          font-size: 15px;
          letter-spacing: 0.5px;
          color: #60a5fa;
          flex: 1;
        ">${timeStr}</span>
        ${fullTimeStr ? `
          <button 
            onclick="copyAnimationTime('${htmlspecialchars(fullTimeStr)}', '${htmlspecialchars(timeStr)}')"
            style="
              background: rgba(96, 165, 250, 0.2);
              border: 1px solid rgba(96, 165, 250, 0.4);
              color: #60a5fa;
              border-radius: 6px;
              padding: 4px 8px;
              cursor: pointer;
              font-size: 14px;
              display: flex;
              align-items: center;
              justify-content: center;
              transition: all 0.2s ease;
              min-width: 32px;
              height: 28px;
            "
            onmouseover="this.style.background='rgba(96, 165, 250, 0.3)'; this.style.borderColor='rgba(96, 165, 250, 0.6)';"
            onmouseout="this.style.background='rgba(96, 165, 250, 0.2)'; this.style.borderColor='rgba(96, 165, 250, 0.4)';"
            title="${currentLang === 'ar' ? 'نسخ الوقت' : 'Copy time'}"
          >
            📋
          </button>
        ` : ''}
      </div>
      ${dateStr ? `
        <!-- Date display -->
        <div style="
          font-size: 11px;
          color: rgba(255, 255, 255, 0.7);
          margin-top: 2px;
          padding-top: 4px;
          border-top: 1px solid rgba(255, 255, 255, 0.1);
        ">${dateStr}</div>
      ` : ''}
      <!-- Arrow pointer -->
      <div style="
        position: absolute;
        bottom: -6px;
        left: 50%;
        transform: translateX(-50%);
        width: 0;
        height: 0;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-top: 6px solid #1e293b;
      "></div>
    </div>
  `;
  
  animationLabel.setContent(labelHtml);
  const position = new google.maps.LatLng(point.lat, point.lng);
  animationLabel.setPosition(position);
  
  // Always show label when marker exists
  if (animationMarker || animationIsPlaying) {
    animationLabel.open(map);
  }
}

/**
 * Format date only (without time)
 */
function formatDateOnly(dateStr) {
  if (!dateStr) return '';
  try {
    const date = new Date(dateStr.replace(' ', 'T'));
    if (isNaN(date.getTime())) return '';
    
    const months = ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 
                    'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'];
    const day = date.getDate();
    const month = months[date.getMonth()];
    const year = date.getFullYear();
    
    return `${day} ${month} ${year}`;
  } catch (e) {
    return '';
  }
}

function hideAnimationLabel() {
  if (animationLabel) {
    animationLabel.close();
  }
}

function updateAnimationProgressSlider(currentIndex, total) {
  const progressRange = document.getElementById('animationProgressRange');
  if (!progressRange || !total || total <= 1) return;
  const clampedIndex = Math.max(0, Math.min(currentIndex, total - 1));
  const ratio = clampedIndex / (total - 1);
  progressRange.value = Math.round(ratio * 100);
}

function onAnimationProgressChange() {
  const slider = document.getElementById('animationProgressRange');
  if (!slider || !routeCoordinates.length) return;

  // إيقاف الحركة التلقائية أثناء السحب
  stopAnimation(true);

  const value = parseFloat(slider.value || '0');
  const ratio = Math.max(0, Math.min(value / 100, 1));
  const idx = Math.round(ratio * (routeCoordinates.length - 1));
  currentAnimationIndex = idx;

  const pt = routeCoordinates[idx];
  if (!pt || !map || !window.google || !google.maps) return;

  // تحديث موضع الأيقونة على الخريطة مع الأيقونة المخصصة
  if (!animationMarker) {
    const icon = createAnimationIcon();
    animationMarker = new google.maps.Marker({
      position: { lat: pt.lat, lng: pt.lng },
      map: map,
      icon: icon || undefined, // Use custom icon if available, otherwise default
      optimized: false,
      zIndex: 1000
    });
  } else {
    animationMarker.setPosition({ lat: pt.lat, lng: pt.lng });
  }

  map.panTo({ lat: pt.lat, lng: pt.lng });
  updateAnimationTimeLabel(pt.time);
  updateAnimationLabel(pt);
  setAnimationState('paused');
}

//----------------------------------------------------
//  دوال مشاركة الموقع
//----------------------------------------------------
function shareLocation() {
  var deviceSel = document.getElementById("deviceSelect");
  if (!deviceSel) return;
  var deviceId  = deviceSel.value;

  if (!deviceId) {
    showToast("❌ اختر جهازاً أولاً.");
    return;
  }
  if (!latestMarker) {
    showToast("❌ لا يوجد موقع حديث للمشاركة. اضغط (آخر موقع مباشر).");
    return;
  }
  var deviceName = (deviceSel.selectedIndex >= 0 && deviceSel.options[deviceSel.selectedIndex])
                   ? deviceSel.options[deviceSel.selectedIndex].text
                   : "جهاز غير محدد";
  var expires = Date.now() + 3600000; // ساعة واحدة
  var shareUrl = window.location.origin + window.location.pathname
               + "?share=1"
               + "&device_id="   + encodeURIComponent(deviceId)
               + "&device_name=" + encodeURIComponent(deviceName)
               + "&expires="     + expires;
  window.open(shareUrl, "_blank"); // فتح رابط المشاركة في نافذة جديدة
  showToast("تم فتح رابط المشاركة في نافذة جديدة.");
}

//----------------------------------------------------
//   دوال جدول السجلات (مخطط زمني عمودي)
//----------------------------------------------------
function updateLogsTable() {
  var tbody = document.getElementById("logsTable")?.getElementsByTagName("tbody")[0];
  if (!tbody) return; // إذا لم يتم العثور على tbody
  tbody.innerHTML = '';
 
  // [تعديل] إلغاء أي فلترة إضافية على المدد هنا
  // الهدف: إظهار **كل** التوقفات التي يعيدها السيرفر كما هي (100%)
  const processedLogs = [];
  if (logs.length > 0) {
    logs.forEach(log => {
      if (log.type === 'stop') {
        processedLogs.push(log);
      }
    });
  }
 
  if (processedLogs.length === 0) {
      tbody.innerHTML = '<tr><td colspan="3" style="text-align:center; padding: 20px;">لا يوجد نشاط مسجل لهذا اليوم.</td></tr>';
      return;
  }
 
  const cfg = getThresholdsConfig();
 
  // [تعديل] استخدام السجلات المدمجة والمصفاة (processedLogs) للعرض
  processedLogs.forEach((log) => {
    var row = tbody.insertRow();

    const timeCell = row.insertCell(0);
    const activityCell = row.insertCell(1);
    const durationCell = row.insertCell(2);

    const enterStr = log.entryTime ? formatTimeOnly12Hour(log.entryTime) : '';
    const exitStr  = log.exitTime  ? formatTimeOnly12Hour(log.exitTime)  : '';
    timeCell.innerHTML = `
      <div class="timeline-time-row">
        <span class="label">${currentLang === 'ar' ? 'دخول:' : 'In:'}</span>
        <span class="value">${enterStr || '--:--'}</span>
        ${enterStr ? `<button class="copy-time-btn" title="${currentLang === 'ar' ? 'نسخ وقت الدخول' : 'Copy entry time'}" onclick="copyTimelineTime('${htmlspecialchars(enterStr)}')">📋</button>` : ''}
      </div>
      ${exitStr ? `
      <div class="timeline-time-row">
        <span class="label">${currentLang === 'ar' ? 'خروج:' : 'Out:'}</span>
        <span class="value">${exitStr}</span>
        <button class="copy-time-btn" title="${currentLang === 'ar' ? 'نسخ وقت الخروج' : 'Copy exit time'}" onclick="copyTimelineTime('${htmlspecialchars(exitStr)}')">📋</button>
      </div>` : ''}
    `;
    timeCell.style.textAlign = 'left';
    timeCell.style.verticalAlign = 'top';
    timeCell.className = 'timeline-time-cell';

    activityCell.classList.add('timeline-cell');
    durationCell.style.textAlign = 'left';
    durationCell.style.verticalAlign = 'top';
    durationCell.className = 'timeline-duration-cell';

    // بناء مسار الخط الزمني
    const dotClass = (log.type === 'stop') ? 'stop' : 'driving';
    let contentHtml = ''; // محتوى الخلية

    if (log.type === 'stop') {
      const placeIcon = getIconForPlaceType(log.place_type);
      const placeName = log.place_name || `${Number(log.lat).toFixed(5)}, ${Number(log.lng).toFixed(5)}`;
      const entryJson = log.entryTime ? JSON.stringify(log.entryTime) : 'null';
      contentHtml = `<a href="#" onclick='event.preventDefault(); focusTimelineLocation(${log.lat}, ${log.lng}, ${entryJson})' title="${htmlspecialchars(placeName)}">${placeIcon} ${htmlspecialchars(placeName)}</a>`; // رابط للموقع
      
      const minutes = Number(log.duration || 0);
      
      // إضافة معلومات البطارية إذا كانت متوفرة
      let batteryHtml = '';
      if (log.battery_range) {
        const batteryRange = log.battery_range;
        // تحديد أيقونة البطارية حسب النسبة
        let batteryIcon = '🔋';
        const batteryMatch = batteryRange.match(/(\d+)/);
        if (batteryMatch) {
          const batteryValue = parseInt(batteryMatch[1]);
          if (batteryValue > 80) batteryIcon = '🔋';
          else if (batteryValue > 20) batteryIcon = '🪫';
          else batteryIcon = '🔌';
        }
        batteryHtml = `<div style="margin-top: 6px; padding-top: 6px; border-top: 1px solid #eee; font-size: 11px; color: #666;">
          <span style="margin-right: 4px;">${batteryIcon}</span>
          <span style="font-weight: 600; color: #4CAF50;">${batteryRange}</span>
        </div>`;
      }
      
      durationCell.innerHTML = `
        <span class="duration-badge">${formatDuration(minutes)}</span>
        ${batteryHtml}
      `;
    } else {
      const activityIcon = '🚗';
      const activityName = currentLang === 'ar' ? 'قيادة' : 'Driving'; // نص النشاط
      const distanceKm = log.distance ? (log.distance / 1000).toFixed(2) : '0.00';
      contentHtml = `${activityIcon} ${activityName}`;
      durationCell.innerHTML = `<span class="duration-badge">${distanceKm} ${currentLang === 'ar' ? 'كم' : 'km'}</span><br><small style="font-size: 10px; opacity: 0.7;">${formatDuration(log.duration || 0)}</small>`;
    }

    activityCell.innerHTML = `
      <div class="timeline-track">
        <span class="timeline-line"></span>
        <span class="timeline-dot ${dotClass}"></span>
        <div class="timeline-content">${contentHtml}</div>
      </div>
    `;
  });
}

// البحث في سجل التوقف (فلترة)
function filterLogsTable() {
  var inputEl = document.getElementById("logsSearchInput");
  if(!inputEl) return;
  var input = inputEl.value.toUpperCase();
  var table = document.getElementById("logsTable");
  if(!table) return;
  var trs   = table.getElementsByTagName("tr");

  for (var i = 0; i < trs.length; i++) {
    var tds = trs[i].getElementsByTagName("td");
    var rowText = "";
    var displayRow = false;
    for (var j = 0; j < tds.length; j++) {
      if (tds[j]) {
        rowText = tds[j].textContent || tds[j].innerText;
        if (rowText.toUpperCase().indexOf(input) > -1) {
          displayRow = true;
          break;
        }
      }
    }
    trs[i].style.display = displayRow ? "" : "none";
  }
}

function resetLogsFilter() { // إعادة تعيين فلتر البحث
  const logsSearchInput = document.getElementById("logsSearchInput");
  if (logsSearchInput) {
      logsSearchInput.value = "";
  }
  filterLogsTable();
}

// فرز الجدول بالعمود index
let logsSortDirections = {}; // كائن لتخزين اتجاه الفرز لكل عمود

function sortLogsTable(columnIndex) {
    var table = document.getElementById("logsTable");
    if (!table) return;
    var tbody = table.tBodies[0];
    if (!tbody) return;
    var rows = Array.from(tbody.querySelectorAll("tr"));
    var ths = table.tHead.querySelectorAll("th.sortable");

    // تحديد اتجاه الفرز (تبديل أو افتراضي تصاعدي)
    const currentDirection = logsSortDirections[columnIndex] || 'asc';
    const newDirection = currentDirection === 'asc' ? 'desc' : 'asc';
    logsSortDirections[columnIndex] = newDirection;
    
    // Reset other column indicators
    ths.forEach((th, idx) => {
        th.classList.remove('sorted-asc', 'sorted-desc');
        if (idx === columnIndex) {
            th.classList.add(newDirection === 'asc' ? 'sorted-asc' : 'sorted-desc');
        }
    });


    rows.sort((rowA, rowB) => {
        var cellA = rowA.cells[columnIndex].textContent.trim();
        var cellB = rowB.cells[columnIndex].textContent.trim();

        let comparison = 0; // مقارنة الخلايا
        if (columnIndex === 1 || columnIndex === 2) { // Timestamp columns
            // Attempt to parse dates, fallback to string comparison if parsing fails
            let dateA = new Date(cellA.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$2/$1/$3')); // Handle dd/mm/yyyy
            let dateB = new Date(cellB.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$2/$1/$3'));
            if (!isNaN(dateA) && !isNaN(dateB)) {
                 comparison = dateA - dateB;
            } else {
                 comparison = cellA.localeCompare(cellB); // Fallback
            }
        } else { // Text columns
            comparison = cellA.localeCompare(cellB, undefined, {numeric: true, sensitivity: 'base'});
        }
        return newDirection === 'asc' ? comparison : -comparison;
    });

    rows.forEach(row => tbody.appendChild(row));
}


function focusOnLocation(center) { // التركيز على موقع معين في الخريطة
  if (map && center && center.length === 2 && !isNaN(center[0]) && !isNaN(center[1])) {
      map.setCenter({lat: center[0], lng: center[1]}); map.setZoom(17);
  } else {
      console.error("Invalid center coordinates for focusOnLocation:", center);
  }
}

function buildCoordinateKey(lat, lng, precision = 5) {
  const safeLat = parseFloat(lat);
  const safeLng = parseFloat(lng);
  if (isNaN(safeLat) || isNaN(safeLng)) return null;
  return `${safeLat.toFixed(precision)},${safeLng.toFixed(precision)}`;
}

function focusTimelineLocation(lat, lng, entryTime = null) {
  const parsedLat = parseFloat(lat);
  const parsedLng = parseFloat(lng);
  if (isNaN(parsedLat) || isNaN(parsedLng)) return;
  const entryValue = typeof entryTime === 'string' ? entryTime : (entryTime || null);
  const indexFromTimeline = alignAnimationWithCoordinate(parsedLat, parsedLng, entryValue);
  const focusTarget = (indexFromTimeline !== null && indexFromTimeline >= 0)
    ? [routeCoordinates[indexFromTimeline].lat, routeCoordinates[indexFromTimeline].lng]
    : [parsedLat, parsedLng];
  focusOnLocation(focusTarget);
  openStopMarkerInfo(parsedLat, parsedLng);
}

function openStopMarkerInfo(lat, lng) {
  const key = buildCoordinateKey(lat, lng);
  if (!key || !stopMarkersIndex.has(key) || !infoWindow) return;
  const { marker, content } = stopMarkersIndex.get(key) || {};
  if (!marker) return;
  infoWindow.setContent(content || '');
  infoWindow.open(map, marker);
}

function alignAnimationWithCoordinate(lat, lng, entryTime = null) {
  if (!routeCoordinates.length) return null;

  let nearestIndex = -1;
  if (entryTime) {
    const targetDate = parseDate(entryTime);
    if (targetDate) {
      nearestIndex = findRouteIndexByTimeAndLocation(targetDate, lat, lng);
      if (nearestIndex < 0) {
        nearestIndex = findFirstIndexAfterTime(targetDate);
      }
    }
  }

  if (nearestIndex < 0) {
    nearestIndex = findClosestRouteIndex(lat, lng);
  }

  if (nearestIndex < 0) return null;

  stopAnimation(true);
  currentAnimationIndex = nearestIndex;

  const pt = routeCoordinates[nearestIndex];
  if (!pt) return;

  updateAnimationTimeLabel(pt.time);
  map.panTo({ lat: pt.lat, lng: pt.lng });
  return nearestIndex;
}

function findClosestRouteIndex(lat, lng) {
  let nearestIndex = -1;
  let nearestDistance = Infinity;
  for (let i = 0; i < routeCoordinates.length; i++) {
    const pt = routeCoordinates[i];
    const dist = haversineDistanceMeters(lat, lng, pt.lat, pt.lng);
    if (dist < nearestDistance) {
      nearestDistance = dist;
      nearestIndex = i;
    }
  }
  return nearestIndex;
}

function findClosestRouteIndexByTime(targetDate) {
  let nearestIndex = -1;
  let nearestDiff = Infinity;
  for (let i = 0; i < routeCoordinates.length; i++) {
    const pt = routeCoordinates[i];
    const ptDate = parseDate(pt.time);
    if (!ptDate) continue;
    const diff = Math.abs(ptDate - targetDate);
    if (diff < nearestDiff) {
      nearestDiff = diff;
      nearestIndex = i;
    }
  }
  return nearestIndex;
}

function parseDate(dateStr) {
  if (!dateStr) return null;
  const parsed = new Date(dateStr.replace(' ', 'T'));
  return isNaN(parsed) ? null : parsed;
}

function findRouteIndexByTimeAndLocation(targetDate, lat, lng, radiusMeters = 150, windowMs = 2 * 60 * 1000) {
  if (!targetDate) return -1;
  const startWindow = targetDate.getTime() - windowMs;
  const endWindow = targetDate.getTime() + windowMs;
  for (let i = 0; i < routeCoordinates.length; i++) {
    const pt = routeCoordinates[i];
    const ptDate = parseDate(pt.time);
    if (!ptDate) continue;
    const timeMs = ptDate.getTime();
    if (timeMs < startWindow) continue;
    if (timeMs > endWindow) break;
    const dist = haversineDistanceMeters(lat, lng, pt.lat, pt.lng);
    if (dist <= radiusMeters) {
      return i;
    }
  }
  return -1;
}

function findFirstIndexAfterTime(targetDate, toleranceMs = 60 * 1000) {
  if (!targetDate) return -1;
  const minTime = targetDate.getTime() - toleranceMs;
  for (let i = 0; i < routeCoordinates.length; i++) {
    const pt = routeCoordinates[i];
    const ptDate = parseDate(pt.time);
    if (!ptDate) continue;
    if (ptDate.getTime() >= minTime) {
      return i;
    }
  }
  return -1;
}

//----------------------------------------------------
//   دوال تجميع المواقع (بارك/تحرك)
//----------------------------------------------------
function groupLocations(locations) { // تجميع النقاط إلى مجموعات (توقف/تحرك)
  if (!locations || !locations.length) return [];
  locations.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());

  const cfg = getThresholdsConfig();
  var groups = [];
  var first = locations[0];
  if (!first) return [];

  var currentGroup = {
    points: [first],
    center: [parseFloat(first.latitude), parseFloat(first.longitude)],
    entryTime: first.timestamp,
    exitTime:  first.timestamp,
    batteryLevels: [ first.battery ? parseInt(first.battery) : null ]
  }; // المجموعة الحالية

  for (var i = 1; i < locations.length; i++) {
    var loc = locations[i];
    var currTime = new Date(loc.timestamp);
    var timeDiff = (currTime.getTime() - prevTime.getTime()) / 60000; // دقائق
    var lastPt   = currentGroup.points[currentGroup.points.length - 1];
    var lastLat  = parseFloat(lastPt.latitude);
    var currLat  = parseFloat(loc.latitude); // إحداثيات النقطة الحالية
    var currLng  = parseFloat(loc.longitude); // إحداثيات النقطة الحالية

    if (isNaN(currLat) || isNaN(currLng)) continue; // Skip if invalid coords

    var distFromCenter = getDistance(currentGroup.center[0], currentGroup.center[1], currLat, currLng);
    var locBattery = loc.battery ? parseInt(loc.battery) : null;

    // حساب السرعة منذ النقطة الأخيرة
    const speedSinceLast = timeDiff > 0 ? (getDistance(lastLat, lastPt.longitude, currLat, currLng) / 1000) / (timeDiff / 60) : 0;

    // ====================================================================================
    // شرط الدمج في المجموعة الحالية (Condition to merge into current group)
    // ====================================================================================
    // يتم دمج النقطة في المجموعة الحالية (تعتبر جزءاً من نفس التوقف) إذا:
    // 1. المسافة من المركز (distFromCenter) < أقصى انتشار للتوقف (stationaryThresholdM)
    //    - النقطة قريبة بما يكفي من مركز المجموعة
    // 2. السرعة منذ النقطة الأخيرة (speedSinceLast) < أقصى سرعة للتوقف (stopMaxSpeedKmh)
    //    - السرعة منخفضة بما يكفي لاعتبارها جزءاً من التوقف
    // ====================================================================================
    if (distFromCenter < cfg.stationaryThresholdM && speedSinceLast < cfg.stopMaxSpeedKmh) {
      currentGroup.points.push(loc);
      currentGroup.exitTime = loc.timestamp;
      if(locBattery !== null) currentGroup.batteryLevels.push(locBattery);
      
      // تحديث المركز بناءً على متوسط النقاط للدقة العالية
      var totalLat = 0, totalLng = 0;
      currentGroup.points.forEach(p => {
        totalLat += parseFloat(p.latitude); // مجموع خطوط العرض
        totalLng += parseFloat(p.longitude);
      });
      currentGroup.center = [totalLat / currentGroup.points.length, totalLng / currentGroup.points.length];
    } else {
      groups.push(finalizeGroup(currentGroup));
      currentGroup = {
        points: [loc],
        center: [currLat, currLng],
        entryTime: loc.timestamp,
        exitTime: loc.timestamp,
        batteryLevels: [locBattery !== null ? locBattery : null] // مستويات البطارية
      };
    }
    prevTime = currTime;
  }
  groups.push(finalizeGroup(currentGroup)); // Push the last group
  
  return groups;
}

function finalizeGroup(group) {
    // حساب المركز المحسن للدقة العالية (متوسط الإحداثيات)
    if (group.points && group.points.length > 1) {
      var totalLat = 0, totalLng = 0, validPoints = 0;
      
      group.points.forEach(p => {
        var lat = parseFloat(p.latitude);
        var lng = parseFloat(p.longitude);
        if (!isNaN(lat) && !isNaN(lng)) {
          totalLat += lat;
          totalLng += lng;
          validPoints++;
        }
      });
      
      if (validPoints > 0) {
        group.center = [totalLat / validPoints, totalLng / validPoints];
      }
    }

    const diffMin = (new Date(group.exitTime).getTime() - new Date(group.entryTime).getTime()) / 60000; // المدة بالدقائق
    var pointCount = group.points ? group.points.length : 1;

    // حساب الانتشار حول المركز والمسافة/السرعة داخل المجموعة
    var centerLat = group.center[0];
    var centerLng = group.center[1];
    var maxDeviation = 0; // أكبر انحراف عن المركز بالمتر
    var totalDistMeters = 0;

    if (group.points && group.points.length > 1 && !isNaN(centerLat) && !isNaN(centerLng)) {
      for (var i = 0; i < group.points.length; i++) {
        var p = group.points[i];
        var plat = parseFloat(p.latitude), plng = parseFloat(p.longitude);
        if (isNaN(plat) || isNaN(plng)) continue;

        var dev = getDistance(centerLat, centerLng, plat, plng);
        if (dev > maxDeviation) maxDeviation = dev; // أكبر انحراف

        if (i > 0) {
          var prev = group.points[i - 1];
          var prevLat = parseFloat(prev.latitude), prevLng = parseFloat(prev.longitude);
          if (!isNaN(prevLat) && !isNaN(prevLng)) totalDistMeters += getDistance(prevLat, prevLng, plat, plng);
        }
      }
    } // حساب متوسط السرعة
    var avgSpeedKmh = diffMin > 0 ? (totalDistMeters / 1000) / (diffMin / 60) : 0;

    // الحصول على إعدادات التصنيف الحالية
    const cfg = getThresholdsConfig();

    // ====================================================================================
    // منطق التصنيف (Classification Logic)
    // ====================================================================================
    // يتم تصنيف المجموعة كـ "توقف" إذا تحققت جميع الشروط التالية:
    // 1. المدة (diffMin) >= أقل مدة للتوقف (stopMinDurationMin)
    //    - يجب أن يكون الجهاز متوقفاً لمدة كافية
    // 2. الانتشار (maxDeviation) <= أقصى انتشار للتوقف (stationaryThresholdM)
    //    - يجب أن تكون جميع النقاط ضمن نطاق جغرافي محدود
    // 3. متوسط السرعة (avgSpeedKmh) <= أقصى سرعة للتوقف (stopMaxSpeedKmh)
    //    - يجب أن تكون السرعة منخفضة بما يكفي
    // 
    // إذا لم تتحقق جميع الشروط، يتم تصنيف المجموعة كـ "تحرك"
    // ====================================================================================
    if (
      (diffMin >= cfg.stopMinDurationMin && 
       maxDeviation <= cfg.stationaryThresholdM && 
       avgSpeedKmh <= cfg.stopMaxSpeedKmh)
    ) {
      group.status = "بارك توقف";
    } else {
      group.status = "تحرك";
    }

    var validB = group.batteryLevels.filter(b => b !== null && !isNaN(b)); // تصفية مستويات البطارية الصالحة
    group.minBattery = validB.length > 0 ? Math.min(...validB) : null;
    group.maxBattery = validB.length > 0 ? Math.max(...validB) : null;
    group.pointCount = pointCount;
    group.duration = diffMin;
    group.totalDistMeters = totalDistMeters;
    delete group.points; // We don't need to store all points after processing
    return group;
}

// ✅ دالة محسّنة: تقسيم ذكي للمسار مع مراعاة الاستدارات والتقاطعات بدقة 100%
function smartSegmentSplit(points) {
  if (points.length < 2) return [];
  
  const segments = [];
  const maxSegmentLength = 12; // ✅ تقليل العدد لتحسين الدقة في الاستدارات
  const minSegmentLength = 3; // الحد الأدنى
  const sharpTurnThreshold = 40; // ✅ تقليل العتبة لرصد استدارات أكثر
  const intersectionThreshold = 30; // ✅ عتبة للتقاطعات (تغيير اتجاه مفاجئ)
  
  let currentStart = 0;
  let lastDirection = null;
  
  for (let i = 1; i < points.length - 1; i++) {
    const prev = points[i - 1];
    const current = points[i];
    const next = points[i + 1];
    
    // ✅ حساب الزاوية بين النقاط الثلاث
    const angle = calculateTurnAngle(prev, current, next);
    const isSharpTurn = Math.abs(angle) > sharpTurnThreshold;
    
    // ✅ حساب الاتجاه الحالي
    const currentDirection = calculateBearingFromPoints(prev, current);
    const isIntersection = lastDirection !== null && 
      Math.abs(currentDirection - lastDirection) > intersectionThreshold;
    
    // ✅ حساب المسافة من بداية القطعة الحالية
    const segmentLength = i - currentStart + 1;
    
    // ✅ حساب المسافة بين النقاط (لتحديد التقاطعات)
    const distance = haversineDistanceMeters(
      prev.lat || prev[0], prev.lng || prev[1],
      current.lat || current[0], current.lng || current[1]
    );
    
    // ✅ تقسيم عند:
    // 1. استدارة حادة (زاوية > 40 درجة)
    // 2. تقاطع (تغيير اتجاه > 30 درجة)
    // 3. أو عند الوصول للحد الأقصى
    // 4. أو عند مسافة كبيرة بين النقاط (قد تكون تقاطع)
    const shouldSplit = (
      (isSharpTurn && segmentLength >= minSegmentLength) ||
      (isIntersection && segmentLength >= minSegmentLength) ||
      (distance > 200 && segmentLength >= minSegmentLength) || // ✅ مسافة كبيرة قد تكون تقاطع
      (segmentLength >= maxSegmentLength)
    );
    
    if (shouldSplit && i > currentStart) {
      // حفظ القطعة الحالية
      segments.push({
        points: points.slice(currentStart, i + 1),
        startIndex: currentStart,
        endIndex: i,
        hasSharpTurn: isSharpTurn,
        isIntersection: isIntersection
      });
      currentStart = i; // بدء قطعة جديدة من نقطة الاستدارة/التقاطع
      lastDirection = null; // إعادة تعيين الاتجاه
    } else {
      lastDirection = currentDirection;
    }
  }
  
  // إضافة القطعة الأخيرة
  if (currentStart < points.length - 1) {
    segments.push({
      points: points.slice(currentStart),
      startIndex: currentStart,
      endIndex: points.length - 1,
      hasSharpTurn: false,
      isIntersection: false
    });
  }
  
  return segments;
}

// ✅ دالة جديدة: حساب زاوية الاستدارة بين ثلاث نقاط
function calculateTurnAngle(p1, p2, p3) {
  const normalizePoint = (p) => {
    if (typeof p === 'object' && 'lat' in p) {
      return { lat: p.lat, lng: p.lng };
    } else if (Array.isArray(p)) {
      return { lat: p[0], lng: p[1] };
    }
    return p;
  };
  
  const np1 = normalizePoint(p1);
  const np2 = normalizePoint(p2);
  const np3 = normalizePoint(p3);
  
  // حساب الاتجاه من p1 إلى p2
  const bearing1 = calculateBearingFromPoints(np1, np2);
  // حساب الاتجاه من p2 إلى p3
  const bearing2 = calculateBearingFromPoints(np2, np3);
  
  // حساب الفرق في الزاوية
  let angle = bearing2 - bearing1;
  
  // تطبيع الزاوية إلى [-180, 180]
  if (angle > 180) angle -= 360;
  if (angle < -180) angle += 360;
  
  return angle;
}

// ✅ دالة جديدة: حساب الاتجاه (bearing) بين نقطتين
function calculateBearingFromPoints(p1, p2) {
  const lat1 = p1.lat * Math.PI / 180;
  const lat2 = p2.lat * Math.PI / 180;
  const dLng = (p2.lng - p1.lng) * Math.PI / 180;
  
  const y = Math.sin(dLng) * Math.cos(lat2);
  const x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng);
  
  const bearing = Math.atan2(y, x) * 180 / Math.PI;
  return (bearing + 360) % 360;
}

// دالة تحليل النقاط بالذكاء الاصطناعي لتحديد أفضل مسار
function analyzeRouteWithAI(routePoints) {
  // ✅ تحسين: التأكد من ترتيب النقاط حسب الوقت أولاً
  const sortedPoints = [...routePoints].sort((a, b) => {
    if (a.time && b.time) {
      return new Date(a.time) - new Date(b.time);
    }
    return 0;
  });
  
  // تحسين الأداء: إذا كان عدد النقاط كبيراً جداً، نأخذ عينة منها
  let pointsToAnalyze = sortedPoints;
  if (sortedPoints.length > 500) {
    const step = Math.ceil(sortedPoints.length / 300);
    pointsToAnalyze = sortedPoints.filter((_, index) => index % step === 0);
  }
  
  const analyzedPoints = [];
  const minDistance = 15; // زيادة الحد الأدنى لتقليل النقاط
  const maxJumpDistance = 1000; // ✅ إضافة: الحد الأقصى للمسافة بين نقطتين (متر)

  for (let i = 0; i < pointsToAnalyze.length; i += 2) { // تخطي نقطة واحدة لتسريع المعالجة
    const currentPoint = pointsToAnalyze[i];
    let shouldInclude = true;
    
    // فحص مبسط للمسافة فقط
    if (i > 0) {
      const prevPoint = analyzedPoints[analyzedPoints.length - 1] || pointsToAnalyze[i - 1];
      const distToPrev = haversineDistanceMeters(
        prevPoint.lat, prevPoint.lng,
        currentPoint.lat, currentPoint.lng
      );
      
      // ✅ تحسين: تجاهل النقاط القريبة جداً أو البعيدة جداً (قفزات مشبوهة)
      if (distToPrev < minDistance) {
        shouldInclude = false;
      } else if (distToPrev > maxJumpDistance) {
        // إذا كانت المسافة كبيرة جداً، قد تكون نقطة GPS خاطئة
        shouldInclude = false;
        console.warn(`تم تجاهل نقطة مشبوهة: مسافة ${distToPrev.toFixed(0)} متر`);
      }
    }
    
    if (shouldInclude) {
      analyzedPoints.push(currentPoint);
    }
  }
  
  // التأكد من إضافة النقطة الأخيرة (إذا لم تكن موجودة)
  if (pointsToAnalyze.length > 0 && analyzedPoints.length > 0) {
    const lastOriginal = pointsToAnalyze[pointsToAnalyze.length - 1];
    const lastAnalyzed = analyzedPoints[analyzedPoints.length - 1];
    const distToLast = haversineDistanceMeters(
      lastAnalyzed.lat, lastAnalyzed.lng,
      lastOriginal.lat, lastOriginal.lng
    );
    if (distToLast > minDistance && distToLast <= maxJumpDistance) {
      analyzedPoints.push(lastOriginal);
    }
  }
  
  return analyzedPoints;
}

// دالة حساب المسافة بين نقطتين بالمتر
function calculateDistance(point1, point2) { // حساب المسافة بين نقطتين (Haversine formula)
  const R = 6371000; // نصف قطر الأرض بالمتر
  const lat1Rad = point1[0] * Math.PI / 180;
  const lat2Rad = point2[0] * Math.PI / 180;
  const deltaLat = (point2[0] - point1[0]) * Math.PI / 180;
  const deltaLng = (point2[1] - point1[1]) * Math.PI / 180;
  
  const a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
    Math.cos(lat1Rad) * Math.cos(lat2Rad) *
    Math.sin(deltaLng/2) * Math.sin(deltaLng/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  
  return R * c;
}

// دالة حساب الاتجاه بين نقطتين
function calculateBearing(point1, point2) { // حساب الاتجاه (Bearing)
  const lat1Rad = point1[0] * Math.PI / 180;
  const lat2Rad = point2[0] * Math.PI / 180;
  const deltaLng = (point2[1] - point1[1]) * Math.PI / 180;
  
  const y = Math.sin(deltaLng) * Math.cos(lat2Rad);
  const x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
    Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLng);
  
  const bearing = Math.atan2(y, x) * 180 / Math.PI;
  return (bearing + 360) % 360;
}

// دالة تحسين المسار باستخدام خوارزمية التنعيم الذكي
function smoothRouteIntelligently(points) { // تنعيم المسار
  if (points.length < 3) return points;
  
  const smoothedPoints = [points[0]]; // البداية دائماً
  
  for (let i = 1; i < points.length - 1; i++) {
    const prev = points[i - 1];
    const current = points[i];
    const next = points[i + 1];
    
    // ✅ تحسين: استخدام haversineDistanceMeters للكائنات {lat, lng}
    const distToPrev = haversineDistanceMeters(
      current.lat || current[0], current.lng || current[1],
      prev.lat || prev[0], prev.lng || prev[1]
    );
    const distToNext = haversineDistanceMeters(
      current.lat || current[0], current.lng || current[1],
      next.lat || next[0], next.lng || next[1]
    );
    
    // إذا كانت النقطة قريبة جداً، استخدم متوسط مرجح
    if (distToPrev < 30 && distToNext < 30) {
      const weight = 0.3; // وزن التنعيم
      const currentLat = current.lat || current[0];
      const currentLng = current.lng || current[1];
      const prevLat = prev.lat || prev[0];
      const prevLng = prev.lng || prev[1];
      const nextLat = next.lat || next[0];
      const nextLng = next.lng || next[1];
      
      const smoothedLat = currentLat * (1 - 2 * weight) + prevLat * weight + nextLat * weight;
      const smoothedLng = currentLng * (1 - 2 * weight) + prevLng * weight + nextLng * weight;
      
      // ✅ الحفاظ على نفس التنسيق (كائن أو مصفوفة)
      if (typeof current === 'object' && 'lat' in current) {
        smoothedPoints.push({ lat: smoothedLat, lng: smoothedLng, time: current.time });
      } else {
        smoothedPoints.push([smoothedLat, smoothedLng]);
      }
    } else {
      smoothedPoints.push(current);
    }
  }
  
  smoothedPoints.push(points[points.length - 1]); // النهاية دائماً
  return smoothedPoints;
}

// دالة رسم المسار الذكي باستخدام Mapbox Directions API
async function drawIntelligentRoute(routePoints, grouped) { // رسم المسار الذكي (باستخدام Google Directions)
  try {
    // تطبيق تحليل الذكاء الاصطناعي على النقاط
    updateLoadingText('جاري تحليل المسار بالذكاء الاصطناعي...');
    console.log('تحليل المسار بالذكاء الاصطناعي...');
    const analyzedPoints = analyzeRouteWithAI(routePoints);
    console.log(`تم تحليل ${routePoints.length} نقطة إلى ${analyzedPoints.length} نقطة محسنة`);
    
    // تطبيق التنعيم الذكي
    updateLoadingText('جاري تنعيم المسار...');
    const smoothedPoints = smoothRouteIntelligently(analyzedPoints);
    console.log(`تم تنعيم المسار إلى ${smoothedPoints.length} نقطة نهائية`);
    
    // ✅ تحسين: تقسيم ذكي للمسار مع مراعاة الاستدارات والتقاطعات
    updateLoadingText('جاري تقسيم المسار...');
    const segments = smartSegmentSplit(smoothedPoints);
     
     // معالجة كل قطعة بشكل منفصل (جلب المسار الفعلي)
     updateLoadingText(`جاري رسم المسار (${segments.length} قطعة)...`);
    for (let i = 0; i < segments.length; i++) {
        updateLoadingText(`جاري رسم المسار الفعلي (قطعة ${i + 1} من ${segments.length})...`);
        // **تصحيح**: تمرير `grouped` الصحيح الذي يحتوي على معلومات الحالة
        await drawSegmentRoute(segments[i], grouped);
    }
     
     // رسم خط رئيسي شفاف للمسار الكامل المحسن
     updateLoadingText('جاري إنهاء رسم المسار...'); // خط المسار الكلي
     const mainRoute = new google.maps.Polyline({
        path: smoothedPoints.map(p => {
          // ✅ دعم كلا التنسيقين: كائنات {lat, lng} أو مصفوفات [lat, lng]
          if (typeof p === 'object' && 'lat' in p) {
            return { lat: p.lat, lng: p.lng };
          } else if (Array.isArray(p)) {
            return { lat: p[0], lng: p[1] };
          }
          return p;
        }),
        geodesic: true,
        strokeColor: '#1976D2',
        strokeOpacity: 0.25,
        strokeWeight: 2,
        map: map
     });
     polylines.push(mainRoute);
    
    // إضافة نقاط اتجاه للمسار المحسن (لتحسين الرؤية)
     addDirectionMarkers(smoothedPoints);
     
     // إضافة معلومات التحسين
     console.log('تم رسم المسار الذكي بنجاح');
     console.log(`نسبة التحسين: ${((routePoints.length - smoothedPoints.length) / routePoints.length * 100).toFixed(1)}%`);
    
  } catch (error) {
    console.error('خطأ في رسم المسار الذكي:', error);
    // العودة للرسم التقليدي في حالة الخطأ
    drawFallbackRoute(routePoints, grouped);
  }
}

// [تم التعديل] دالة محسّنة: رسم قطعة من المسار بدقة 100% مع مراعاة الطرق والاستدارات
async function drawSegmentRoute(segment, grouped) {
  const { points, startIndex, hasSharpTurn, isIntersection } = segment;
  if (points.length < 2) return;
  
  // ✅ دعم كلا التنسيقين: كائنات {lat, lng} أو مصفوفات [lat, lng]
  const normalizePoint = (p) => {
    if (typeof p === 'object' && 'lat' in p) {
      return { lat: p.lat, lng: p.lng };
    } else if (Array.isArray(p)) {
      return { lat: p[0], lng: p[1] };
    }
    return p;
  };
  
  // ✅ تحسين متقدم: في الاستدارات والتقاطعات، استخدم استراتيجية مختلفة
  let pointsToUse = points;
  
  if (hasSharpTurn || isIntersection) {
    // ✅ في الاستدارات والتقاطعات: استخدم نقاط أكثر ولكن بذكاء
    // نأخذ النقاط المهمة: البداية، النهاية، ونقاط في الوسط عند تغيير الاتجاه
    const importantPoints = [points[0]];
    
    let lastBearing = null;
    for (let i = 1; i < points.length - 1; i++) {
      const prev = normalizePoint(points[i - 1]);
      const current = normalizePoint(points[i]);
      const next = normalizePoint(points[i + 1]);
      
      const bearing1 = calculateBearingFromPoints(prev, current);
      const bearing2 = calculateBearingFromPoints(current, next);
      
      const angleDiff = Math.abs(bearing2 - bearing1);
      const normalizedAngle = angleDiff > 180 ? 360 - angleDiff : angleDiff;
      
      // ✅ إضافة النقاط عند تغيير الاتجاه (> 20 درجة)
      if (lastBearing === null || normalizedAngle > 20) {
        importantPoints.push(points[i]);
        lastBearing = bearing2;
      }
    }
    
    importantPoints.push(points[points.length - 1]);
    
    // ✅ إذا كان لدينا نقاط كافية (3+)، استخدمها
    if (importantPoints.length >= 3) {
      pointsToUse = importantPoints;
    }
  }
  
  // إنشاء مفتاح للتخزين المؤقت
  const cacheKey = pointsToUse.map(p => {
    const np = normalizePoint(p);
    return `${np.lat.toFixed(6)},${np.lng.toFixed(6)}`;
  }).join('|');
  
  // التحقق من التخزين المؤقت
  if (routeCache.has(cacheKey)) { // إذا كان المسار موجوداً في الكاش
    const cachedRoute = routeCache.get(cacheKey);
    drawRouteSegment(cachedRoute, startIndex, grouped);
    return;
  }
  
  // تجنب الطلبات المتكررة
  if (pendingRoutes.has(cacheKey)) {
    return; // إذا كان الطلب معلقاً بالفعل
  }
  
  pendingRoutes.add(cacheKey);
  
  try {
    const origin = normalizePoint(pointsToUse[0]);
    const destination = normalizePoint(pointsToUse[pointsToUse.length - 1]);
    
    // ✅ في الاستدارات الحادة، استخدم نقاط وسيطة أقل
    let waypoints = [];
    if (pointsToUse.length > 2) {
      waypoints = pointsToUse.slice(1, -1).map(p => {
        const np = normalizePoint(p);
        return {
          location: new google.maps.LatLng(np.lat, np.lng),
          stopover: false
        };
      });
    }

    const request = {
        origin: new google.maps.LatLng(origin.lat, origin.lng),
        destination: new google.maps.LatLng(destination.lat, destination.lng),
        waypoints: waypoints,
        travelMode: google.maps.TravelMode.DRIVING,
        optimizeWaypoints: false, // ❌ تم تعطيله لمنع إعادة ترتيب النقاط التي تسبب الخلط في المسار
        // ✅ خيارات متقدمة لتحسين الدقة
        alternatives: false, // لا نحتاج بدائل
        avoidHighways: false,
        avoidTolls: false,
        // ✅ إضافة: خيارات لتحسين الدقة في الاستدارات
        provideRouteAlternatives: false,
        region: 'IQ' // ✅ تحديد المنطقة (العراق) لتحسين الدقة
    };

    const data = await new Promise((resolve, reject) => {
        directionsService.route(request, (result, status) => {
            if (status === 'OK') {
                resolve(result);
            } else {
                reject(new Error('Directions request failed due to ' + status));
            }
        });
    });
    
    if (data.routes && data.routes.length > 0) {
      const route = data.routes[0];
      
      // ✅ تحسين: استخدام detailed path بدلاً من overview_path للدقة العالية
      // detailed path يحتوي على نقاط أكثر ويتبع الطرق بدقة أكبر
      let coordinates = route.overview_path;
      
      // ✅ محاولة الحصول على مسار أكثر تفصيلاً من legs
      if (route.legs && route.legs.length > 0) {
        const detailedPath = [];
        route.legs.forEach(leg => {
          if (leg.steps) {
            leg.steps.forEach(step => {
              if (step.path) {
                detailedPath.push(...step.path);
              }
            });
          }
        });
        
        // ✅ إذا كان المسار المفصل متوفراً وطويلاً بما فيه الكفاية، استخدمه
        if (detailedPath.length > coordinates.length * 0.8) {
          coordinates = detailedPath;
        }
      }
      
      // حفظ في التخزين المؤقت باستخدام بيانات Google الصحيحة (لتحسين الأداء)
      routeCache.set(cacheKey, {
        coordinates: coordinates, // ✅ استخدام المسار المفصل
        distance: route.legs.reduce((acc, leg) => acc + leg.distance.value, 0),
        duration: route.legs.reduce((acc, leg) => acc + leg.duration.value, 0)
      });
      // رسم القطعة
      drawRouteSegment(routeCache.get(cacheKey), startIndex, grouped);
    } else {
      // ✅ تحسين: في حالة الفشل، استخدم تنعيم ذكي بدلاً من خط مستقيم
      drawSmoothedSegment(points, startIndex, grouped);
    }
    
  } catch (error) {
    console.error('خطأ في جلب المسار من Google Directions:', error);
    // رسم خط مستقيم كبديل
    drawSmoothedSegment(points, startIndex, grouped);
  } finally {
    pendingRoutes.delete(cacheKey);
  }
}

// دالة رسم قطعة المسار (تلوين الخطوط بناءً على الحالة)
function drawRouteSegment(routeData, startIndex, grouped) {
  const { coordinates } = routeData;
  
  // تحديد خصائص الخط بناءً على حالة المجموعة
  const currentGroup = grouped[startIndex] || {};
  let lineColor = '#4CAF50'; // أخضر للحركة
  let lineWeight = 4;
  let lineOpacity = 0.85;
  let dashArray = null;
  let shadowColor = '#C8E6C9';

  if (currentGroup.status === 'بارك توقف') {
    lineColor = '#F44336'; // أحمر للتوقف
    lineWeight = 5;
    lineOpacity = 0.9;
    dashArray = '8, 4';
    shadowColor = '#FFCDD2'; // لون الظل
  }
  
  // رسم ظل الخط
  if (shadowColor) {
    const shadowSegment = new google.maps.Polyline({
        path: coordinates, // coordinates is already an array of {lat, lng}
        geodesic: true,
        strokeColor: shadowColor,
        strokeOpacity: 0.4,
        strokeWeight: lineWeight + 2,
        map: map
    });
    polylines.push(shadowSegment);
  }
  
  // رسم الخط الرئيسي
  const segment = new google.maps.Polyline({
    path: coordinates, // الإحداثيات هي مصفوفة من {lat, lng}
    geodesic: true,
    strokeColor: lineColor,
    strokeOpacity: lineOpacity,
    strokeWeight: lineWeight,
    map: map
  });
  
  // إضافة معلومات للخط عند النقر
  const content = `<b>مقطع المسار الذكي</b><br>
                   الحالة: ${currentGroup.status || 'غير محدد'}<br>
                   المدة: ${Math.round(currentGroup.duration || 0)} دقيقة<br>
                   نوع المسار: طريق فعلي`;
  segment.addListener('click', (e) => { infoWindow.setContent(content); infoWindow.setPosition(e.latLng); infoWindow.open(map); });

  
  polylines.push(segment);
}

// ✅ دالة احتياطية: رسم خط مستقيم (للتوافق مع الكود القديم)
function drawStraightSegment(points, startIndex, grouped) {
  drawSmoothedSegment(points, startIndex, grouped);
}

// ✅ دالة محسّنة: رسم خط منعّم بدلاً من خط مستقيم (في حالة فشل جلب المسار الفعلي)
function drawSmoothedSegment(points, startIndex, grouped) {
  const currentGroup = grouped[startIndex] || {};
  
  // ✅ تطبيق تنعيم على النقاط
  const smoothedPath = smoothPathPoints(points);
  
  let lineColor = '#2196F3'; // أزرق للخط المنعّم
  let lineWeight = 3;
  let lineOpacity = 0.7;
  
  if (currentGroup.status === 'بارك توقف') {
    lineColor = '#FF5722';
    lineWeight = 4;
  }
  
  const segment = new google.maps.Polyline({
    path: smoothedPath,
    geodesic: true, // ✅ مهم: يجعل الخط يتبع منحنى الأرض
    strokeColor: lineColor,
    strokeOpacity: lineOpacity,
    strokeWeight: lineWeight,
    map: map
  });

  const content = `<b>مقطع مسار منعّم</b><br>
                   الحالة: ${currentGroup.status || 'غير محدد'}<br>
                   نوع المسار: مسار منعّم (بدون محاذاة للطريق)`;
  segment.addListener('click', (e) => { infoWindow.setContent(content); infoWindow.setPosition(e.latLng); infoWindow.open(map); });

  polylines.push(segment);
}

// ✅ دالة جديدة: تنعيم النقاط باستخدام Bezier curves أو Catmull-Rom spline
function smoothPathPoints(points) {
  if (points.length < 3) return points;
  
  const normalizePoint = (p) => {
    if (typeof p === 'object' && 'lat' in p) {
      return { lat: p.lat, lng: p.lng };
    } else if (Array.isArray(p)) {
      return { lat: p[0], lng: p[1] };
    }
    return p;
  };
  
  const normalized = points.map(normalizePoint);
  const smoothed = [normalized[0]]; // البداية دائماً
  
  // ✅ تطبيق Catmull-Rom spline للتنعيم
  for (let i = 1; i < normalized.length - 1; i++) {
    const p0 = normalized[Math.max(0, i - 1)];
    const p1 = normalized[i];
    const p2 = normalized[Math.min(normalized.length - 1, i + 1)];
    
    // ✅ إضافة نقاط وسيطة منعّمة
    for (let t = 0.25; t < 1; t += 0.25) {
      const smoothedPoint = catmullRomSpline(p0, p1, p2, normalized[Math.min(normalized.length - 1, i + 2)] || p2, t);
      smoothed.push(smoothedPoint);
    }
  }
  
  smoothed.push(normalized[normalized.length - 1]); // النهاية دائماً
  
  return smoothed;
}

// ✅ دالة جديدة: Catmull-Rom spline للتنعيم
function catmullRomSpline(p0, p1, p2, p3, t) {
  const t2 = t * t;
  const t3 = t2 * t;
  
  const lat = 0.5 * (
    (2 * p1.lat) +
    (-p0.lat + p2.lat) * t +
    (2 * p0.lat - 5 * p1.lat + 4 * p2.lat - p3.lat) * t2 +
    (-p0.lat + 3 * p1.lat - 3 * p2.lat + p3.lat) * t3
  );
  
  const lng = 0.5 * (
    (2 * p1.lng) +
    (-p0.lng + p2.lng) * t +
    (2 * p0.lng - 5 * p1.lng + 4 * p2.lng - p3.lng) * t2 +
    (-p0.lng + 3 * p1.lng - 3 * p2.lng + p3.lng) * t3
  );
  
  return { lat, lng };
}

// دالة إضافة نقاط الاتجاه (لتحسين رؤية المسار)
function addDirectionMarkers(routePoints) {
  if (routePoints.length > 2) {
    const markerInterval = Math.max(1, Math.floor(routePoints.length / 8));
    
    for (let j = 1; j < routePoints.length - 1; j += markerInterval) {
      const p = routePoints[j];
      // ✅ دعم كلا التنسيقين: كائنات {lat, lng} أو مصفوفات [lat, lng]
      const lat = (typeof p === 'object' && 'lat' in p) ? p.lat : (Array.isArray(p) ? p[0] : p.lat);
      const lng = (typeof p === 'object' && 'lng' in p) ? p.lng : (Array.isArray(p) ? p[1] : p.lng);
      
      const directionMarker = new google.maps.Marker({
          position: { lat: lat, lng: lng },
          map: map,
          icon: {
              path: google.maps.SymbolPath.CIRCLE,
              scale: 3,
              fillColor: '#FF9800',
              fillOpacity: 0.8,
              strokeColor: '#F57C00',
              strokeWeight: 1
          }
      });
      
      polylines.push(directionMarker);
    }
  }
}

// دالة الرسم التقليدي كبديل (في حالة فشل المسار الذكي)
function drawFallbackRoute(routePoints, grouped) {
  console.log('استخدام الرسم التقليدي كبديل');
  
  for (let i = 0; i < routePoints.length - 1; i++) {
    const currentGroup = grouped[i] || {};
    
    let lineColor = '#4CAF50';
    let lineWeight = 4;
    let lineOpacity = 0.85;
    let dashArray = null;
    
    if (currentGroup.status === 'بارك توقف') {
      lineColor = '#F44336';
      lineWeight = 5;
      lineOpacity = 0.9;
      dashArray = '8, 4';
    }
    
    const segment = new google.maps.Polyline({
        path: [
            { lat: routePoints[i].lat, lng: routePoints[i].lng },
            { lat: routePoints[i + 1].lat, lng: routePoints[i + 1].lng }
        ],
        strokeColor: lineColor,
        strokeOpacity: lineOpacity,
        strokeWeight: lineWeight,
        map: map
    });
    
    polylines.push(segment);
  }
}


//----------------------------------------------------
//   دوال مساعدة
//----------------------------------------------------
function getDistance(lat1, lon1, lat2, lon2) { // حساب المسافة بين نقطتين باستخدام Google Maps Geometry Library
  const p1 = new google.maps.LatLng(lat1, lon1);
  const p2 = new google.maps.LatLng(lat2, lon2);
  return google.maps.geometry.spherical.computeDistanceBetween(p1, p2);
}

function convertTo24Hour(timeStr) {
  if (!timeStr) return null;
  timeStr = timeStr.trim();

  const regex = /^(\d{1,2}):(\d{1,2})(?:\s*([AP]M))?$/i;
  const match = timeStr.match(regex); // مطابقة الوقت

  if (!match) {
    console.warn("Invalid time format for conversion:", timeStr);
    return null;
  }

  let hours = parseInt(match[1], 10);
  let minutes = parseInt(match[2], 10);
  let ampm = match[3] ? match[3].toUpperCase() : null;

  if (minutes < 0 || minutes > 59) {
    console.warn("Invalid minutes in time:", timeStr);
    return null;
  }

  if (ampm) { // إذا كان هناك AM/PM
    if (hours < 1 || hours > 12) {
        console.warn("Invalid hours for AM/PM time:", timeStr);
        return null;
    }
    if (ampm === 'PM' && hours < 12) {
      hours += 12;
    } else if (ampm === 'AM' && hours === 12) { // 12 AM is 00 hours
      hours = 0;
    } // تحويل إلى 24 ساعة
  } else {
    if (hours < 0 || hours > 23) {
        console.warn("Invalid hours for 24-hour time:", timeStr);
        return null;
    }
  }

  const hh = (hours < 10) ? '0' + String(hours) : String(hours);
  const mm = (minutes < 10) ? '0' + String(minutes) : String(minutes);
  return hh + ":" + mm + ":00"; // Return with seconds for consistency if DB expects it
}

function formatTo12Hour(dateStr) {
    // إرجاع النص كما هو بدون أي تحويل لضمان تطابقه مع وقت الإرسال من التطبيق / قاعدة البيانات
    return dateStr || '';
}

/**
 * [جديد] دالة لتنسيق الوقت فقط بنظام 12 ساعة (ص/م)
 * @param {string} dateStr - السلسلة النصية للتاريخ والوقت
 * @returns {string} الوقت المنسق
 */
function formatTimeOnly12Hour(dateStr) {
    // تنسيق الوقت فقط بنظام 12 ساعة (ص/م) حسب التوقيت المرسل من السيرفر (بدون تغيير المنطقة الزمنية)
    if (!dateStr) return '';
    try {
        // نتوقع صيغة مثل "2025-11-29 08:18:54" أو "08:18:54"
        let timePart = dateStr;
        const spaceIndex = dateStr.indexOf(' ');
        if (spaceIndex !== -1) {
            timePart = dateStr.slice(spaceIndex + 1);
        }

        const parts = timePart.split(':');
        if (parts.length < 2) return timePart; // نرجع كما هو إذا لم تكن الصيغة متوقعة

        let hours = parseInt(parts[0], 10);
        const minutes = parts[1];
        if (isNaN(hours)) return timePart;

        const ampm = hours >= 12 ? 'م' : 'ص';
        hours = hours % 12;
        if (hours === 0) hours = 12;

        return `${hours}:${minutes} ${ampm}`;
    } catch (e) {
        return dateStr;
    }
}

function formatDuration(minutes) { // تنسيق المدة (دقائق، ساعات)
    if (minutes < 1) return currentLang === 'ar' ? 'أقل من دقيقة' : '< 1 min';
    
    const hours = Math.floor(minutes / 60);
    const mins = Math.round(minutes % 60);
    const minsStr = mins < 10 ? '0' + mins : String(mins);

    if (hours > 0) {
        return `${hours}:${minsStr}`;
    }
    return `${Math.round(minutes)} ${currentLang === 'ar' ? 'دقيقة' : 'min'}`;
}


function getPlaceName(lat, lng) { // جلب اسم المكان من Google Geocoding API
    return new Promise((resolve, reject) => {
        const geocoder = new google.maps.Geocoder();
        geocoder.geocode({ 'location': { lat: lat, lng: lng } }, (results, status) => {
            if (status === 'OK') {
                if (results[0]) {
                    resolve(results[0].formatted_address);
                } else {
                    resolve("مكان غير معروف");
                }
            } else {
                console.error("Geocoding failed due to: " + status);
                resolve("خطأ في تحديد المكان");
            }
        });
    });
}

/**
 * Enhanced HTML escaping with better performance
 * Prevents XSS attacks by escaping dangerous characters
 */
function htmlspecialchars(str) {
    if (typeof str !== 'string') return '';
    // Use a more efficient approach with a single pass
    const escapeMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;'
    };
    return str.replace(/[&<>"']/g, (match) => escapeMap[match]);
}

/**
 * Enhanced debounce function for performance optimization
 * Prevents excessive function calls
 */
function debounce(func, wait = 300) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

/**
 * Enhanced throttle function for performance optimization
 * Limits function execution frequency
 */
function throttle(func, limit = 300) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            func.apply(this, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

/**
 * Copy timeline time to clipboard
 */
async function copyTimelineTime(timeValue) {
    if (!timeValue) return;
    try {
        await navigator.clipboard.writeText(timeValue);
        showToast(currentLang === 'ar' ? '📋 تم نسخ الوقت' : 'Copied time to clipboard', 'success');
    } catch (err) {
        console.error('Clipboard copy failed:', err);
        showToast(currentLang === 'ar' ? '⚠️ تعذّر نسخ الوقت' : 'Unable to copy time', 'error');
    }
}

/**
 * Copy animation time to clipboard
 * Copies both full time and formatted time
 */
async function copyAnimationTime(fullTime, formattedTime) {
    if (!fullTime && !formattedTime) return;
    
    // Try to copy formatted time first, fallback to full time
    const textToCopy = formattedTime || fullTime;
    
    try {
        await navigator.clipboard.writeText(textToCopy);
        showToast(
            currentLang === 'ar' 
                ? `📋 تم نسخ الوقت: ${formattedTime || fullTime}` 
                : `Copied time: ${formattedTime || fullTime}`,
            'success',
            2000
        );
    } catch (err) {
        console.error('Clipboard copy failed:', err);
        
        // Fallback method for older browsers
        try {
            const textArea = document.createElement('textarea');
            textArea.value = textToCopy;
            textArea.style.position = 'fixed';
            textArea.style.left = '-999999px';
            textArea.style.top = '-999999px';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            const successful = document.execCommand('copy');
            document.body.removeChild(textArea);
            
            if (successful) {
                showToast(
                    currentLang === 'ar' 
                        ? `📋 تم نسخ الوقت: ${formattedTime || fullTime}` 
                        : `Copied time: ${formattedTime || fullTime}`,
                    'success',
                    2000
                );
            } else {
                throw new Error('execCommand failed');
            }
        } catch (fallbackErr) {
            console.error('Fallback copy failed:', fallbackErr);
            showToast(
                currentLang === 'ar' 
                    ? '⚠️ تعذّر نسخ الوقت. يرجى نسخه يدوياً.' 
                    : 'Unable to copy time. Please copy manually.',
                'error'
            );
        }
    }
}

/**
 * Copy stop time (entry or exit) to clipboard
 * Enhanced function for stop markers
 */
async function copyStopTime(fullTime, formattedTime, timeType) {
    if (!fullTime && !formattedTime) return;
    
    // Try to copy formatted time first, fallback to full time
    const textToCopy = formattedTime || fullTime;
    const typeText = timeType === 'دخول' ? 'وقت الدخول' : (timeType === 'خروج' ? 'وقت الخروج' : 'الوقت');
    
    try {
        await navigator.clipboard.writeText(textToCopy);
        showToast(
            currentLang === 'ar' 
                ? `📋 تم نسخ ${typeText}: ${formattedTime || fullTime}` 
                : `Copied ${timeType} time: ${formattedTime || fullTime}`,
            'success',
            2000
        );
    } catch (err) {
        console.error('Clipboard copy failed:', err);
        
        // Fallback method for older browsers
        try {
            const textArea = document.createElement('textarea');
            textArea.value = textToCopy;
            textArea.style.position = 'fixed';
            textArea.style.left = '-999999px';
            textArea.style.top = '-999999px';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            const successful = document.execCommand('copy');
            document.body.removeChild(textArea);
            
            if (successful) {
                showToast(
                    currentLang === 'ar' 
                        ? `📋 تم نسخ ${typeText}: ${formattedTime || fullTime}` 
                        : `Copied ${timeType} time: ${formattedTime || fullTime}`,
                    'success',
                    2000
                );
            } else {
                throw new Error('execCommand failed');
            }
        } catch (fallbackErr) {
            console.error('Fallback copy failed:', fallbackErr);
            showToast(
                currentLang === 'ar' 
                    ? `⚠️ تعذّر نسخ ${typeText}. يرجى نسخه يدوياً.` 
                    : `Unable to copy ${timeType} time. Please copy manually.`,
                'error'
            );
        }
    }
}


//----------------------------------------------------
//    تنزيل سجلات التوقف بصيغة XLSX (Excel)
//----------------------------------------------------
function downloadLogsXLSX() {
  // تصدير سجلات التوقف فقط ومدة لا تقل عن 5 دقائق
  var filtered = logs.filter(l => {
    if (l.type !== 'stop') return false;
    if (!l.entryTime || !l.exitTime) return false;
    var diff = (new Date(l.exitTime).getTime() - new Date(l.entryTime).getTime()) / 60000;
    return diff >= 5;
  });

  if (filtered.length === 0) {
    showToast("لا توجد سجلات للتنزيل.");
    return;
  }

  var ws_data = [["اسم المكان", "وقت الدخول", "وقت الخروج", "الحالة", "البطارية"]];
  filtered.forEach(l => {
    ws_data.push([
      l.place_name || l.placeName || '—',
      formatTo12Hour(l.entryTime),
      formatTo12Hour(l.exitTime),
      l.status || 'توقف',
      l.batteryRange || '—'
    ]);
  });

  var wb = XLSX.utils.book_new();
  var ws = XLSX.utils.aoa_to_sheet(ws_data); // تحويل البيانات إلى ورقة عمل
  ws['!cols'] = [
    { wch: 40 }, { wch: 25 }, { wch: 25 }, { wch: 15 }, { wch: 20 }
  ];
  XLSX.utils.book_append_sheet(wb, ws, "سجلات التوقف");
  XLSX.writeFile(wb, "stop_logs.xlsx");
  showToast("تم تنزيل ملف Excel بنجاح");
}

//----------------------------------------------------
//   Enhanced Device Filtering with Performance Optimization
//----------------------------------------------------
// تحسينات البحث المتقدمة
const filterDevices = debounce(function() {
  const inputEl = document.getElementById("searchDevice");
  if (!inputEl) return;
  
  const input = inputEl.value.trim().toUpperCase();
  let visibleCount = 0;
  
  // ✅ إذا كان حقل البحث فارغاً، إظهار جميع العناصر
  if (!input) {
    // إظهار جميع الأجهزة غير المجمعة
    const ul = document.getElementById("deviceList");
    if (ul) {
      const lis = ul.querySelectorAll("li[data-device-id]");
      lis.forEach(li => {
        li.style.display = "";
      });
    }
    
    // إظهار جميع المجموعات والأجهزة داخلها
    const groupHeaders = document.querySelectorAll("li.group-header");
    groupHeaders.forEach(groupHeader => {
      groupHeader.style.display = "";
      const groupId = groupHeader.getAttribute('onclick')?.match(/toggleGroupDevices\((\d+)\)/)?.[1];
      if (groupId) {
        const groupDevicesUl = document.getElementById(`group-devices-${groupId}`);
        if (groupDevicesUl) {
          // الحفاظ على حالة العرض الحالية (مفتوحة/مغلقة)
          const currentDisplay = window.getComputedStyle(groupDevicesUl).display;
          if (currentDisplay !== 'none') {
            groupDevicesUl.style.display = "block";
          }
          // إظهار جميع الأجهزة داخل المجموعة
          const groupDevices = groupDevicesUl.querySelectorAll("li[data-device-id]");
          groupDevices.forEach(deviceLi => {
            deviceLi.style.display = "";
          });
        }
      }
    });
    return; // إنهاء الدالة إذا كان البحث فارغاً
  }
  
  // دعم البحث المتقدم (حالة الجهاز، آخر ظهور، إلخ)
  const searchFilters = {
    active: input.includes('نشط') || input.includes('🟢'),
    inactive: input.includes('غير نشط') || input.includes('⚪'),
    query: input.replace(/نشط|غير نشط|🟢|⚪/g, '').trim()
  };
  
  // Use requestAnimationFrame for smooth filtering
  requestAnimationFrame(() => {
    // ✅ البحث في الأجهزة غير المجمعة
    const ul = document.getElementById("deviceList");
    if (ul) {
      const lis = ul.querySelectorAll("li[data-device-id]");
      for (let i = 0; i < lis.length; i++) {
        const li = lis[i];
        const txt = (li.textContent || li.innerText).toUpperCase();
        const deviceName = li.getAttribute('data-device-name')?.toUpperCase() || '';
        
        // فلترة حسب حالة الجهاز
        const isActive = li.classList.contains('device-active');
        if (searchFilters.active && !isActive) {
          li.style.display = "none";
          continue;
        }
        if (searchFilters.inactive && isActive) {
          li.style.display = "none";
          continue;
        }
        
        // البحث في النص
        const matches = !searchFilters.query || txt.indexOf(searchFilters.query) > -1 || deviceName.indexOf(searchFilters.query) > -1;
        
        if (matches) {
          li.style.display = "";
          li.style.animation = 'slideInLeft 0.2s ease';
          visibleCount++;
        } else {
          li.style.display = "none";
        }
      }
    }
    
    // ✅ البحث في المجموعات والأجهزة داخل المجموعات
    const groupHeaders = document.querySelectorAll("li.group-header");
    for (let i = 0; i < groupHeaders.length; i++) {
      const groupHeader = groupHeaders[i];
      const groupName = (groupHeader.textContent || groupHeader.innerText).toUpperCase();
      const groupId = groupHeader.getAttribute('onclick')?.match(/toggleGroupDevices\((\d+)\)/)?.[1];
      const groupDevicesUl = groupId ? document.getElementById(`group-devices-${groupId}`) : null;
      
      let groupHasMatches = false;
      
      // البحث في أجهزة المجموعة
      if (groupDevicesUl) {
        const groupDevices = groupDevicesUl.querySelectorAll("li[data-device-id]");
        let groupDeviceCount = 0;
        
        for (let j = 0; j < groupDevices.length; j++) {
          const deviceLi = groupDevices[j];
          const deviceTxt = (deviceLi.textContent || deviceLi.innerText).toUpperCase();
          const deviceName = deviceLi.getAttribute('data-device-name')?.toUpperCase() || '';
          
          // فلترة حسب حالة الجهاز
          const isActive = deviceLi.classList.contains('device-active');
          if (searchFilters.active && !isActive) {
            deviceLi.style.display = "none";
            continue;
          }
          if (searchFilters.inactive && isActive) {
            deviceLi.style.display = "none";
            continue;
          }
          
          const deviceMatches = !searchFilters.query || deviceTxt.indexOf(searchFilters.query) > -1 || deviceName.indexOf(searchFilters.query) > -1 || groupName.indexOf(searchFilters.query) > -1;
          
          if (deviceMatches) {
            deviceLi.style.display = "";
            groupHasMatches = true;
            groupDeviceCount++;
            visibleCount++;
          } else {
            deviceLi.style.display = "none";
          }
        }
        
        // إظهار/إخفاء المجموعة بناءً على النتائج
        if (!searchFilters.query || groupName.indexOf(searchFilters.query) > -1 || groupHasMatches) {
          groupHeader.style.display = "";
          groupDevicesUl.style.display = "block"; // إظهار الأجهزة عند البحث
          visibleCount++;
        } else {
          groupHeader.style.display = "none";
          groupDevicesUl.style.display = "none";
        }
      } else {
        // إذا لم توجد أجهزة في المجموعة، اعرضها فقط إذا تطابق اسم المجموعة
        if (!searchFilters.query || groupName.indexOf(searchFilters.query) > -1) {
          groupHeader.style.display = "";
          visibleCount++;
        } else {
          groupHeader.style.display = "none";
        }
      }
    }
    
    // Show message if no results
    if (input && visibleCount === 0) {
      showToast('لا توجد نتائج للبحث', 'info', 2000);
    }
  });
}, 200); // Debounce with 200ms delay

/**
 * معالج حدث النقر الموحد لجميع الأجهزة في القائمة الجانبية
 * عند النقر على أي جهاز (مجمع أو غير مجمع)، يتم تحديد الجهاز وجلب آخر موقع له.
 */
function setupDeviceListClickHandler() {
    const sidebar = document.querySelector(".sidebar"); // القائمة الجانبية

    if (sidebar) {
        // إزالة أي معالج سابق لتجنب التكرار
        sidebar.removeEventListener("click", handleDeviceClick, false);
        
        // إضافة معالج جديد في bubbling phase (بعد onclick في HTML)
        sidebar.addEventListener("click", handleDeviceClick, false);
        
        console.log('✅ تم إعداد معالج النقر للأجهزة');
    } else {
        console.error('❌ القائمة الجانبية غير موجودة');
        // إعادة المحاولة بعد قليل
        setTimeout(setupDeviceListClickHandler, 500);
    }
}

function handleDeviceClick(e) {
    // تجاهل النقر على رأس المجموعة (group-header) - السماح لـ toggleGroupDevices بالعمل
    const groupHeader = e.target.closest('.group-header');
    if (groupHeader) {
        // لا نفعل شيء، دع onclick في HTML يعمل
        // لا نستخدم stopPropagation هنا حتى يعمل toggleGroupDevices
        return;
    }
    
    // تجاهل النقر على العناصر داخل group-header (مثل الروابط)
    if (e.target.closest('.group-header a') || e.target.closest('.group-header button') || e.target.closest('.group-header form')) {
        return;
    }
    
    // تجاهل النقر المباشر على الروابط والأزرار (لكن السماح بالنقر على العناصر داخل li)
    if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON' || e.target.tagName === 'FORM' || e.target.closest('form')) {
        return; // السماح للروابط والأزرار بالعمل بشكل طبيعي
    }
    
    // استهداف العنصر `li` الذي يحتوي على بيانات الجهاز
    const targetLi = e.target.closest("li[data-device-id]");
    
    // إذا لم نجد عنصر li، لا نفعل شيء
    if (!targetLi) {
        return;
    }
    
    // تجاهل النقر على الروابط والأزرار داخل li
    if (e.target.closest('a.delete-btn') || e.target.closest('a.edit-btn') || e.target.closest('a') || e.target.closest('button')) {
        return;
    }

    // إذا وصلنا هنا، يعني أننا نقرنا على عنصر جهاز صالح
    e.preventDefault(); // منع أي إجراءات افتراضية
    e.stopPropagation(); // منع انتشار الحدث

    const deviceId = targetLi.getAttribute("data-device-id");
    let deviceName = targetLi.getAttribute("data-device-name");
        
        // إذا لم يكن device-name موجوداً، استخرجه من النص
        if (!deviceName) {
            const deviceNameSpan = targetLi.querySelector('.device-name');
            if (deviceNameSpan) {
                // استخراج النص من span فقط، بدون الأيقونات
                const clone = deviceNameSpan.cloneNode(true);
                const indicators = clone.querySelectorAll('.device-status-indicator');
                indicators.forEach(ind => ind.remove());
                deviceName = clone.textContent.trim();
            } else {
                deviceName = targetLi.textContent.trim();
            }
            // إزالة أي أزرار أو روابط من النص
            deviceName = deviceName.replace(/حذف|تعديل/g, '').trim();
        }

        if (!deviceId || !deviceName) {
            console.warn('⚠️ بيانات الجهاز غير مكتملة:', { deviceId, deviceName });
            return;
        }

        console.log('🖱️ تم النقر على الجهاز:', deviceName, deviceId);

        // تحديث الواجهة
        const deviceSelect = document.getElementById("deviceSelect");
        const selectedDeviceNameEl = document.getElementById("selectedDeviceName");

        if (deviceSelect) {
            // التحقق مما إذا كان الجهاز موجودًا بالفعل في القائمة المنسدلة
            let optionExists = Array.from(deviceSelect.options).some(opt => opt.value === deviceId);
            if (!optionExists) {
                // إذا لم يكن موجودًا، قم بإضافته وتحديده
                const newOption = new Option(deviceName, deviceId, true, true);
                deviceSelect.add(newOption);
            }
            deviceSelect.value = deviceId;
            
            // إطلاق حدث change لضمان تحديث الواجهة
            deviceSelect.dispatchEvent(new Event('change'));
        }

        if (selectedDeviceNameEl) {
            selectedDeviceNameEl.textContent = deviceName;
        }

        if (typeof showToast === 'function') {
            showToast(`تم تحديد: ${deviceName}. جاري جلب آخر موقع...`);
        }
        
        if (typeof fetchLatestLocation === 'function') {
            fetchLatestLocation(); // جلب آخر موقع للجهاز المحدد
        } else {
            console.error('❌ دالة fetchLatestLocation غير موجودة');
        }
}

// تهيئة معالج النقر عند تحميل الصفحة
document.addEventListener('DOMContentLoaded', setupDeviceListClickHandler);

// ✅ التأكد من إظهار جميع الأجهزة والمجموعات عند تحميل الصفحة
document.addEventListener('DOMContentLoaded', function() {
  // التأكد من أن حقل البحث فارغ
  const searchInput = document.getElementById("searchDevice");
  if (searchInput) {
    searchInput.value = "";
  }
  
  // إظهار جميع العناصر بشكل صريح بعد تحميل الصفحة
  setTimeout(() => {
    // إظهار جميع الأجهزة غير المجمعة
    const deviceList = document.getElementById("deviceList");
    if (deviceList) {
      const devices = deviceList.querySelectorAll("li[data-device-id]");
      devices.forEach(device => {
        device.style.display = "";
        device.style.visibility = "visible";
      });
    }
    
    // إظهار جميع المجموعات
    const groupHeaders = document.querySelectorAll("li.group-header");
    groupHeaders.forEach(header => {
      header.style.display = "";
      header.style.visibility = "visible";
    });
    
    // إظهار جميع الأجهزة داخل المجموعات
    const groupDevicesLists = document.querySelectorAll("ul.group-devices");
    groupDevicesLists.forEach(list => {
      const devices = list.querySelectorAll("li[data-device-id]");
      devices.forEach(device => {
        device.style.display = "";
        device.style.visibility = "visible";
      });
    });
    
    // إظهار الأقسام نفسها
    const sidebarSections = document.querySelectorAll(".sidebar-section");
    sidebarSections.forEach(section => {
      section.style.display = "";
      section.style.visibility = "visible";
    });
  }, 300);
});

// ✅ إعادة إظهار العناصر عند تحميل الصفحة بالكامل
window.addEventListener('load', function() {
  setTimeout(() => {
    // إظهار جميع الأجهزة غير المجمعة
    const deviceList = document.getElementById("deviceList");
    if (deviceList) {
      const devices = deviceList.querySelectorAll("li[data-device-id]");
      devices.forEach(device => {
        device.style.display = "";
        device.style.visibility = "visible";
      });
    }
    
    // إظهار جميع المجموعات
    const groupHeaders = document.querySelectorAll("li.group-header");
    groupHeaders.forEach(header => {
      header.style.display = "";
      header.style.visibility = "visible";
    });
    
    // إظهار الأقسام نفسها
    const sidebarSections = document.querySelectorAll(".sidebar-section");
    sidebarSections.forEach(section => {
      section.style.display = "";
      section.style.visibility = "visible";
    });
  }, 500);
});

// إعادة المحاولة بعد تحميل كامل للصفحة
window.addEventListener('load', function() {
    setTimeout(setupDeviceListClickHandler, 100);
});

// توسيع/طي أجهزة المجموعة
function toggleGroupDevices(groupId) {
  console.log('🔄 toggleGroupDevices called for group:', groupId);
  
  var el = document.getElementById("group-devices-" + groupId); // عنصر قائمة الأجهزة
  var headerEl = document.querySelector(`.group-header[onclick*="toggleGroupDevices(${groupId})"]`);
  
  if (!el) {
    console.error('❌ لم يتم العثور على عنصر المجموعة:', "group-devices-" + groupId);
    return;
  }

  // التحقق من الحالة الحالية
  const computedStyle = window.getComputedStyle(el);
  const currentDisplay = el.style.display || computedStyle.display;
  const isHidden = currentDisplay === "none" || currentDisplay === "";

  if (isHidden) {
    // إظهار الأجهزة
    el.style.display = "block";
    if (headerEl) {
      headerEl.classList.add('active');
    }
    console.log('✅ تم توسيع المجموعة:', groupId, '- display:', el.style.display);
  } else {
    // إخفاء الأجهزة
    el.style.display = "none";
    if (headerEl) {
      headerEl.classList.remove('active');
    }
    console.log('✅ تم طي المجموعة:', groupId);
  }
}

// التأكد من أن toggleGroupDevices متاح في النطاق العام
window.toggleGroupDevices = toggleGroupDevices;

//----------------------------------------------------
//   تبديل اللغة (Translations)
//----------------------------------------------------
const translations = {
    en: {
        appTitle: "Almanara - Tracking System",
        deviceListTitle: "Devices & Groups",
        searchDevicePlaceholder: "Search device...",
        lblChooseDevice: "Choose Device:",
        lblDate: "Date:",
        lblTimeFrom: "From (12h):",
        lblTimeTo: "To (12h):", // ترجمة عناصر التحكم
        btnSearch: "🔍 Search",
        btnLatestLoc: "📡 Live Location",
        btnShare: "🔗 Share",
        lblAnimSpeed: "Animation Speed (ms):", // ترجمة عناصر الحركة
        btnPlay: "▶️ Play",
        btnStop: "⏹ Stop",
        btnResetAnimation: "↩️ Reset Anim.",
        optAllDevices: "All Devices",
        lblSelectedDeviceNamePrefix: "Selected Device:",
        selectedDeviceNameDefault: "No device selected",
        logsTitle: "Activity Timeline",
        btnDownloadExcel: "📥 Excel (XLSX)",
        lblLogsSearch: "Search in logs:",
        btnResetLogsFilter: "Show All",
        thTime: "Time",
        thActivity: "Activity / Place",
        thDuration: "Duration / Distance",
        analyticsTitle: "Data Analytics",
        lblTotalDist: "Total Distance",
        lblAvgSpeed: "Average Speed",
        logout: "Logout",
        adminPanel: "Admin Panel",
        langToggle: "العربية",
        // Settings
        lblThStopMinDuration: "Min Stop Duration (min)",
        lblThStationaryThreshold: "Max Stop Radius (m)",
        lblThStopMaxSpeed: "Max Stop Speed (km/h)",
        lblThDrivingMinSpeed: "Min Driving Speed (km/h)",
        lblThDrivingMinSegment: "Min Driving Duration (min)",
        lblThDrivingMinDistance: "Min Driving Distance (m)",
        btnCloseSettings: "✖ Close", // ترجمة إعدادات العتبات
        btnSaveThresholds: "💾 Save & Apply",

    },
    ar: {
        appTitle: "Almanara - نظام التتبع",
        deviceListTitle: "الأجهزة والمجموعات",
        searchDevicePlaceholder: "🔍 ابحث عن جهاز...",
        lblChooseDevice: "🔽 اختر الجهاز:",
        lblDate: "📅 اختر التاريخ:",
        lblTimeFrom: "⏰ من (12h):",
        lblTimeTo: "⏰ إلى (12h):", // ترجمة عناصر التحكم
        btnSearch: "🔍 بحث",
        btnLatestLoc: "📡 آخر موقع مباشر",
        btnShare: "🔗 مشاركة الموقع",
        lblAnimSpeed: "⚡ سرعة الحركة (ملّي ثانية):", // ترجمة عناصر الحركة
        btnPlay: "▶️ تشغيل الحركة",
        btnStop: "⏹ إيقاف الحركة",
        btnResetAnimation: "↩️ رجوع إلى البداية",
        optAllDevices: "جميع الأجهزة",
        lblSelectedDeviceNamePrefix: "اسم الجهاز المختار:",
        selectedDeviceNameDefault: "لا يوجد جهاز محدد",
        logsTitle: "المخطط الزمني للنشاط",
        btnDownloadExcel: "📥 Excel (XLSX)",
        lblLogsSearch: "بحث في السجلات:",
        btnResetLogsFilter: "إعادة الكل",
        thTime: "الوقت",
        thActivity: "النشاط / المكان",
        thDuration: "المدة / المسافة",
        analyticsTitle: "تحليل البيانات",
        lblTotalDist: "المسافة الإجمالية", // ترجمة التحليلات
        lblAvgSpeed: "متوسط السرعة",
        logout: "خروج",
        adminPanel: "لوحة الأدمن",
        langToggle: "English",
        // Settings
        lblThStopMinDuration: "أقل مدة للتوقف (دقيقة)",
        lblThStationaryThreshold: "أقصى انتشار للتوقف (متر)",
        lblThStopMaxSpeed: "أقصى سرعة للتوقف (كم/س)",
        lblThDrivingMinSpeed: "أدنى سرعة للقيادة (كم/س)",
        lblThDrivingMinSegment: "أقل مدة قيادة (دقيقة)",
        lblThDrivingMinDistance: "أقل مسافة قيادة (متر)",
        btnCloseSettings: "✖ إغلاق", // ترجمة إعدادات العتبات
        btnSaveThresholds: "💾 حفظ وتطبيق",
    }
};

function applyTranslations(lang) {
    const trans = translations[lang];
    const setText = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val; };
    const setHTML = (id, val) => { const el = document.getElementById(id); if (el) el.innerHTML = val; };

    setText("appTitle", trans.appTitle);
    setText("deviceListTitle", trans.deviceListTitle);
    const searchDeviceEl = document.getElementById("searchDevice");
    if (searchDeviceEl) searchDeviceEl.placeholder = trans.searchDevicePlaceholder;
    setText("lblChooseDevice", trans.lblChooseDevice);
    setText("lblDate", trans.lblDate);
    setText("lblTimeFrom", trans.lblTimeFrom);
    setText("lblTimeTo", trans.lblTimeTo); // تطبيق الترجمة على عناصر التحكم
    setHTML("btnSearch", trans.btnSearch);
    setHTML("btnLatestLoc", trans.btnLatestLoc);
    setHTML("btnShare", trans.btnShare);
    // عناصر التحكم بالحركة تم إزالتها من الواجهة الرئيسية لتبسيطها
    setText("optAllDevices", trans.optAllDevices);

    const selectedDeviceNameStrong = document.getElementById("lblSelectedDeviceName");
    if (selectedDeviceNameStrong) selectedDeviceNameStrong.textContent = trans.lblSelectedDeviceNamePrefix;
    const selectedDeviceNameSpan = document.getElementById("selectedDeviceName");
    if (selectedDeviceNameSpan && selectedDeviceNameSpan.textContent === translations[currentLang === 'ar' ? 'en' : 'ar'].selectedDeviceNameDefault) {
        selectedDeviceNameSpan.textContent = trans.selectedDeviceNameDefault;
    }

    setText("logsTitle", trans.logsTitle);
    setHTML("btnDownloadExcel", trans.btnDownloadExcel);
    setText("lblLogsSearch", trans.lblLogsSearch);
    setText("btnResetLogsFilter", trans.btnResetLogsFilter);
    setText("thTime", trans.thTime);
    setText("thActivity", trans.thActivity);
    setText("thDuration", trans.thDuration);

    // ترجمة عناوين التحليلات
    setText("analyticsTitle", trans.analyticsTitle);
    setText("lblTotalDist", trans.lblTotalDist);
    setText("lblAvgSpeed", trans.lblAvgSpeed);

    const logoutBtn = document.getElementById("btnLogout");
    if (logoutBtn) logoutBtn.textContent = trans.logout;
    const adminLink = document.querySelector(".top-nav .actions a[href='admin.php']");
    if (adminLink) adminLink.textContent = trans.adminPanel;
    setText("langLabel", trans.langToggle);
    
    // Settings Panel
    setText("lblThStopMinDuration", trans.lblThStopMinDuration);
    setText("lblThStationaryThreshold", trans.lblThStationaryThreshold);
    setText("lblThStopMaxSpeed", trans.lblThStopMaxSpeed);
    setText("lblThDrivingMinSpeed", trans.lblThDrivingMinSpeed);
    setText("lblThDrivingMinSegment", trans.lblThDrivingMinSegment);
    setText("lblThDrivingMinDistance", trans.lblThDrivingMinDistance);
    setText("btnCloseSettings", trans.btnCloseSettings);
    setText("btnSaveThresholds", trans.btnSaveThresholds);

    document.documentElement.lang = lang;
}

// تبديل اللغة وحفظ التفضيل
function toggleLanguage() {
  currentLang = (currentLang === "ar") ? "en" : "ar";
  localStorage.setItem('preferredLang', currentLang);
}

// Load preferred language on page load
document.addEventListener('DOMContentLoaded', function() { // تحميل اللغة المفضلة عند تحميل الصفحة
    const preferredLang = localStorage.getItem('preferredLang');
    if (preferredLang && preferredLang !== currentLang) { // if stored lang is different from default
        currentLang = preferredLang;
    }
});

//************************************************
//   [NEW] دالة جلب سجلات التوقف المحسنة من الخادم
//************************************************
/*
function getStopLogsForDevice(deviceId) { // جلب سجلات التوقف المحسنة
  // إظهار رسالة تحميل في الجدول
  const tbody = document.getElementById("logsTable")?.getElementsByTagName("tbody")[0];
  if (!tbody) { console.error("Timeline table body not found."); return; }
  tbody.innerHTML = '<tr><td colspan="5" style="text-align:center; padding: 20px;">جاري جلب سجلات التوقف...</td></tr>';
  // تمرير التاريخ المحدد إن وجد
  const dateEl = document.getElementById("dateSelect");
  const timeFromEl = document.getElementById("timeFrom");
  const timeToEl   = document.getElementById("timeTo");
  const dateVal = dateEl ? dateEl.value : "";
  const timeFrom = timeFromEl ? convertTo24Hour(timeFromEl.value.trim()) : "";
  const timeTo   = timeToEl   ? convertTo24Hour(timeToEl.value.trim())   : "";

  let url = `get_device_stops_optimized.php?device_id=${encodeURIComponent(deviceId)}`;
  if ((timeFrom || timeTo) && dateVal) {
    const fromDate = `${dateVal} ${timeFrom || '00:00:00'}`;
    const toDate   = `${dateVal} ${timeTo   || '23:59:59'}`;
    url += `&from_date=${encodeURIComponent(fromDate)}&to_date=${encodeURIComponent(toDate)}`;
  } else if (dateVal) {
    url += `&date=${encodeURIComponent(dateVal)}`;
  }
  // نقطة النهاية الجديدة تحلل جميع المقاطع، والفلترة تتم في الواجهة الأمامية للمخطط الزمني
  // So we don't need min_seconds here.
  url += `&t=${Date.now()}`;

  fetch(url)
    .then(res => {
        if (!res.ok) {
            return res.text().then(text => {
                console.error('Server error response:', text);
                throw new Error(`HTTP error! status: ${res.status}`);
            });
        }
        return res.text().then(text => {
            try {
                return JSON.parse(text);
            } catch (e) {
                console.error("Failed to parse JSON:", text);
                throw new Error("Invalid JSON response");
            }
        });
    })
    .then(data => {
      if (data.status === "success" && data.stops.length > 0) {
        // نقطة النهاية الجديدة ترجع مخططاً زمنياً كاملاً، وليس فقط توقفات
        logs = data.stops;
      } else {
        logs = [];
      }
      updateLogsTable();
    })
    .catch(err => {
      console.error('خطأ في جلب سجلات التوقف المحسنة:', err);
      tbody.innerHTML = '<tr><td colspan="3" style="text-align:center; padding: 20px;">حدث خطأ أثناء جلب البيانات.</td></tr>';
    });
}
*/

/**
 * [تم التعديل] دالة للحصول على أيقونة بناءً على نوع المكان
 * @param {string} placeType - نوع المكان (e.g., 'restaurant', 'home')
 * @returns {string} الأيقونة المناسبة (Emoji)
 */
function getIconForPlaceType(placeType = 'parking') {
    const iconMapping = {
        'user_defined': '📍',
        'home': '🏠',
        'work': '💼',
        'office': '🏢',
        'restaurant': '🍴',
        'cafe': '☕',
        'store': '🏬',
        'supermarket': '🛒',
        'mall': '🛍️',
        'bank': '🏦',
        'gas_station': '⛽',
        'parking': '🅿️',
        'school': '🏫',
        'hospital': '🏥',
        'mosque': '🕌'
        // Add more as needed
    };
    // البحث عن النوع المطابق الأول
    const key = (placeType || 'parking').split('_')[0];
    return iconMapping[key] || '🅿️'; // Default to parking icon
}

//----------------------------------------------------
//   دوال اللوحات الجديدة (Analytics, Alerts, Geofencing)
//----------------------------------------------------

/**
 * عرض لوحة الإحصائيات
 */
function showAnalytics() {
    // انتظار قليلاً للتأكد من تحميل DOM
    setTimeout(function() {
        const panel = document.getElementById('analyticsPanel');
        if (!panel) {
            console.error('❌ لوحة الإحصائيات غير موجودة في DOM');
            if (typeof showToast === 'function') {
                showToast('لوحة الإحصائيات غير متاحة', 'error');
            } else {
                alert('لوحة الإحصائيات غير متاحة');
            }
            return;
        }
        
        panel.style.display = 'flex';
        
        // جلب قائمة الأجهزة من القائمة الجانبية
        const deviceItems = document.querySelectorAll('li[data-device-id]');
        const select = document.getElementById('analyticsDeviceSelect');
        if (select) {
            select.innerHTML = '<option value="">اختر الجهاز</option>';
            deviceItems.forEach(item => {
                const deviceId = item.getAttribute('data-device-id');
                const deviceName = item.getAttribute('data-device-name');
                if (deviceId && deviceName) {
                    const option = document.createElement('option');
                    option.value = deviceId;
                    option.textContent = deviceName;
                    select.appendChild(option);
                }
            });
            
            // إذا كان هناك جهاز محدد، حدده
            const deviceSelect = document.getElementById('deviceSelect');
            if (deviceSelect && deviceSelect.value) {
                const analyticsDeviceSelect = document.getElementById('analyticsDeviceSelect');
                if (analyticsDeviceSelect) {
                    analyticsDeviceSelect.value = deviceSelect.value;
                }
            }
        }
    }, 100);
}

/**
 * عرض لوحة التنبيهات
 */
function showAlerts() {
    // انتظار قليلاً للتأكد من تحميل DOM
    setTimeout(function() {
        const panel = document.getElementById('alertsPanel');
        if (!panel) {
            console.error('❌ لوحة التنبيهات غير موجودة في DOM');
            if (typeof showToast === 'function') {
                showToast('لوحة التنبيهات غير متاحة', 'error');
            } else {
                alert('لوحة التنبيهات غير متاحة');
            }
            return;
        }
        
        panel.style.display = 'flex';
        
        // تحديث عدد التنبيهات
        if (typeof updateAlertsBadge === 'function') {
            updateAlertsBadge();
        }
    }, 100);
}

/**
 * تحديث عدد التنبيهات في الشارة
 */
function updateAlertsBadge() {
    fetch('get_alerts.php?limit=1')
        .then(res => {
            if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
            return res.text().then(text => {
                try {
                    return JSON.parse(text);
                } catch (e) {
                    console.error("Failed to parse JSON:", text);
                    throw new Error("Invalid JSON response");
                }
            });
        })
        .then(data => {
            const badge = document.getElementById('alertsBadge');
            if (badge) {
                if (data.count > 0) {
                    badge.textContent = data.count;
                    badge.style.display = 'inline';
                } else {
                    badge.style.display = 'none';
                }
            }
        })
        .catch(err => {
            console.error('❌ خطأ في تحديث عدد التنبيهات:', err);
        });
}

/**
 * عرض لوحة المناطق الجغرافية
 */
function showGeofencing() {
    // انتظار قليلاً للتأكد من تحميل DOM
    setTimeout(function() {
        const panel = document.getElementById('geofencingPanel');
        if (!panel) {
            console.error('❌ لوحة المناطق الجغرافية غير موجودة في DOM');
            if (typeof showToast === 'function') {
                showToast('لوحة المناطق الجغرافية غير متاحة', 'error');
            } else {
                alert('لوحة المناطق الجغرافية غير متاحة');
            }
            return;
        }
        
        panel.style.display = 'flex';
    }, 100);
}

/**
 * تفعيل/تعطيل عرض جميع الأجهزة
 */
function toggleMultiDeviceView() {
    if (typeof multiDeviceView === 'undefined') {
        showToast('نظام عرض الأجهزة المتعددة غير متاح', 'error');
        return;
    }
    
    const btn = document.getElementById('btnMultiDevice');
    if (multiDeviceView.isEnabled) {
        multiDeviceView.disable();
        if (btn) {
            btn.classList.remove('active');
            btn.textContent = '👥 جميع الأجهزة';
        }
        showToast('تم تعطيل عرض جميع الأجهزة', 'info');
    } else {
        multiDeviceView.enable();
        if (btn) {
            btn.classList.add('active');
            btn.textContent = '👥 إخفاء الكل';
        }
        showToast('تم تفعيل عرض جميع الأجهزة', 'success');
    }
}
