round((float)($learning['average_completion'] ?? 0), 2), 'lessons_completed' => (int)($learning['lessons_completed'] ?? 0), 'lessons_started' => (int)($learning['lessons_started'] ?? 0), 'remediation_mastered' => (int)($errors['mastered'] ?? 0), 'remediation_total' => (int)($errors['total_errors'] ?? 0), 'latest_exam_score' => $latestExam ? (float)$latestExam['percentage'] : null, 'exams_passed' => (int)($mastery['exams_passed'] ?? 0), 'exams_total' => (int)($mastery['exams_total'] ?? 0), 'general_readiness' => round((float)($mastery['readiness'] ?? 0), 2), ]; return ['student' => $student, 'metrics' => $metrics, 'whatsapp_message' => self::buildWhatsAppMessage($student, $metrics)]; } public static function dispatchReportToGuardian(int $studentId): array { try { $report = self::compileMonthlyReport($studentId); $result = (new NabehService())->sendMessage($report['student']['guardian_phone'], $report['whatsapp_message']); if (!($result['success'] ?? false)) { return ['status' => 'error', 'message' => $result['error'] ?? 'تعذر إرسال التقرير عبر نبيه']; } return ['status' => 'success', 'message' => 'تم إرسال التقرير الفعلي لولي الأمر', 'dispatched_at' => date('Y-m-d H:i:s')]; } catch (\Throwable $e) { return ['status' => 'error', 'message' => $e->getMessage()]; } } public static function dispatchBatchReports(int $schoolId): array { $students = Database::select( "SELECT DISTINCT s.id FROM students s JOIN guardian_students gs ON gs.student_id = s.id AND gs.can_view_analytics = 1 WHERE s.school_id = ?", [$schoolId] ); $sent = 0; $failed = 0; foreach ($students as $student) { $result = self::dispatchReportToGuardian((int)$student['id']); ($result['status'] ?? 'error') === 'success' ? $sent++ : $failed++; } return [ 'status' => $failed === 0 ? 'success' : 'partial', 'school_id' => $schoolId, 'total_dispatched' => $sent, 'failed_count' => $failed, 'total_eligible' => count($students), ]; } private static function buildWhatsAppMessage(array $student, array $metrics): string { $latestExam = $metrics['latest_exam_score'] === null ? 'لا توجد محاولة مكتملة' : $metrics['latest_exam_score'] . '%'; return "تقرير صَقِل الشهري — {$student['month']}\n" . "الطالب: {$student['full_name']}\n" . "المدرسة: " . ($student['school_name'] ?: 'غير مرتبطة') . "\n" . "الصف: {$student['grade_level']} / {$student['stream']}\n\n" . "الحصص المكتملة: {$metrics['lessons_completed']} من {$metrics['lessons_started']}\n" . "متوسط إكمال الحصص: {$metrics['average_lesson_completion']}%\n" . "المعالجات المتقنة: {$metrics['remediation_mastered']} من {$metrics['remediation_total']}\n" . "آخر امتحان: {$latestExam}\n" . "مؤشر الجاهزية: {$metrics['general_readiness']}%\n\n" . "للتفاصيل ادخل إلى تطبيق صَقِل بحساب ولي الأمر."; } }