<?php
/**
 * قارئ ملفات Excel و CSV
 * Excel and CSV File Reader
 */

class ExcelReader {
    
    /**
     * قراءة ملف Excel أو CSV
     * @param string $file_path مسار الملف المؤقت
     * @param string $file_ext امتداد الملف (csv, xlsx, xls)
     * @return array|false بيانات الطلاب أو false في حالة الفشل
     */
    public function readFile($file_path, $file_ext) {
        if ($file_ext === 'csv') {
            return $this->readCSV($file_path);
        } elseif ($file_ext === 'xlsx' || $file_ext === 'xls') {
            return $this->readExcel($file_path, $file_ext);
        }
        return false;
    }
    
    /**
     * ضمان أن النص UTF-8 صالح (للقيم المفردة من Excel/CSV)
     * معالجة ملفات محفوظة بترميز عربي (Windows-1256) أو ظهور ??? بدل العربية
     */
    private function normalizeStringUtf8($str) {
        if ($str === '' || $str === null) {
            return '';
        }
        if (is_numeric($str)) {
            return (string)$str;
        }
        $str = (string)$str;
        // إذا كان UTF-8 صالحاً ولا يوجد حرف استبدال، استخدمه
        if (mb_check_encoding($str, 'UTF-8') && strpos($str, "\xEF\xBF\xBD") === false) {
            return $str;
        }
        // محاولة إصلاح نص محفوظ بترميز عربي ويندوز (الملف من Excel عربي)
        foreach (['Windows-1256', 'CP1256', 'ISO-8859-6', 'UTF-16LE', 'ISO-8859-1', 'Windows-1252'] as $enc) {
            $converted = @mb_convert_encoding($str, 'UTF-8', $enc);
            if ($converted !== false && mb_check_encoding($converted, 'UTF-8') && strpos($converted, "\xEF\xBF\xBD") === false) {
                return $converted;
            }
        }
        // إذا النص يبدو خاطئاً (كثير من ?) جرّب تفسير البايتات كـ Windows-1256
        if (preg_match('/\?+/u', $str) && strlen($str) > 0) {
            $asLatin1 = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8');
            if ($asLatin1 !== false) {
                $from1256 = @mb_convert_encoding($asLatin1, 'UTF-8', 'Windows-1256');
                if ($from1256 !== false && mb_check_encoding($from1256, 'UTF-8')) {
                    return $from1256;
                }
            }
        }
        $converted = @mb_convert_encoding($str, 'UTF-8', 'auto');
        return ($converted !== false && mb_check_encoding($converted, 'UTF-8')) ? $converted : $str;
    }
    
    /**
     * استخراج نص خلية Excel (يدعم RichText ويطبع الترميز)
     */
    /**
     * استخراج نص خلية (لا تحوّل الرقم الجامعي مثل 23-11064571 إلى عدد فتفسد القيمة)
     */
    private function getCellStringValue($cellValue) {
        if ($cellValue === null || $cellValue === '') {
            return '';
        }
        if (is_numeric($cellValue)) {
            $s = trim((string)$cellValue);
            if (strpos($s, 'E') !== false || strpos($s, 'e') !== false) {
                $s = rtrim(sprintf('%.0f', (float)$cellValue), '0');
            }
            return $s;
        }
        $text = '';
        if (is_object($cellValue) && method_exists($cellValue, 'getPlainText')) {
            $text = $cellValue->getPlainText();
        } else {
            $text = (string)$cellValue;
        }
        return $this->normalizeStringUtf8(trim($text));
    }
    
