import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../models/directorate_models.dart'; import '../services/directorate_api_service.dart'; class DirectorateCommandScreen extends StatefulWidget { const DirectorateCommandScreen({super.key}); @override State createState() => _DirectorateCommandScreenState(); } class _DirectorateCommandScreenState extends State with SingleTickerProviderStateMixin { late TabController _tabController; bool _isLoading = true; Map? _data; @override void initState() { super.initState(); _tabController = TabController(length: 3, vsync: this); _loadDashboard(); } Future _loadDashboard() async { setState(() => _isLoading = true); final res = await DirectorateApiService.fetchDirectorateDashboard(); if (mounted) { setState(() { _data = res; _isLoading = false; }); } } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (_isLoading) { return const Scaffold( backgroundColor: Color(0xFF070B12), body: Center( child: CupertinoActivityIndicator(color: Color(0xFF8B5CF6), radius: 18), ), ); } final dir = _data?['directorate'] ?? {}; final schools = (_data?['schools'] as List? ?? []) .map((s) => SchoolItem.fromJson(s)) .toList(); final anomalies = (_data?['anomalies'] as List? ?? []) .map((a) => ExamAnomalyAlert.fromJson(a)) .toList(); final radar = _data?['radar'] ?? {}; return Scaffold( backgroundColor: const Color(0xFF070B12), appBar: AppBar( backgroundColor: const Color(0xFF0E1626), elevation: 0, centerTitle: false, title: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 8, height: 8, decoration: const BoxDecoration( color: Color(0xFF10B981), shape: BoxShape.circle, ), ), const SizedBox(width: 6), Text( dir['name'] ?? 'مديرية الثقافة العسكرية', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w800, color: Colors.white), ), ], ), const SizedBox(height: 2), const Text( 'لوحة القائد الأعلى للرقابة والسيادة الرقمية (43 مدرسة في المملكة)', style: TextStyle(fontSize: 12, color: Color(0xFF94A3B8)), ), ], ), bottom: TabBar( controller: _tabController, indicatorColor: const Color(0xFF8B5CF6), indicatorWeight: 3, labelColor: Colors.white, unselectedLabelColor: const Color(0xFF64748B), labelStyle: const TextStyle(fontWeight: FontWeight.w700, fontSize: 13.5), tabs: const [ Tab( icon: Icon(CupertinoIcons.chart_bar_alt_fill, size: 18), text: 'الرؤية الكلية والمدارس', ), Tab( icon: Icon(CupertinoIcons.star_circle_fill, size: 18), text: 'رادار المعلمين والتسييل', ), Tab( icon: Icon(CupertinoIcons.shield_lefthalf_fill, size: 18), text: 'نزاهة الامتحانات الموحدة', ), ], ), ), body: TabBarView( controller: _tabController, children: [ _buildMacroOverviewTab(dir, schools), _buildTeachersRadarTab(radar), _buildExamIntegrityTab(anomalies), ], ), ); } // --------------------------------------------------------------------------- // TAB 1: Macro Directorate Metrics & 43 Schools Matrix // --------------------------------------------------------------------------- Widget _buildMacroOverviewTab( Map dir, List schools) { return SingleChildScrollView( padding: const EdgeInsets.all(18), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Commander KPI Ribbon Container( padding: const EdgeInsets.all(18), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF1E1B4B), Color(0xFF0F172A)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF6366F1).withOpacity(0.4)), ), child: Column( children: [ Row( children: [ Expanded( child: _kpiCell( 'إجمالي المدارس', '${dir['total_schools'] ?? 43} مدرسة', CupertinoIcons.building_2_fill, const Color(0xFF818CF8), ), ), Expanded( child: _kpiCell( 'الطلبة المسجلون', '${dir['total_students'] ?? 19350}', CupertinoIcons.person_3_fill, const Color(0xFF38BDF8), ), ), ], ), const SizedBox(height: 14), Row( children: [ Expanded( child: _kpiCell( 'معلمو الثقافة العسكرية', '${dir['total_teachers'] ?? 812} معلم', CupertinoIcons.person_badge_plus_fill, const Color(0xFFFBBF24), ), ), Expanded( child: _kpiCell( 'نسبة كوتة الحصص', '${dir['compliance_rate'] ?? 94.5}%', CupertinoIcons.check_mark_circled_solid, const Color(0xFF34D399), ), ), ], ), ], ), ), const SizedBox(height: 20), // Schools Weight Tier Breakdown Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'توزيع مدارس الثقافة العسكرية الـ 43 حسب تصنيف الوزن:', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), Text( 'إجمالي العقد: 20,000 د.أ', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w700, color: const Color(0xFFA78BFA)), ), ], ), const SizedBox(height: 12), // School List Cards ...schools.map((s) => Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF0F172A), borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFF1E293B)), ), child: Row( children: [ Container( width: 44, height: 44, decoration: BoxDecoration( color: _statusColor(s.status).withOpacity(0.15), borderRadius: BorderRadius.circular(10), ), child: Icon(CupertinoIcons.building_2_fill, color: _statusColor(s.status), size: 22), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( s.name, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), const SizedBox(height: 4), Row( children: [ Text( s.governorate, style: const TextStyle( fontSize: 12, color: Color(0xFF94A3B8)), ), const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 1), decoration: BoxDecoration( color: const Color(0xFF1E293B), borderRadius: BorderRadius.circular(4), ), child: Text( s.weightTierArabic, style: const TextStyle( fontSize: 11, color: Color(0xFFA78BFA)), ), ), ], ), ], ), ), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( '${s.compliance}% التزام', style: TextStyle( fontSize: 12.5, fontWeight: FontWeight.w700, color: _statusColor(s.status), ), ), const SizedBox(height: 4), Text( '${s.studentCount} طالب · ${s.annualFee.toInt()} د.أ/سنة', style: const TextStyle( fontSize: 11, color: Color(0xFF64748B)), ), ], ), ], ), )), ], ), ); } // --------------------------------------------------------------------------- // TAB 2: Teachers Radar & Marketplace Monetization // --------------------------------------------------------------------------- Widget _buildTeachersRadarTab(Map radar) { final topTeachers = (radar['top_teachers'] as List? ?? []); final needingSupport = (radar['needing_support'] as List? ?? []); return SingleChildScrollView( padding: const EdgeInsets.all(18), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Monetization Model Header Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF14532D), Color(0xFF0F172A)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF22C55E).withOpacity(0.4)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(CupertinoIcons.money_dollar_circle_fill, color: Color(0xFF4ADE80), size: 22), SizedBox(width: 8), Text( 'سوق تسييل المعلمين المتميزين (شراكة الأرباح)', style: TextStyle( fontSize: 14.5, fontWeight: FontWeight.w700, color: Colors.white), ), ], ), const SizedBox(height: 8), const Text( 'المعلمون الحاصلون على تقييم 95%+ يتم منحهم اعتماد "معلم صَقِل المعتمد" وتُباع شروحاتهم خارج الثقافة العسكرية مع توزيع العائد: 55% للمعلم، 15% للمديرية، 30% لصَقِل.', style: TextStyle( fontSize: 12.5, color: Color(0xFFCBD5E1), height: 1.5), ), ], ), ), const SizedBox(height: 20), // Top Teachers List const Text( '🌟 أفضل المعلمين المرشحين للتسييل والاعتماد الرسمي:', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), const SizedBox(height: 12), ...topTeachers.map((t) => Container( margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xFF0F172A), borderRadius: BorderRadius.circular(14), border: Border.all( color: const Color(0xFF10B981).withOpacity(0.4)), ), child: Row( children: [ const CircleAvatar( radius: 20, backgroundColor: Color(0xFF065F46), child: Icon(CupertinoIcons.star_fill, color: Color(0xFF34D399), size: 18), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( t['name'] ?? '', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), const SizedBox(height: 2), Text( '${t['subject']} · ${t['school']}', style: const TextStyle( fontSize: 12, color: Color(0xFF94A3B8)), ), ], ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 3), decoration: BoxDecoration( color: const Color(0xFF10B981).withOpacity(0.2), borderRadius: BorderRadius.circular(6), ), child: Text( '${t['score']}% تقييم AI', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w800, color: Color(0xFF34D399)), ), ), ], ), )), const SizedBox(height: 18), // Early Intervention Radar const Text( '⚠️ رادار الإنذار والتوجيه المبكر (معالجة القصور قبل التوجيهي):', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), const SizedBox(height: 12), ...needingSupport.map((ns) => Container( margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xFF0F172A), borderRadius: BorderRadius.circular(14), border: Border.all( color: const Color(0xFFEF4444).withOpacity(0.3)), ), child: Row( children: [ const CircleAvatar( radius: 20, backgroundColor: Color(0xFF7F1D1D), child: Icon(CupertinoIcons.exclamationmark_triangle_fill, color: Color(0xFFF87171), size: 18), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( ns['name'] ?? '', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), const SizedBox(height: 2), Text( '${ns['school']} · ${ns['issue']}', style: const TextStyle( fontSize: 12, color: Color(0xFFF87171)), ), ], ), ), Text( '${ns['score']}%', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w700, color: Color(0xFFF87171)), ), ], ), )), ], ), ); } // --------------------------------------------------------------------------- // TAB 3: Kingdom Exam Integrity & Statistical Fraud Detection // --------------------------------------------------------------------------- Widget _buildExamIntegrityTab(List anomalies) { return SingleChildScrollView( padding: const EdgeInsets.all(18), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Live Exam Integrity Header Container( padding: const EdgeInsets.all(18), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF1E293B), Color(0xFF0F172A)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF0284C7).withOpacity(0.5)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(CupertinoIcons.shield_fill, color: Color(0xFF38BDF8), size: 20), SizedBox(width: 8), Text( 'غرفة عمليات نزاهة الامتحانات الموحدة', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w800, color: Colors.white), ), ], ), const SizedBox(height: 8), const Text( 'مراقبة لحظية لنحو 19,000 طالب يخوضون الامتحان الموحد المتزامن عبر 43 مدرسة، برصد فوري للسرعة المستحيلة وتكتل الأخطاء.', style: TextStyle( fontSize: 12.5, color: Color(0xFF94A3B8), height: 1.5), ), ], ), ), const SizedBox(height: 20), const Text( 'تنبيهات الشذوذ الإحصائي وشبهات التواطؤ:', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), const SizedBox(height: 12), if (anomalies.isEmpty) Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: const Color(0xFF0F172A), borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFF1E293B)), ), child: const Center( child: Text( '✅ لا توجد أي تنبيهات شذوذ حالياً · كافة المدارس تعمل بانضباط تام', style: TextStyle(color: Color(0xFF10B981), fontSize: 13.5), ), ), ) else ...anomalies.map((anm) => Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF1E1B2E), borderRadius: BorderRadius.circular(14), border: Border.all( color: const Color(0xFFEF4444).withOpacity(0.5)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ const Icon( CupertinoIcons .exclamationmark_triangle_fill, color: Color(0xFFEF4444), size: 18), const SizedBox(width: 8), Text( anm.schoolName, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: Colors.white), ), ], ), Text( anm.timestamp, style: const TextStyle( fontSize: 11.5, color: Color(0xFF94A3B8)), ), ], ), const SizedBox(height: 8), Text( anm.description, style: const TextStyle( fontSize: 13, color: Color(0xFFFCA5A5), height: 1.4), ), const SizedBox(height: 12), ElevatedButton.icon( onPressed: () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( '🎥 جاري فتح العينة البانورامية المسجلة (16.5 MB) لتلك الدقيقة للتحقق البصري المباشر'), backgroundColor: Color(0xFF0284C7), ), ); }, icon: const Icon(CupertinoIcons.play_circle_fill, size: 16), label: const Text( 'عرض العينة البانورامية المسجلة في هذه الدقيقة 👁️', style: TextStyle(fontSize: 12.5), ), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF0284C7), padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8)), ), ), ], ), )), ], ), ); } Widget _kpiCell( String title, String value, IconData icon, Color accentColor) { return Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: accentColor.withOpacity(0.15), shape: BoxShape.circle, ), child: Icon(icon, color: accentColor, size: 20), ), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle(fontSize: 11.5, color: Color(0xFF94A3B8)), ), const SizedBox(height: 2), Text( value, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w800, color: Colors.white), ), ], ) ], ); } Color _statusColor(String status) { switch (status) { case 'excellent': return const Color(0xFF10B981); case 'warning_under_quota': return const Color(0xFFEF4444); case 'good': default: return const Color(0xFF38BDF8); } } }