import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/company_stats_controller.dart'; class CompanyStatsView extends StatelessWidget { const CompanyStatsView({super.key}); @override Widget build(BuildContext context) { final args = Get.arguments as Map; final controller = Get.put( CompanyStatsController( companyId: args['company_id'], companyName: args['company_name'], ), tag: args['company_id'], ); final isDark = Theme.of(context).brightness == Brightness.dark; return Scaffold( appBar: AppBar( title: Text( 'إحصائيات ${args['company_name']}', style: const TextStyle(fontFamily: 'El Messiri', fontSize: 16), overflow: TextOverflow.ellipsis, ), centerTitle: true, backgroundColor: const Color(0xFF0F4C81), foregroundColor: Colors.white, elevation: 0, actions: [ Obx(() => controller.isLoading.value ? const Padding( padding: EdgeInsets.all(14), child: SizedBox( width: 20, height: 20, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2), ), ) : IconButton( icon: const Icon(Icons.refresh), onPressed: controller.fetchStats, )), ], ), body: Obx(() { if (controller.isLoading.value && controller.totals.isEmpty) { return const Center(child: CircularProgressIndicator()); } if (controller.totals.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.bar_chart_outlined, size: 80, color: Colors.grey.shade400), const SizedBox(height: 16), const Text('لا توجد بيانات بعد', style: TextStyle(fontSize: 18, color: Colors.grey)), ], ), ); } final totals = controller.totals; final monthly = controller.monthly; return RefreshIndicator( onRefresh: controller.fetchStats, child: ListView( padding: const EdgeInsets.all(16), children: [ // ── Lifetime Totals ────────────────────────────── _sectionTitle('الإحصائيات الإجمالية', isDark), const SizedBox(height: 12), GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, mainAxisSpacing: 12, crossAxisSpacing: 12, childAspectRatio: 1.6, children: [ _statCard( icon: Icons.receipt_long_rounded, label: 'إجمالي الفواتير', value: _fmt(totals['total_invoices']), color: const Color(0xFF0F4C81), isDark: isDark, ), _statCard( icon: Icons.check_circle_rounded, label: 'فواتير معتمدة', value: _fmt(totals['approved_count']), color: const Color(0xFF10B981), isDark: isDark, ), _statCard( icon: Icons.attach_money_rounded, label: 'إجمالي المبيعات', value: '${_fmtAmount(totals['total_amount'])} د.أ', color: const Color(0xFFD4AF37), isDark: isDark, ), _statCard( icon: Icons.percent_rounded, label: 'إجمالي الضريبة', value: '${_fmtAmount(totals['total_tax'])} د.أ', color: const Color(0xFF8B5CF6), isDark: isDark, ), ], ), // Approval Rate const SizedBox(height: 20), _buildApprovalRateCard(totals, isDark), // ── Monthly Breakdown ──────────────────────────── if (monthly.isNotEmpty) ...[ const SizedBox(height: 24), _sectionTitle('التفاصيل الشهرية (آخر 12 شهر)', isDark), const SizedBox(height: 12), ...monthly.map((m) => _buildMonthRow(m, isDark)), ], ], ), ); }), ); } Widget _sectionTitle(String title, bool isDark) { return Row( children: [ Container( width: 4, height: 20, decoration: BoxDecoration( color: const Color(0xFF0F4C81), borderRadius: BorderRadius.circular(2), ), ), const SizedBox(width: 10), Text( title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ], ); } Widget _statCard({ required IconData icon, required String label, required String value, required Color color, required bool isDark, }) { return Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: isDark ? const Color(0xFF1E1E2E) : Colors.white, borderRadius: BorderRadius.circular(14), border: Border.all(color: isDark ? Colors.white10 : Colors.grey.shade200), boxShadow: isDark ? [] : [ BoxShadow( color: Colors.black.withValues(alpha: 0.04), blurRadius: 8, offset: const Offset(0, 2)) ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: color.withValues(alpha: 0.1), shape: BoxShape.circle, ), child: Icon(icon, color: color, size: 18), ), const SizedBox(width: 8), Expanded( child: Text(label, style: TextStyle( fontSize: 11, color: isDark ? Colors.white54 : Colors.grey.shade600), overflow: TextOverflow.ellipsis), ), ], ), const SizedBox(height: 8), Text( value, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: color, ), ), ], ), ); } Widget _buildApprovalRateCard(Map totals, bool isDark) { final total = int.tryParse(totals['total_invoices']?.toString() ?? '0') ?? 0; final approved = int.tryParse(totals['approved_count']?.toString() ?? '0') ?? 0; final rate = total > 0 ? (approved / total) : 0.0; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isDark ? const Color(0xFF1E1E2E) : Colors.white, borderRadius: BorderRadius.circular(14), border: Border.all(color: isDark ? Colors.white10 : Colors.grey.shade200), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('نسبة القبول', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), Text( '${(rate * 100).toStringAsFixed(1)}%', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 18, color: rate > 0.8 ? const Color(0xFF10B981) : rate > 0.5 ? const Color(0xFFD4AF37) : const Color(0xFFDC2626), ), ), ], ), const SizedBox(height: 10), ClipRRect( borderRadius: BorderRadius.circular(4), child: LinearProgressIndicator( value: rate, minHeight: 8, color: rate > 0.8 ? const Color(0xFF10B981) : rate > 0.5 ? const Color(0xFFD4AF37) : const Color(0xFFDC2626), backgroundColor: isDark ? Colors.white10 : const Color(0xFFE2E8F0), ), ), const SizedBox(height: 8), Text( '$approved معتمدة من أصل $total فاتورة', style: TextStyle( fontSize: 12, color: isDark ? Colors.white54 : Colors.grey.shade600), ), ], ), ); } Widget _buildMonthRow(Map m, bool isDark) { return Container( margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: isDark ? const Color(0xFF1E1E2E) : Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: isDark ? Colors.white10 : Colors.grey.shade200), ), child: Row( children: [ // Month label Container( width: 56, padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 4), decoration: BoxDecoration( color: const Color(0xFF0F4C81).withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Text( _formatMonth(m['month']?.toString() ?? ''), style: const TextStyle( fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xFF0F4C81), ), textAlign: TextAlign.center, ), ), const SizedBox(width: 12), // Stats Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.receipt_long_rounded, size: 14, color: Colors.grey), const SizedBox(width: 4), Text('${_fmt(m['total_invoices'])} فاتورة', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w600)), const SizedBox(width: 12), const Icon(Icons.check_circle_outline, size: 14, color: Color(0xFF10B981)), const SizedBox(width: 4), Text('${_fmt(m['approved_count'])} معتمدة', style: const TextStyle( fontSize: 12, color: Color(0xFF10B981))), ], ), const SizedBox(height: 4), Row( children: [ Text( '${_fmtAmount(m['total_amount'])} د.أ مبيعات', style: TextStyle( fontSize: 12, color: isDark ? Colors.white70 : Colors.black87), ), const SizedBox(width: 12), Text( '${_fmtAmount(m['total_tax'])} د.أ ضريبة', style: const TextStyle( fontSize: 12, color: Color(0xFF8B5CF6)), ), ], ), ], ), ), ], ), ); } String _fmt(dynamic v) { if (v == null) return '0'; return int.tryParse(v.toString())?.toString() ?? v.toString(); } String _fmtAmount(dynamic v) { if (v == null) return '0.000'; final d = double.tryParse(v.toString()) ?? 0; return d.toStringAsFixed(3); } String _formatMonth(String m) { if (m.isEmpty) return m; final parts = m.split('-'); if (parts.length < 2) return m; final months = [ '', 'يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر' ]; final monthIndex = int.tryParse(parts[1]) ?? 0; final monthName = monthIndex > 0 && monthIndex < months.length ? months[monthIndex] : parts[1]; return '$monthName\n${parts[0]}'; } }