    /**
     * تحويل محتوى الملف إلى UTF-8 (معالجة جذرية للأحرف العربية)
     * يجرب ترميزات شائعة: UTF-8، Windows-1256 (عربي ويندوز)، ISO-8859-6، UTF-16LE
     */
    private function ensureUtf8($raw_content) {
        // إزالة BOM إذا كان موجوداً
        if (substr($raw_content, 0, 3) === "\xEF\xBB\xBF") {
            $raw_content = substr($raw_content, 3);
        }
        if (substr($raw_content, 0, 2) === "\xFF\xFE") {
            $raw_content = substr($raw_content, 2);
        }
        
        // إذا كان المحتوى UTF-8 صالحاً ولا يحتوي على أحرف استبدال، استخدمه كما هو
        if (mb_check_encoding($raw_content, 'UTF-8')) {
            $decoded = $raw_content;
            if (strpos($decoded, "\xEF\xBF\xBD") === false) {
                return $decoded;
            }
        }
        
        $encodings_to_try = ['Windows-1256', 'CP1256', 'ISO-8859-6', 'UTF-16LE', 'UTF-16BE', 'ISO-8859-1'];
        foreach ($encodings_to_try as $enc) {
            if (!@mb_check_encoding($raw_content, $enc)) {
                continue;
            }
            $converted = @mb_convert_encoding($raw_content, 'UTF-8', $enc);
            if ($converted !== false && mb_check_encoding($converted, 'UTF-8')) {
                return $converted;
            }
        }
        
        // محاولة أخيرة بـ auto
        $converted = @mb_convert_encoding($raw_content, 'UTF-8', 'auto');
        if ($converted !== false && mb_check_encoding($converted, 'UTF-8')) {
            return $converted;
        }
        
        return $raw_content;
    }
    
