<?php
/**
 * Enhanced Contacts Upload with Automatic Duplicate Removal
 * نظام رفع جهات الاتصال مع تصفية التكرار التلقائي
 * 
 * @version 2.0
 */

header('Content-Type: application/json; charset=UTF-8');
require 'config.php';

/**
 * دالة تنظيف التكرارات التلقائي
 * يتم استدعاؤها بعد كل عملية رفع
 */
function removeDuplicatesAutomatically($connection) {
    $removedCount = 0;
    
    try {
        // استراتيجية 1: حذف التكرارات بناءً على رقم الهاتف
        $duplicates = $connection->query("
            SELECT device_id, phone_number, GROUP_CONCAT(id ORDER BY uploaded_at DESC) as ids
            FROM device_contacts
            WHERE phone_number IS NOT NULL AND phone_number != ''
            GROUP BY device_id, phone_number
            HAVING COUNT(*) > 1
        ")->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($duplicates as $dup) {
            $ids = explode(',', $dup['ids']);
            if (count($ids) > 1) {
                $idsToDelete = array_slice($ids, 1);
                $placeholders = implode(',', array_fill(0, count($idsToDelete), '?'));
                $deleteStmt = $connection->prepare("DELETE FROM device_contacts WHERE id IN ($placeholders)");
                $deleteStmt->execute($idsToDelete);
                $removedCount += $deleteStmt->rowCount();
            }
        }
        
        // استراتيجية 2: حذف التكرارات بناءً على البريد الإلكتروني
        $duplicatesEmail = $connection->query("
            SELECT device_id, email, GROUP_CONCAT(id ORDER BY uploaded_at DESC) as ids
            FROM device_contacts
            WHERE email IS NOT NULL AND email != '' AND email LIKE '%@%'
            GROUP BY device_id, email
            HAVING COUNT(*) > 1
        ")->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($duplicatesEmail as $dup) {
            $ids = explode(',', $dup['ids']);
            if (count($ids) > 1) {
                $idsToDelete = array_slice($ids, 1);
                $placeholders = implode(',', array_fill(0, count($idsToDelete), '?'));
                $deleteStmt = $connection->prepare("DELETE FROM device_contacts WHERE id IN ($placeholders)");
                $deleteStmt->execute($idsToDelete);
                $removedCount += $deleteStmt->rowCount();
            }
        }
        
    } catch (PDOException $e) {
        error_log("Auto cleanup error: " . $e->getMessage());
    }
    
    return ['removed' => $removedCount];
}

// التحقق من أن الطلب هو POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
    exit;
}

