/// Directorate Model (المظلة المركزية: مديرية الثقافة العسكرية) class DirectorateOverview { final String code; final String name; final String commanderName; final int totalSchools; final int totalStudents; final int totalTeachers; final double annualContractValue; final int recordedLessonsMonth; final double complianceRate; final double aiAverageScore; final int activeUnifiedExams; DirectorateOverview({ required this.code, required this.name, required this.commanderName, required this.totalSchools, required this.totalStudents, required this.totalTeachers, required this.annualContractValue, required this.recordedLessonsMonth, required this.complianceRate, required this.aiAverageScore, required this.activeUnifiedExams, }); factory DirectorateOverview.fromJson(Map json) { return DirectorateOverview( code: json['code']?.toString() ?? '', name: json['name']?.toString() ?? '', commanderName: json['commander_name']?.toString() ?? '', totalSchools: (json['total_schools'] as num?)?.toInt() ?? 0, totalStudents: (json['total_students'] as num?)?.toInt() ?? 0, totalTeachers: (json['total_teachers'] as num?)?.toInt() ?? 0, annualContractValue: (json['annual_contract_value'] as num?)?.toDouble() ?? 0, recordedLessonsMonth: (json['recorded_lessons_month'] as num?)?.toInt() ?? 0, complianceRate: (json['compliance_rate'] as num?)?.toDouble() ?? 0, aiAverageScore: (json['ai_average_score'] as num?)?.toDouble() ?? 0, activeUnifiedExams: (json['active_unified_exams'] as num?)?.toInt() ?? 0, ); } } /// School Item Model (المدرسة التابعة وتصنيف الوزن) class SchoolItem { final int id; final String code; final String name; final String governorate; final String weightTier; // tier_a_small, tier_b_medium, tier_c_large final int studentCount; final int teacherCount; final double compliance; final String status; // excellent, good, warning_under_quota final double annualFee; SchoolItem({ required this.id, required this.code, required this.name, required this.governorate, required this.weightTier, required this.studentCount, required this.teacherCount, required this.compliance, required this.status, required this.annualFee, }); String get weightTierArabic { switch (weightTier) { case 'tier_a_small': return 'الفئة (أ) - صغيرة/نائية'; case 'tier_c_large': return 'الفئة (ج) - كبرى/مركزية'; case 'tier_b_medium': default: return 'الفئة (ب) - قياسية'; } } factory SchoolItem.fromJson(Map json) { return SchoolItem( id: json['id'] ?? 0, code: json['code'] ?? '', name: json['name'] ?? '', governorate: json['governorate']?.toString() ?? '', weightTier: json['weight_tier']?.toString() ?? '', studentCount: (json['student_count'] as num?)?.toInt() ?? 0, teacherCount: (json['teacher_count'] as num?)?.toInt() ?? 0, compliance: (json['compliance'] as num?)?.toDouble() ?? 0, status: json['status']?.toString() ?? 'unknown', annualFee: (json['annual_fee'] as num?)?.toDouble() ?? 0, ); } } /// Detailed school data used by the principal and supervisor dashboards. class SchoolDetail { final int id; final String name; final String governorate; final int studentCount; final int teacherCount; final String weightTier; final String directorName; final String biweeklyCycle; final String cycleProgress; const SchoolDetail({ required this.id, required this.name, required this.governorate, required this.studentCount, required this.teacherCount, required this.weightTier, required this.directorName, required this.biweeklyCycle, required this.cycleProgress, }); factory SchoolDetail.fromJson(Map json) => SchoolDetail( id: (json['id'] as num?)?.toInt() ?? 0, name: json['name']?.toString() ?? '', governorate: json['governorate']?.toString() ?? '', studentCount: (json['student_count'] as num?)?.toInt() ?? 0, teacherCount: (json['teacher_count'] as num?)?.toInt() ?? 0, weightTier: json['weight_tier']?.toString() ?? '', directorName: json['director_name']?.toString() ?? '', biweeklyCycle: json['biweekly_cycle']?.toString() ?? '', cycleProgress: json['cycle_progress']?.toString() ?? '', ); } /// A real computer-lab resource returned by the school dashboard API. class ComputerLabItem { final int id; final String name; final int deviceCount; final int onlineDevices; final String status; const ComputerLabItem({ required this.id, required this.name, required this.deviceCount, required this.onlineDevices, required this.status, }); factory ComputerLabItem.fromJson(Map json) => ComputerLabItem( id: (json['id'] as num?)?.toInt() ?? 0, name: json['name']?.toString() ?? '', deviceCount: (json['device_count'] as num?)?.toInt() ?? 0, onlineDevices: (json['online_devices'] as num?)?.toInt() ?? 0, status: json['status']?.toString() ?? 'unknown', ); } /// Teacher Item Model (المعلم ومؤشر دورية الأسبوعين) class TeacherItem { final int id; final String name; final String subject; final String grade; final String quotaStatus; // completed, pending, overdue final String lastLesson; final double aiScore; final String recordedAt; TeacherItem({ required this.id, required this.name, required this.subject, required this.grade, required this.quotaStatus, required this.lastLesson, required this.aiScore, required this.recordedAt, }); bool get isCompleted => quotaStatus == 'completed'; factory TeacherItem.fromJson(Map json) { return TeacherItem( id: json['id'] ?? 0, name: json['name'] ?? '', subject: json['subject'] ?? '', grade: json['grade'] ?? '', quotaStatus: json['quota_status'] ?? 'pending', lastLesson: json['last_lesson'] ?? '', aiScore: (json['ai_score'] as num?)?.toDouble() ?? 0, recordedAt: json['recorded_at']?.toString() ?? '', ); } } /// Recorded Classroom Lesson Result (نتيجة فحص الحصة المرئية) class RecordedLessonResult { final String lessonUuid; final String teacherName; final String subject; final String lessonTitle; final double fileSizeMb; final int durationMinutes; final double aiAlignmentScore; final String teacherTalkRatio; final String status; final String reportSummary; final List> socraticCheckpoints; RecordedLessonResult({ required this.lessonUuid, required this.teacherName, required this.subject, required this.lessonTitle, required this.fileSizeMb, required this.durationMinutes, required this.aiAlignmentScore, required this.teacherTalkRatio, required this.status, required this.reportSummary, required this.socraticCheckpoints, }); factory RecordedLessonResult.fromJson(Map json) { var rawCheckpoints = json['socratic_checkpoints'] as List? ?? []; List> checkpoints = rawCheckpoints.map((c) { if (c is Map) { return { 'timestamp': c['timestamp']?.toString() ?? '', 'question': c['question']?.toString() ?? '', 'objective': c['objective']?.toString() ?? '', }; } return {}; }).toList(); return RecordedLessonResult( lessonUuid: json['lesson_uuid'] ?? '', teacherName: json['teacher_name'] ?? '', subject: json['subject'] ?? '', lessonTitle: json['lesson_title'] ?? '', fileSizeMb: (json['file_size_mb'] as num?)?.toDouble() ?? 0, durationMinutes: (json['duration_minutes'] as num?)?.toInt() ?? 0, aiAlignmentScore: (json['ai_alignment_score'] as num?)?.toDouble() ?? 0, teacherTalkRatio: json['teacher_talk_ratio']?.toString() ?? '', status: json['status']?.toString() ?? 'unknown', reportSummary: json['report_summary']?.toString() ?? '', socraticCheckpoints: checkpoints, ); } } /// Unified Exam Model (الامتحان الموحد) class UnifiedExamModel { final String id; final String title; final String subject; final String gradeLevel; final String scheduledTime; final int durationMinutes; final bool pushedToLab; final String status; final List forms; final Map antiCheating; UnifiedExamModel({ required this.id, required this.title, required this.subject, required this.gradeLevel, required this.scheduledTime, required this.durationMinutes, required this.pushedToLab, required this.status, required this.forms, required this.antiCheating, }); factory UnifiedExamModel.fromJson(Map json) { return UnifiedExamModel( id: json['id'] ?? '', title: json['title'] ?? '', subject: json['subject'] ?? '', gradeLevel: json['grade_level'] ?? '', scheduledTime: json['scheduled_time'] ?? '', durationMinutes: json['duration_minutes'] ?? 60, pushedToLab: json['pushed_to_lab'] == true, status: json['status'] ?? 'scheduled', forms: (json['forms'] as List?)?.map((e) => e.toString()).toList() ?? ['نموذج أ', 'نموذج ب'], antiCheating: json['anti_cheating'] as Map? ?? {}, ); } } /// Exam Anomaly Alert Model (تنبيهات الشذوذ الإحصائي والغش) class ExamAnomalyAlert { final String id; final String type; // speed_impossible, error_clustering, performance_leap final String schoolName; final String subject; final String description; final String severity; final String timestamp; ExamAnomalyAlert({ required this.id, required this.type, required this.schoolName, required this.subject, required this.description, required this.severity, required this.timestamp, }); factory ExamAnomalyAlert.fromJson(Map json) { return ExamAnomalyAlert( id: json['id'] ?? '', type: json['type'] ?? 'speed_impossible', schoolName: json['school_name'] ?? '', subject: json['subject'] ?? '', description: json['description'] ?? '', severity: json['severity'] ?? 'medium', timestamp: json['timestamp'] ?? '', ); } }