    /**
     * قراءة ملف CSV
     */
    private function readCSV($file_path) {
        $data = [];
        
        $file_content = file_get_contents($file_path);
        $file_content = $this->ensureUtf8($file_content);
        
        // حفظ المحتوى المؤقت في ملف UTF-8
        $temp_file = tempnam(sys_get_temp_dir(), 'csv_');
        file_put_contents($temp_file, $file_content);
        
        $handle = fopen($temp_file, 'r');
        
        if ($handle === false) {
            @unlink($temp_file);
            return false;
        }
        
        // قراءة السطر الأول (العناوين)
        $headers = fgetcsv($handle);
        if ($headers === false) {
            fclose($handle);
            @unlink($temp_file);
            return false;
        }
        
        // تنظيف العناوين وضمان UTF-8
        $original_headers = [];
        foreach ($headers as $header) {
            $header = $this->normalizeStringUtf8(trim($header));
            $original_headers[] = $header;
        }
        
        // قراءة البيانات - قراءة جميع الأعمدة
        $row_num = 1;
        while (($row = fgetcsv($handle)) !== false) {
            $row_num++;
            
            // تخطي الصفوف الفارغة
            if (empty(array_filter($row))) {
                continue;
            }
            
            // إنشاء مصفوفة بيانات باستخدام العناوين كمفاتيح
            $row_data = [];
            foreach ($original_headers as $index => $header) {
                $header_trimmed = trim($header);
                $header_lower = mb_strtolower($header_trimmed, 'UTF-8');
                
                // قراءة القيمة وتنظيفها وضمان UTF-8
                $value = isset($row[$index]) ? trim($row[$index]) : '';
                $value = $this->normalizeStringUtf8($value);
                
                // حفظ القيمة باستخدام العنوان الأصلي
                $row_data[$header] = $value;
                
                // حفظ أيضاً باستخدام العنوان الصغير للتوافق
                $row_data[$header_lower] = $value;
                
                // حفظ باستخدام الأسماء القياسية المطلوبة
                
                // student_number
                if (in_array($header_lower, ['student_number', 'student_id', 'رقم_جامعي', 'رقم جامعي', 'الرقم الجامعي', 'id', 'معرف'])) {
                    $row_data['student_number'] = $value;
                }
                
                // full_name_ar (مهم جداً!)
                if (in_array($header_lower, ['full_name_ar', 'full_name', 'name_ar', 'name', 'student_name', 'اسم', 'الاسم', 'اسم_عربي', 'اسم عربي', 'الاسم العربي', 'اسم_الطالب', 'اسم الطالب'])) {
                    $row_data['full_name_ar'] = $value;
                    $row_data['name_ar'] = $value;
                }
                
                // full_name_en
                if (in_array($header_lower, ['full_name_en', 'name_en', 'اسم_إنجليزي', 'اسم إنجليزي', 'الاسم الإنجليزي', 'english_name'])) {
                    $row_data['full_name_en'] = $value;
                    $row_data['name_en'] = $value;
                }
                
                // national_id
                if (in_array($header_lower, ['national_id', 'nid', 'رقم_وطني', 'رقم وطني', 'الرقم الوطني'])) {
                    $row_data['national_id'] = $value;
                }
                
                // email
                if (in_array($header_lower, ['email', 'e-mail', 'بريد', 'البريد الإلكتروني', 'بريد_إلكتروني'])) {
                    $row_data['email'] = $value;
                }
                
                // phone
                if (in_array($header_lower, ['phone', 'telephone', 'mobile', 'هاتف', 'الهاتف', 'رقم_الهاتف'])) {
                    $row_data['phone'] = $value;
                }
                
                // major_code
                if (in_array($header_lower, ['major_code', 'رمز_تخصص', 'رمز تخصص', 'رمز التخصص', 'code'])) {
                    $row_data['major_code'] = $value;
                }
                
                // major_id
                if (in_array($header_lower, ['major_id', 'معرف_تخصص', 'معرف تخصص'])) {
                    $row_data['major_id'] = $value;
                }
                
                // enrollment_date
                if (in_array($header_lower, ['enrollment_date', 'تاريخ_تسجيل', 'تاريخ تسجيل', 'تاريخ التسجيل', 'date', 'registration_date'])) {
                    $row_data['enrollment_date'] = $value;
                }
                
                // course_code (للدرجات)
                if (in_array($header_lower, ['course_code', 'رمز_المادة', 'رمز المادة', 'رمز', 'الرمز'])) {
                    $row_data['course_code'] = $value;
                }
                
                // course_id (للدرجات)
                if (in_array($header_lower, ['course_id', 'معرف_المادة', 'معرف المادة'])) {
                    $row_data['course_id'] = $value;
                }
                
                // marks (للدرجات)
                if (in_array($header_lower, ['marks', 'grade', 'degree', 'درجة', 'الدرجة', 'mark'])) {
                    $row_data['marks'] = $value;
                    $row_data['grade'] = $value;
                }
            }
            
            // إذا كان هناك بيانات، أضفها
            if (!empty($row_data)) {
                $data[] = $row_data;
            }
        }
        
        fclose($handle);
        @unlink($temp_file);
        return $data;
    }
    
    /**
     * قراءة ملف Excel
     */
    private function readExcel($file_path, $file_ext) {
        // محاولة استخدام مكتبة PhpSpreadsheet إذا كانت متوفرة
        if (class_exists('PhpOffice\PhpSpreadsheet\IOFactory')) {
            return $this->readExcelWithPhpSpreadsheet($file_path);
        }
        
        // إذا لم تكن متوفرة، نستخدم مكتبة بسيطة أو نعيد CSV
        // يمكن استخدام مكتبة SimpleXLSX هنا
        if (class_exists('SimpleXLSX')) {
            return $this->readExcelWithSimpleXLSX($file_path);
        }
        
        // إذا لم تكن هناك مكتبة، نحاول قراءة Excel كملف ثنائي بسيط
        // أو نطلب من المستخدم استخدام CSV
        // يمكن إضافة مكتبة بسيطة هنا أو تحويل Excel إلى CSV يدوياً
        
        // رسالة خطأ واضحة
        throw new Exception('لا توجد مكتبة لقراءة ملفات Excel. يرجى استخدام ملف CSV أو تثبيت مكتبة PhpSpreadsheet.');
    }
    
