<?php
session_start();
require_once 'config.php';
// @author Ibrahim Al-Mansour

header('Content-Type: application/json; charset=utf-8');

// التحقق من تسجيل الدخول
if (!isset($_SESSION['user_id'])) {
    http_response_code(401);
    echo json_encode(['status' => 'error', 'message' => 'غير مسموح بالوصول']);
    exit;
}

// إنشاء جدول التخزين المؤقت إذا لم يكن موجوداً
try {
    $conn->exec("
        CREATE TABLE IF NOT EXISTS `places_cache` (
          `id` INT AUTO_INCREMENT PRIMARY KEY,
          `lat` DECIMAL(10, 7) NOT NULL,
          `lng` DECIMAL(10, 7) NOT NULL,
          `place_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
          `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
          UNIQUE KEY `lat_lng_idx` (`lat`, `lng`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    ");
} catch (PDOException $e) {
    error_log("خطأ في إنشاء الجدول: " . $e->getMessage());
}

$input = file_get_contents('php://input');
$data = json_decode($input, true);

if (empty($data['locations'])) {
    echo json_encode(['status' => 'error', 'message' => 'لا توجد مواقع لإجراء الهندسة العكسية']);
    exit;
}

$results = [];

foreach ($data['locations'] as $location) {
    // التحقق من وجود الإحداثيات
    if (!isset($location['lat']) || !isset($location['lng'])) {
        continue;
    }

    $lat = floatval($location['lat']);
    $lng = floatval($location['lng']);
    
    // تنسيق الإحداثيات للتخزين والبحث
    $lat_rounded = round($lat, 5);
    $lng_rounded = round($lng, 5);
    $cacheKey = "{$lat_rounded},{$lng_rounded}";

    // 1. البحث في الكاش أولاً
    $stmt = $conn->prepare("SELECT place_name, place_type, confidence_score FROM places_cache WHERE lat_rounded = :lat AND lng_rounded = :lng LIMIT 1");
    $stmt->execute([':lat' => $lat_rounded, ':lng' => $lng_rounded]);
    $cached = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if ($cached && !empty($cached['place_name']) && !str_starts_with($cached['place_name'], 'موقع')) {
        // إزالة أي بادئة قديمة مثل "أقرب معلم:" من الكاش لضمان تنسيق موحّد
        $cachedName = preg_replace('/^\s*أقرب\s+معلم:\s*/u', '', $cached['place_name']);
        $results[$cacheKey] = $cachedName;
        continue;
    }

    // 2. إذا لم يكن في الكاش، جلب الاسم من APIs
    $placeInfo = getHighAccuracyPlaceName($lat, $lng, $google_maps_api_key);
    
    // 3. حفظ النتيجة في الكاش
    try {
        $stmt = $conn->prepare("INSERT INTO places_cache (lat_rounded, lng_rounded, place_name, place_type, confidence_score, updated_at) VALUES (:lat, :lng, :place_name, :place_type, :confidence, NOW()) ON DUPLICATE KEY UPDATE place_name = VALUES(place_name), place_type = VALUES(place_type), confidence_score = VALUES(confidence_score), updated_at = NOW(), access_count = access_count + 1");
        $stmt->execute([':lat' => $lat_rounded, ':lng' => $lng_rounded, ':place_name' => $placeInfo['name'], ':place_type' => $placeInfo['type'], ':confidence' => $placeInfo['confidence']]);
    } catch (PDOException $e) {
        error_log("خطأ في حفظ الكاش: " . $e->getMessage());
    }

    $results[$cacheKey] = $placeName;
    
    // تأخير بين الطلبات لتجنب rate limiting
    usleep(300000); // 0.3 ثانية
}

echo json_encode(['status' => 'success', 'places' => $results], JSON_UNESCAPED_UNICODE);

// الدالة الرئيسية للحصول على أفضل اسم مكان (تم إعادة تسميتها وتوحيدها مع get_device_stops_optimized)
function getHighAccuracyPlaceName($lat, $lng, $apiKey) {
    $defaultResult = ['name' => 'موقع غير محدد', 'type' => 'unknown', 'confidence' => 0];
    $lat_str = number_format($lat, 6, '.', '');
    $lng_str = number_format($lng, 6, '.', '');

    $geocodingResults = getPlaceFromGeocodingAPI($lat, $lng, $apiKey);
    if ($geocodingResults) {
        // استخراج المكونات التفصيلية من نتائج Geocoding
        $comp = extractAddressComponentsDetailed($geocodingResults);

        $parts = [];
        if (!empty($comp['administrative_area_level_1'])) { // المحافظة
            $parts[] = $comp['administrative_area_level_1'];
        }
        // المدينة/القضاء (الأولوية للقضاء ثم المدينة)
        $cityOrDistrict = $comp['administrative_area_level_2'] ?? $comp['locality'] ?? null;
        if (!empty($cityOrDistrict)) {
            $parts[] = $cityOrDistrict;
        }
        // الحي أو المنطقة الفرعية
        $neigh = $comp['neighborhood'] ?? $comp['sublocality'] ?? null;
        if (!empty($neigh)) {
            $parts[] = $neigh;
        }
        // الشارع
        if (!empty($comp['route']) && mb_stripos($comp['route'], 'unnamed') === false && mb_stripos($comp['route'], 'بدون اسم') === false) {
            $parts[] = $comp['route'];
        }

        // إزالة التكرارات البسيطة
        $seen = [];
        $uniqueParts = [];
        foreach ($parts as $p) {
            $key = trim(mb_strtolower($p));
            if (!isset($seen[$key])) {
                $seen[$key] = true;
                $uniqueParts[] = $p;
            }
        }

        // أقرب معلم (POI)
        $nearestPoi = getPlaceFromPlacesAPI($lat, $lng, $apiKey, 150);
        if (!empty($nearestPoi)) {
            // تجنب تكرار المعلم إن كان مطابقاً لأحد الأجزاء (بناءً على الاسم فقط)
            $poiLower = mb_strtolower($nearestPoi['name']);
            $dup = false;
            foreach ($uniqueParts as $up) {
                if (mb_strtolower($up) === $poiLower) { $dup = true; break; }
            }
            if (!$dup) { // إذا لم يكن مكرراً، أضفه
                $uniqueParts[] = $nearestPoi['name'];
            }
        }

        if (!empty($uniqueParts)) {
            return implode('، ', array_slice($uniqueParts, 0, 5));
        }

        // احتياطي: استخدام الصياغة السابقة الذكية
        $bestInfo = extractBestAddressComponentV2($geocodingResults);
        if ($bestInfo) {
            return $bestInfo;
        }
    }

    // المحاولة الاحتياطية: Places API بنصف قطر أكبر
    $placesWiderName = getPlaceFromPlacesAPI($lat, $lng, $apiKey, 200); // جلب من Places API
    if ($placesWiderName && $placesWiderName !== "موقع {$lat_str}, {$lng_str}") {
        return $placesWiderName;
    }

    return "موقع {$lat_str}, {$lng_str}";
} // نهاية الدالة الرئيسية

// دالة Google Places API محسنة
function getPlaceFromPlacesAPI($lat, $lng, $apiKey, $radius = 50) { // جلب من Places API
    $url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?" . http_build_query([
        'location' => "{$lat},{$lng}",
        'radius' => $radius,
        'key' => $apiKey,
        'language' => 'ar',
        'rankby' => 'prominence'
    ]);
    
    $response = makeAPIRequest($url);
    
    if (!$response) {
        return null;
    }
    
    $data = json_decode($response, true);
    
    if ($data['status'] === 'OK' && !empty($data['results'])) {
        // [تحسين] البحث عن أفضل نتيجة غير عامة
        // نأخذ أول نتيجة ونقوم بتنسيقها
        $bestResult = $data['results'][0];
        return [
            'name' => formatPlacesResult($bestResult),
            'type' => determinePlaceType($bestResult['types']),
            'confidence' => 90, // ثقة عالية
            'address' => $bestResult['vicinity'] ?? '',
            'types' => $bestResult['types'],
            'source' => 'nearby'
        ];
    }
    
    return null;
}

// حساب نقاط الجودة للنتيجة
function calculatePlaceScore($place, $targetLat, $targetLng, $source = 'places') {
    $score = 0; // نقاط الجودة
    
    // [تحسين] توسيع نطاق الأحياء والمناطق الفرعية ورفع أولوية الشوارع
    $topPriorityTypes = [
        'neighborhood' => 120, 'sublocality' => 115, 'sublocality_level_1' => 110, 'sublocality_level_2' => 105, 'sublocality_level_3' => 100,
    ];
    $mediumPriorityTypes = [
        'route' => 80,
        'street_address' => 60,
    ];
    
    // أنواع غير مرغوب فيها
    $poiTypes = [
        'premise' => 10,
        'point_of_interest' => 5,
        'establishment' => 5,
        'store' => 5,
        'food' => 5,
        'restaurant' => 5,
        'cafe' => 5,
    ];
    $lowPriorityTypes = [
        'locality' => 5, // مدينة
        'political' => 2, // محافظة أو دولة
    ];
    
    // حساب نقاط النوع
    if (isset($place['types'])) {
        foreach ($place['types'] as $type) {
            if (isset($topPriorityTypes[$type])) {
                $score += $topPriorityTypes[$type];
            } elseif (isset($mediumPriorityTypes[$type])) {
                $score += $mediumPriorityTypes[$type];
            } elseif (isset($poiTypes[$type])) {
                $score += $poiTypes[$type];
            } elseif (isset($lowPriorityTypes[$type])) {
                $score += $lowPriorityTypes[$type];
            }
        }
    }
    
    // نقاط التصنيف
    if (isset($place['rating']) && $place['rating'] > 0) {
        $score += $place['rating'] * 2;
    }
    
    // نقاط عدد المراجعات
    if (isset($place['user_ratings_total']) && $place['user_ratings_total'] > 0) {
        $score += min($place['user_ratings_total'] / 100, 5);
    }
    
    // نقاط القرب (الأماكن الأقرب أفضل)
    if (isset($place['geometry']['location'])) {
        $distance = calculateDistance($targetLat, $targetLng, $place['geometry']['location']['lat'], $place['geometry']['location']['lng']);
        $score -= $distance * 10; // خصم نقاط للمسافة
    }

    // نقاط إضافية للمصدر
    if ($source === 'geocoding') {
        $score += 20; // Geocoding أفضل للعناوين
    } else {
        $score -= 10; // Places API يميل للأماكن التجارية
    }
    
    return $score;
}

// دالة Google Geocoding API محسنة
function getPlaceFromGeocodingAPI($lat, $lng, $apiKey) { // جلب من Geocoding API
    $url = "https://maps.googleapis.com/maps/api/geocode/json?" . http_build_query([
        'latlng' => "{$lat},{$lng}",
        'key' => $apiKey,
        'language' => 'ar',
        // توسيع نطاق الأنواع ليشمل المدينة والمناطق الإدارية لتأمين مكونات عنوان أكثر ثراءً
        'result_type' => 'premise|point_of_interest|street_address|route|neighborhood|sublocality|locality|administrative_area_level_3|administrative_area_level_2|administrative_area_level_1|political'
    ]);
    
    $response = makeAPIRequest($url);
    
    if (!$response) {
        return null;
    }
    
    $data = json_decode($response, true);
    
    if ($data['status'] === 'OK' && !empty($data['results'])) {
        // [إعادة هيكلة] إرجاع جميع النتائج ليتم تحليلها بواسطة الدالة الذكية
        return $data['results'];
    }
    
    return null;
}

// حساب نقاط جودة نتائج Geocoding
// function calculateGeocodingScore($geocodeResult) {
//     // تم دمج هذا المنطق في `calculatePlaceScore`
//     return 0;
// }

// تنسيق نتيجة Places API
function formatPlacesResult($place) { // تنسيق نتيجة Places API
    $name = $place['name'];
    
    // تجنب إضافة اسم المدينة إذا كان موجوداً بالفعل في اسم المكان
    // if (isset($place['vicinity']) && strpos($name, $place['vicinity']) === false) {
    //     $name .= " - " . $place['vicinity'];
    // }
    
    return $name;
}

/**
 * استخراج مكونات العنوان التفصيلية من نتائج Geocoding
 */
function extractAddressComponentsDetailed($geocodingResults) { // استخراج مكونات العنوان
    $components = [
        'route' => null,
        'neighborhood' => null,
        'sublocality' => null,
        'locality' => null, // مدينة
        'administrative_area_level_2' => null, // قضاء/منطقة
        'administrative_area_level_1' => null, // محافظة
    ];

    foreach ($geocodingResults as $result) {
        if (empty($result['address_components'])) continue;
        foreach ($result['address_components'] as $component) {
            $types = $component['types'] ?? [];
            $name = $component['long_name'] ?? '';
            if ($name === '') continue;
            foreach ($types as $type) {
                if (array_key_exists($type, $components) && $components[$type] === null) {
                    if ($type === 'route' && (mb_stripos($name, 'unnamed') !== false || mb_stripos($name, 'بدون اسم') !== false)) {
                        continue;
                    }
                    $components[$type] = $name;
                    break;
                }
            }
        }
    }
    return $components;
}

// تنسيق نتيجة Geocoding API
// function formatGeocodingResult($geocodeResult) {
//     $address = $geocodeResult['formatted_address'];
//     return $address; // تم استبدال هذا المنطق بالدالة الجديدة
// }

/**
 * تحديد نوع المكان (تم نقله من get_device_stops_optimized.php)
 */
function determinePlaceType($types) {
    $typeMapping = [
        'home_graph' => 'home', 'work' => 'work', 'office' => 'office',
        'restaurant' => 'restaurant', 'cafe' => 'cafe', 'store' => 'store',
        'shopping_mall' => 'mall', 'supermarket' => 'supermarket', 'bank' => 'bank',
        'gas_station' => 'gas_station', 'parking' => 'parking', 'school' => 'school',
        'hospital' => 'hospital', 'mosque' => 'mosque', 'premise' => 'premise',
        'street_address' => 'street', 'point_of_interest' => 'point_of_interest',
        'route' => 'street', 'neighborhood' => 'neighborhood',
        'sublocality' => 'sublocality', 'locality' => 'locality',
        'administrative_area_level_1' => 'administrative_area_level_1',
        'administrative_area_level_2' => 'administrative_area_level_2',
    ];
    
    foreach ($types as $type) {
        if (isset($typeMapping[$type])) {
            return $typeMapping[$type];
        }
    }
    return 'point_of_interest';
}

/**
 * [دالة موحدة] تستخرج أفضل مكون عنوان (حي، منطقة، شارع) من مجموعة نتائج
 * هذه هي الدالة الأساسية الآن لضمان الدقة
 */
function extractBestAddressComponentV2($geocodingResults) {
    if (empty($geocodingResults)) {
        return null;
    }

    // تجميع المكونات المفيدة عبر جميع النتائج لتكوين اسم مركّب
    $components = [
        'route' => null,
        'neighborhood' => null,
        'sublocality' => null,
        'locality' => null, // City
        'administrative_area_level_2' => null, // District
        'administrative_area_level_1' => null, // Province
    ];

    foreach ($geocodingResults as $result) { // تجميع المكونات
        if (!isset($result['address_components'])) continue;
        foreach ($result['address_components'] as $component) {
            $types = $component['types'] ?? [];
            $name = $component['long_name'] ?? '';
            if (empty($name)) continue;

            // Find the first matching type and store it if not already found
            foreach ($types as $type) {
                if (array_key_exists($type, $components) && $components[$type] === null) {
                    // Special handling for unnamed roads
                    if ($type === 'route' && (mb_stripos($name, 'unnamed road') !== false || mb_stripos($name, 'طريق بدون اسم') !== false)) {
                        continue;
                    }
                    $components[$type] = $name;
                    break; // Move to next component
                }
            }
        }
    }

    // تركيب الاسم النهائي بترتيب الأولوية: شارع، حي، منطقة، مدينة
    $parts = []; // بناء الأجزاء
    if ($components['route']) $parts[] = $components['route'];
    if ($components['neighborhood']) $parts[] = $components['neighborhood'];
    if ($components['sublocality']) $parts[] = $components['sublocality'];
    
    // Add city/province if it's not redundant
    $cityComponent = $components['locality'] ?: $components['administrative_area_level_2'] ?: $components['administrative_area_level_1'];
    if ($cityComponent) {
        $parts[] = $cityComponent;
    }

    // إزالة التكرارات وجعل النتيجة فريدة
    if (!empty($parts)) {
        $seen = []; // لتتبع التكرارات
        $unique = [];
        foreach ($parts as $p) {
            $key = trim(mb_strtolower($p));
            // Check for redundancy (e.g., "Al Mansour" and "Al Mansour District")
            $isRedundant = false;
            foreach ($seen as $s_key => $val) {
                if (mb_strpos($s_key, $key) !== false || mb_strpos($key, $s_key) !== false) {
                    $isRedundant = true;
                    break;
                }
            }
            if (!$isRedundant) {
                $seen[$key] = true;
                $unique[] = $p;
            }
        }
        if (!empty($unique)) {
            // عرض أول 3 مكونات كحد أقصى
            return implode('، ', array_slice($unique, 0, 3));
        }
    }

    // [آلية احتياطية] إذا فشل كل شيء، استخدم أول عنوان منسق
    $tokens = [];
    foreach ($geocodingResults as $result) { // البحث عن عنوان منسق
        if (!empty($result['formatted_address'])) {
            $fa = $result['formatted_address'];
            // تقسيم بحسب الفاصلة العربية، وإلا الإنجليزية
            $partsFA = preg_split('/\s*،\s*|\s*,\s*/u', $fa);
            foreach ($partsFA as $tok) {
                $t = trim($tok);
                if ($t === '') continue;
                $lower = mb_strtolower($t);
                // تجاهل الطرق غير المسماة والأجزاء الرقمية البحتة
                if ($lower === 'unnamed road' || mb_strpos($lower, 'طريق بدون اسم') !== false) continue;
                if (preg_match('/^[0-9\-\s]+$/u', $t)) continue;
                $tokens[] = $t;
            }
        }
    }
    if (!empty($tokens)) {
        // إزالة التكرار
        $seen = [];
        $unique = [];
        foreach ($tokens as $t) {
            $key = trim(mb_strtolower($t));
            if (!isset($seen[$key])) {
                $seen[$key] = true;
                $unique[] = $t;
            }
        }
        if (!empty($unique)) {
            return implode('، ', array_slice($unique, 0, 3));
        }
    }

    // لم يتم العثور على مكونات كافية
    return [
        'name' => $geocodingResults[0]['formatted_address'] ?? 'موقع غير محدد',
        'type' => determinePlaceType($geocodingResults[0]['types'] ?? []),
        'confidence' => 50];
}

// حساب المسافة بين نقطتين
function calculateDistance($lat1, $lng1, $lat2, $lng2) {
    $earthRadius = 6371; // كيلومتر
    
    $dLat = deg2rad($lat2 - $lat1);
    $dLng = deg2rad($lng2 - $lng1);
    
    $a = sin($dLat/2) * sin($dLat/2) +
         cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
         sin($dLng/2) * sin($dLng/2);
    
    $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    
    return $earthRadius * $c;
}

// دالة مساعدة لطلبات API
function makeAPIRequest($url) {
    $ch = curl_init();
    curl_setopt_array($ch, [ // إعدادات cURL
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200 && !empty($response)) {
        return $response;
    }
    
    return false;
}
?>