try {
    // التحقق من وجود الجدول وإصلاحه إذا لزم الأمر
    try {
        $checkTable = $conn->query("SHOW TABLES LIKE 'device_contacts'");
        if ($checkTable->rowCount() == 0) {
            // إنشاء الجدول إذا لم يكن موجوداً
            $conn->exec("
                CREATE TABLE device_contacts (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    device_id VARCHAR(255) NOT NULL,
                    device_name VARCHAR(255) DEFAULT NULL,
                    contact_name VARCHAR(255) DEFAULT NULL,
                    phone_number VARCHAR(50) DEFAULT NULL,
                    email VARCHAR(255) DEFAULT NULL,
                    organization VARCHAR(255) DEFAULT NULL,
                    notes TEXT DEFAULT NULL,
                    uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                    INDEX idx_device_id (device_id),
                    INDEX idx_uploaded_at (uploaded_at),
                    INDEX idx_device_uploaded (device_id, uploaded_at),
                    UNIQUE KEY unique_device_contact (device_id, contact_name, phone_number, email)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");
        } else {
            // إضافة جميع الأعمدة المطلوبة إذا لم تكن موجودة
            // نستخدم طريقة أكثر أماناً: التحقق أولاً ثم الإضافة
            $requiredColumns = [
                'device_name' => 'VARCHAR(255) DEFAULT NULL',
                'contact_name' => 'VARCHAR(255) DEFAULT NULL',
                'phone_number' => 'VARCHAR(50) DEFAULT NULL',
                'email' => 'VARCHAR(255) DEFAULT NULL',
                'organization' => 'VARCHAR(255) DEFAULT NULL',
                'notes' => 'TEXT DEFAULT NULL',
                'uploaded_at' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP',
            ];
            
            // الحصول على قائمة الأعمدة الموجودة
            $existingColumns = [];
            try {
                $columnsResult = $conn->query("SHOW COLUMNS FROM device_contacts");
                while ($row = $columnsResult->fetch(PDO::FETCH_ASSOC)) {
                    $existingColumns[] = $row['Field'];
                }
            } catch (PDOException $e) {
                error_log("Warning: Could not get existing columns: " . $e->getMessage());
            }
            
            // إضافة الأعمدة المفقودة
            foreach ($requiredColumns as $columnName => $columnType) {
                if (!in_array($columnName, $existingColumns)) {
                    try {
                        // تحديد موضع العمود
                        $afterColumn = 'device_id';
                        if ($columnName === 'device_name') {
                            $afterColumn = 'device_id';
                        } elseif ($columnName === 'contact_name') {
                            $afterColumn = in_array('device_name', $existingColumns) ? 'device_name' : 'device_id';
                        } elseif ($columnName === 'phone_number') {
                            $afterColumn = in_array('contact_name', $existingColumns) ? 'contact_name' : (in_array('device_name', $existingColumns) ? 'device_name' : 'device_id');
                        } elseif ($columnName === 'email') {
                            $afterColumn = in_array('phone_number', $existingColumns) ? 'phone_number' : (in_array('contact_name', $existingColumns) ? 'contact_name' : 'device_id');
                        } elseif ($columnName === 'organization') {
                            $afterColumn = in_array('email', $existingColumns) ? 'email' : (in_array('phone_number', $existingColumns) ? 'phone_number' : 'device_id');
                        } elseif ($columnName === 'notes') {
                            $afterColumn = in_array('organization', $existingColumns) ? 'organization' : (in_array('email', $existingColumns) ? 'email' : 'device_id');
                        } elseif ($columnName === 'uploaded_at') {
                            $afterColumn = in_array('notes', $existingColumns) ? 'notes' : (in_array('organization', $existingColumns) ? 'organization' : 'device_id');
                        }
                        
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$columnName}` {$columnType} AFTER `{$afterColumn}`");
                        error_log("Added column: {$columnName}");
                    } catch (PDOException $addError) {
                        error_log("Error adding column {$columnName}: " . $addError->getMessage());
                    }
                }
            }
            
            // إضافة الفهارس إذا لم تكن موجودة
            try {
                $indexesResult = $conn->query("SHOW INDEXES FROM device_contacts");
                $existingIndexes = [];
                while ($row = $indexesResult->fetch(PDO::FETCH_ASSOC)) {
                    $existingIndexes[] = $row['Key_name'];
                }
                
                $indexes = [
                    'idx_device_id' => 'device_id',
                    'idx_uploaded_at' => 'uploaded_at',
                    'unique_device_contact' => 'device_id, contact_name, phone_number, email'
                ];
                
                foreach ($indexes as $indexName => $columns) {
                    if (!in_array($indexName, $existingIndexes)) {
                        try {
                            // unique_device_contact يجب أن يكون فهرس فريد
                            if ($indexName === 'unique_device_contact') {
                                $conn->exec("CREATE UNIQUE INDEX {$indexName} ON device_contacts ({$columns})");
                            } else {
                                $conn->exec("CREATE INDEX {$indexName} ON device_contacts ({$columns})");
                            }
                        } catch (PDOException $indexError) {
                            error_log("Warning: Could not add index {$indexName}: " . $indexError->getMessage());
                        }
                    }
                }
                
                // فهرس مركب إضافي (إذا لم يكن موجوداً)
                $compositeIndexName = 'idx_device_uploaded';
                if (!in_array($compositeIndexName, $existingIndexes)) {
                    try {
                        $conn->exec("CREATE INDEX {$compositeIndexName} ON device_contacts (device_id, uploaded_at)");
                    } catch (PDOException $indexError) {
                        error_log("Warning: Could not add composite index: " . $indexError->getMessage());
                    }
                }
            } catch (PDOException $e) {
                error_log("Warning: Could not check/add indexes: " . $e->getMessage());
            }
        }
    } catch (PDOException $e) {
        // تجاهل الأخطاء في التحقق، سنحاول المتابعة
        error_log("Warning: Could not check/fix table structure: " . $e->getMessage());
    }
    
    // التحقق النهائي: التأكد من أن جميع الأعمدة موجودة قبل المتابعة
    try {
        $finalCheck = $conn->query("SHOW COLUMNS FROM device_contacts");
        $finalColumns = [];
        while ($row = $finalCheck->fetch(PDO::FETCH_ASSOC)) {
            $finalColumns[] = $row['Field'];
        }
        
        $requiredColumns = ['device_id', 'device_name', 'contact_name', 'phone_number', 'email', 'organization', 'notes', 'uploaded_at'];
        $missingColumns = array_diff($requiredColumns, $finalColumns);
        
        if (!empty($missingColumns)) {
            error_log("Warning: Missing columns: " . implode(', ', $missingColumns));
            // محاولة إضافة الأعمدة المفقودة مرة أخرى بدون AFTER clause
            foreach ($missingColumns as $col) {
                try {
                    if ($col === 'device_name') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` VARCHAR(255) DEFAULT NULL");
                    } elseif ($col === 'contact_name') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` VARCHAR(255) DEFAULT NULL");
                    } elseif ($col === 'phone_number') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` VARCHAR(50) DEFAULT NULL");
                    } elseif ($col === 'email') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` VARCHAR(255) DEFAULT NULL");
                    } elseif ($col === 'organization') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` VARCHAR(255) DEFAULT NULL");
                    } elseif ($col === 'notes') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` TEXT DEFAULT NULL");
                    } elseif ($col === 'uploaded_at') {
                        $conn->exec("ALTER TABLE device_contacts ADD COLUMN `{$col}` TIMESTAMP DEFAULT CURRENT_TIMESTAMP");
                    }
                } catch (PDOException $e) {
                    error_log("Final attempt to add {$col} failed: " . $e->getMessage());
                }
            }
        }
    } catch (PDOException $e) {
        error_log("Final column check failed: " . $e->getMessage());
    }
    
    // قراءة البيانات المرسلة
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    
    if (!$data) {
        throw new Exception('Invalid JSON data');
    }
    
    // التحقق من البيانات المطلوبة
    if (empty($data['device_id'])) {
        throw new Exception('device_id is required');
    }
    
    if (empty($data['contacts']) || !is_array($data['contacts'])) {
        throw new Exception('contacts array is required');
    }
    
    $deviceId = trim($data['device_id']);
    $deviceName = isset($data['device_name']) ? trim($data['device_name']) : null;
    $contacts = $data['contacts'];
    
    // بدء المعاملة
    $conn->beginTransaction();
    
    // حذف جهات الاتصال القديمة لهذا الجهاز (اختياري - يمكنك الاحتفاظ بها)
    // $deleteStmt = $conn->prepare("DELETE FROM device_contacts WHERE device_id = ?");
    // $deleteStmt->execute([$deviceId]);
    
    /**
     * Enhanced Duplicate Prevention System
     * نظام محسّن لمنع التكرار عند الإدخال
     */
    
    // ✅ تحسين: توحيد تنسيق أرقام الهواتف قبل الإدخال
    // إزالة المسافات والأحرف الخاصة لتسهيل المقارنة
    function normalizePhoneNumber($phone) {
        if (empty($phone)) return null;
        // إزالة المسافات والأحرف الخاصة
        $normalized = preg_replace('/[\s\-\(\)\+]/', '', $phone);
        return !empty($normalized) ? $normalized : null;
    }
    
    // ✅ تحسين: توحيد تنسيق البريد الإلكتروني
    function normalizeEmail($email) {
        if (empty($email)) return null;
        return strtolower(trim($email));
    }
    
    // ✅ تحسين: توحيد تنسيق الاسم
    function normalizeContactName($name) {
        if (empty($name)) return null;
        return trim($name);
    }
    
    // إدراج جهات الاتصال الجديدة مع منع التكرار المحسّن
    // نستخدم فهرس فريد على (device_id, contact_name, phone_number, email)
    // إذا كانت جهة الاتصال موجودة يتم تحديثها فقط بدون إنشاء سجل مكرر
    $insertStmt = $conn->prepare("
        INSERT INTO device_contacts 
        (device_id, device_name, contact_name, phone_number, email, organization, notes) 
        VALUES (?, ?, ?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE
            device_name = VALUES(device_name),
            contact_name = VALUES(contact_name),
            phone_number = VALUES(phone_number),
            email = VALUES(email),
            organization = VALUES(organization),
            notes = VALUES(notes),
            uploaded_at = CURRENT_TIMESTAMP
    ");
    
    // ✅ تحسين: فحص التكرار قبل الإدخال بناءً على رقم الهاتف فقط
    // إذا كان نفس رقم الهاتف موجوداً، نحدث السجل الموجود بدلاً من إنشاء جديد
    $checkPhoneStmt = $conn->prepare("
        SELECT id FROM device_contacts 
        WHERE device_id = ? AND phone_number = ? 
        LIMIT 1
    ");
    
    $insertedCount = 0;
    $updatedCount = 0;
    $skippedCount = 0;
    
    foreach ($contacts as $contact) {
        // ✅ تحسين: توحيد تنسيق البيانات قبل المعالجة
        $contactName = isset($contact['name']) ? normalizeContactName($contact['name']) : null;
        $phoneNumber = isset($contact['phone']) ? normalizePhoneNumber($contact['phone']) : null;
        $email = isset($contact['email']) ? normalizeEmail($contact['email']) : null;
        $organization = isset($contact['organization']) ? trim($contact['organization']) : null;
        $notes = isset($contact['notes']) ? trim($contact['notes']) : null;
        
        // تخطي جهات الاتصال بدون اسم أو رقم هاتف
        if (empty($contactName) && empty($phoneNumber)) {
            $skippedCount++;
            continue;
        }
        
        // ✅ تحسين: فحص التكرار بناءً على رقم الهاتف قبل الإدخال
        // إذا كان نفس رقم الهاتف موجوداً لنفس الجهاز، نحدث السجل الموجود
        if (!empty($phoneNumber)) {
            $checkPhoneStmt->execute([$deviceId, $phoneNumber]);
            $existing = $checkPhoneStmt->fetch(PDO::FETCH_ASSOC);
            
            if ($existing) {
                // تحديث السجل الموجود بدلاً من إنشاء جديد
                $updateStmt = $conn->prepare("
                    UPDATE device_contacts 
                    SET device_name = ?,
                        contact_name = ?,
                        phone_number = ?,
                        email = ?,
                        organization = ?,
                        notes = ?,
                        uploaded_at = CURRENT_TIMESTAMP
                    WHERE id = ?
                ");
                $updateStmt->execute([
                    $deviceName,
                    $contactName,
                    $phoneNumber,
                    $email,
                    $organization,
                    $notes,
                    $existing['id']
                ]);
                $updatedCount++;
                continue;
            }
        }
        
        // إدراج جديد إذا لم يكن موجوداً
        $insertStmt->execute([
            $deviceId,
            $deviceName,
            $contactName,
            $phoneNumber,
            $email,
            $organization,
            $notes
        ]);
        
        // في MySQL: 1 = INSERT جديد، 2 = UPDATE بسبب ON DUPLICATE KEY
        $affected = $insertStmt->rowCount();
        if ($affected === 1) {
            $insertedCount++;
        } elseif ($affected === 2) {
            $updatedCount++;
        }
    }
    
    // تأكيد المعاملة
    $conn->commit();
    
    // ✅ تحسين: تشغيل تنظيف التكرارات التلقائي بعد كل رفع
    // يتم تنظيف التكرارات تلقائياً بعد كل عملية رفع
    $autoCleaned = 0;
    try {
        // استدعاء دالة تنظيف التكرارات (بدون معاملة منفصلة)
        $cleanupResult = removeDuplicatesAutomatically($conn);
        $autoCleaned = isset($cleanupResult['removed']) ? $cleanupResult['removed'] : 0;
    } catch (Exception $cleanupError) {
        // تجاهل أخطاء التنظيف التلقائي (لا نريد إيقاف عملية الرفع)
        error_log("Auto cleanup warning: " . $cleanupError->getMessage());
    }
    
    $message = "تم رفع $insertedCount جهة اتصال جديدة وتحديث $updatedCount جهة موجودة";
    if ($autoCleaned > 0) {
        $message .= " (تم تنظيف $autoCleaned سجل مكرر تلقائياً)";
    }
    
    echo json_encode([
        'status' => 'success',
        'message' => $message,
        'count' => $insertedCount,
        'updated' => $updatedCount,
        'skipped' => $skippedCount,
        'auto_cleaned' => $autoCleaned
    ]);
    
} catch (PDOException $e) {
    if ($conn->inTransaction()) {
        $conn->rollBack();
    }
    http_response_code(500);
    echo json_encode([
        'status' => 'error',
        'message' => 'Database error: ' . $e->getMessage()
    ]);
} catch (Exception $e) {
    if ($conn->inTransaction()) {
        $conn->rollBack();
    }
    http_response_code(400);
    echo json_encode([
        'status' => 'error',
        'message' => $e->getMessage()
    ]);
}
?>