    /**
     * قراءة Excel باستخدام PhpSpreadsheet
     */
    private function readExcelWithPhpSpreadsheet($file_path) {
        try {
            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_path);
            $worksheet = $spreadsheet->getActiveSheet();
            $data = [];
            
            $highestRow = $worksheet->getHighestRow();
            $highestColumn = $worksheet->getHighestColumn();
            
            // قراءة العناوين من الصف الأول
            $original_headers = [];
            $headers_lower = [];
            $col_index = 0;
            for ($col = 'A'; $col <= $highestColumn; $col++) {
                $cellValue = $worksheet->getCell($col . '1')->getValue();
                $header = $this->getCellStringValue($cellValue);
                if ($header === '' && $cellValue !== null && $cellValue !== '') {
                    $header = trim((string)$cellValue);
                    if ($header !== '') $header = $this->normalizeStringUtf8($header);
                }
                $original_headers[$col] = $header;
                $headers_lower[$col] = mb_strtolower($header, 'UTF-8');
                $col_index++;
            }
            
            // قراءة البيانات من الصف الثاني
            for ($row = 2; $row <= $highestRow; $row++) {
                $row_data = [];
                
                // قراءة جميع الأعمدة
                foreach ($original_headers as $col => $header) {
                    $cellValue = $worksheet->getCell($col . $row)->getValue();
                    $header_lower = mb_strtolower($header, 'UTF-8');
                    if ($cellValue === null || $cellValue === '') {
                        $value = '';
                    } elseif (in_array($header_lower, ['student_number', 'الرقم الجامعي', 'رقم_جامعي', 'student_id', 'national_id', 'الرقم الوطني', 'full_name_ar', 'الاسم العربي', 'name_ar', 'اسم', 'الاسم'])) {
                        $value = $this->getCellStringValue($cellValue);
                    } elseif (is_numeric($cellValue)) {
                        $value = (string)(int)(float)$cellValue;
                    } else {
                        $value = $this->getCellStringValue($cellValue);
                    }
                    
                    // حفظ القيمة باستخدام العنوان الأصلي
                    $row_data[$header] = $value;
                    
                    // حفظ أيضاً باستخدام العنوان الصغير للتوافق
                    $row_data[$header_lower] = $value;
                    
                    // حفظ أيضاً باستخدام أسماء بديلة شائعة
                    if (in_array($header_lower, ['id', 'student_id', 'معرف', 'معرّف', 'رقم', 'الرقم'])) {
                        $row_data['student_id'] = $value;
                    }
                    if (in_array($header_lower, ['student_number', 'student_id', 'رقم_جامعي', 'رقم جامعي', 'الرقم الجامعي', 'id'])) {
                        $row_data['student_number'] = $value;
                    }
                    if (in_array($header_lower, ['national_id', 'nid', 'رقم_وطني', 'رقم وطني', 'الرقم الوطني'])) {
                        $row_data['national_id'] = $value;
                    }
                    if (in_array($header_lower, ['student_name', 'name', 'full_name', 'full_name_ar', 'name_ar', 'اسم', 'الاسم', 'اسم الطالب', 'اسم_الطالب', 'اسم_عربي', 'اسم عربي', 'الاسم العربي'])) {
                        $row_data['student_name'] = $value;
                        $row_data['full_name_ar'] = $value;
                        $row_data['name_ar'] = $value;
                    }
                    if (in_array($header_lower, ['course_code', 'course_code', 'رمز_المادة', 'رمز المادة', 'رمز', 'الرمز'])) {
                        $row_data['course_code'] = $value;
                    }
                    if (in_array($header_lower, ['course_id', 'course_id', 'معرف_المادة', 'معرف المادة'])) {
                        $row_data['course_id'] = $value;
                    }
                    if (in_array($header_lower, ['marks', 'grade', 'degree', 'درجة', 'الدرجة', 'mark', 'marks'])) {
                        $row_data['marks'] = $value;
                        $row_data['grade'] = $value;
                        $row_data['degree'] = $value;
                    }
                    if (in_array($header_lower, ['status', 'الحالة', 'حالة'])) {
                        $row_data['status'] = $value;
                    }
                    if (in_array($header_lower, ['college_id', 'معرف_الكلية', 'معرف الكلية', 'الكلية'])) {
                        $row_data['college_id'] = $value;
                    }
                    if (in_array($header_lower, ['major_id', 'معرف_التخصص', 'معرف التخصص', 'التخصص'])) {
                        $row_data['major_id'] = $value;
                    }
                }
                
                // إذا كان هناك بيانات، أضفها
                if (!empty($row_data)) {
                    $data[] = $row_data;
                }
            }
            
            return $data;
        } catch (Exception $e) {
            return false;
        }
    }
    
    /**
     * قراءة Excel باستخدام SimpleXLSX
     */
    private function readExcelWithSimpleXLSX($file_path) {
        try {
            $xlsx = SimpleXLSX::parse($file_path);
            if (!$xlsx) {
                return false;
            }
            
            $data = [];
            $rows = $xlsx->rows();
            
            if (empty($rows)) {
                return false;
            }
            
            // قراءة العناوين من الصف الأول
            $original_headers = array_map('trim', $rows[0]);
            $headers_lower = array_map('strtolower', $original_headers);
            
            // قراءة البيانات من الصف الثاني
            for ($i = 1; $i < count($rows); $i++) {
                $row = $rows[$i];
                
                // تخطي الصفوف الفارغة
                if (empty(array_filter($row))) {
                    continue;
                }
                
                // إنشاء مصفوفة بيانات باستخدام العناوين كمفاتيح
                $row_data = [];
                foreach ($original_headers as $index => $header) {
                    $header_lower = strtolower(trim($header));
                    $value = isset($row[$index]) ? trim($row[$index]) : '';
                    
                    // حفظ القيمة باستخدام العنوان الأصلي
                    $row_data[$header] = $value;
                    
                    // حفظ أيضاً باستخدام العنوان الصغير للتوافق
                    $row_data[$header_lower] = $value;
                    
                    // حفظ أيضاً باستخدام أسماء بديلة شائعة
                    if (in_array($header_lower, ['id', 'student_id', 'معرف', 'معرّف', 'رقم', 'الرقم'])) {
                        $row_data['student_id'] = $value;
                    }
                    if (in_array($header_lower, ['student_number', 'رقم_جامعي', 'رقم جامعي', 'الرقم الجامعي'])) {
                        $row_data['student_number'] = $value;
                    }
                    if (in_array($header_lower, ['national_id', 'nid', 'رقم_وطني', 'رقم وطني', 'الرقم الوطني'])) {
                        $row_data['national_id'] = $value;
                    }
                    if (in_array($header_lower, ['student_name', 'name', 'full_name', 'full_name_ar', 'اسم', 'الاسم', 'اسم الطالب', 'اسم_الطالب'])) {
                        $row_data['student_name'] = $value;
                    }
                    if (in_array($header_lower, ['course_code', 'course_code', 'رمز_المادة', 'رمز المادة', 'رمز', 'الرمز'])) {
                        $row_data['course_code'] = $value;
                    }
                    if (in_array($header_lower, ['course_id', 'course_id', 'معرف_المادة', 'معرف المادة'])) {
                        $row_data['course_id'] = $value;
                    }
                    if (in_array($header_lower, ['marks', 'grade', 'degree', 'درجة', 'الدرجة', 'mark', 'marks'])) {
                        $row_data['marks'] = $value;
                        $row_data['grade'] = $value;
                        $row_data['degree'] = $value;
                    }
                }
                
                // إذا كان هناك بيانات، أضفها
                if (!empty($row_data)) {
                    $data[] = $row_data;
                }
            }
            
            return $data;
        } catch (Exception $e) {
            return false;
        }
    }
}


