import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../dashboard/views/dashboard_view.dart'; import '../../invoices/views/invoices_list_view.dart'; import '../../notifications/views/notifications_view.dart'; import '../../settings/views/settings_view.dart'; import '../controllers/main_shell_controller.dart'; import '../../../app/routes/app_pages.dart'; import '../../../core/services/upload_progress_service.dart'; class MainShellView extends StatefulWidget { const MainShellView({super.key}); @override State createState() => _MainShellViewState(); } class _MainShellViewState extends State { final MainShellController _shellController = Get.find(); final UploadProgressService _progressService = Get.put(UploadProgressService()); // 5 pages: Home(0), Invoices(1), [Scanner FAB](2), Notifications(3), Settings(4) final List _pages = const [ DashboardView(), // 0 InvoicesListView(), // 1 SizedBox(), // 2 - Scanner (FAB placeholder) NotificationsView(), // 3 SettingsView(), // 4 ]; @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; final navBg = isDark ? const Color(0xFF1A1A2E) : Colors.white; const activeColor = Color(0xFF0F4C81); final inactiveColor = isDark ? Colors.white38 : const Color(0xFF94A3B8); return Scaffold( backgroundColor: isDark ? const Color(0xFF121212) : const Color(0xFFF5F7FA), body: Stack( children: [ Obx( () => IndexedStack( index: _getPageIndex(_shellController.currentIndex.value), children: [ _pages[0], // Dashboard _pages[1], // Invoices _pages[3], // Notifications _pages[4], // Settings ], ), ), // Global Upload Progress Overlay Obx(() => _progressService.isUploading.value ? Positioned( bottom: 80, left: 16, right: 16, child: _buildUploadOverlay(isDark), ) : const SizedBox.shrink()), ], ), floatingActionButton: _buildScannerFAB(), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, bottomNavigationBar: BottomAppBar( shape: const CircularNotchedRectangle(), notchMargin: 8, color: navBg, elevation: 16, child: SizedBox( height: 60, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ // Left side (2 items) _buildNavItem(0, Icons.home_rounded, 'الرئيسية', activeColor, inactiveColor), _buildNavItem(1, Icons.receipt_long_rounded, 'الفواتير', activeColor, inactiveColor), // Center gap for FAB const SizedBox(width: 48), // Right side (2 items) _buildNavItem(3, Icons.notifications_rounded, 'الإشعارات', activeColor, inactiveColor), _buildNavItem(4, Icons.settings_rounded, 'الإعدادات', activeColor, inactiveColor), ], ), ), ), ); } int _getPageIndex(int navIndex) { // Map nav index to page index (skip scanner placeholder at 2) if (navIndex <= 1) return navIndex; if (navIndex == 3) return 2; // Notifications if (navIndex == 4) return 3; // Settings return 0; } Widget _buildNavItem( int index, IconData icon, String label, Color active, Color inactive) { return Expanded( child: Obx(() { final isSelected = _shellController.currentIndex.value == index; return InkWell( onTap: () => _shellController.selectTab(index), borderRadius: BorderRadius.circular(12), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 2), decoration: isSelected ? BoxDecoration( color: active.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), ) : null, child: Icon(icon, color: isSelected ? active : inactive, size: 22), ), const SizedBox(height: 2), Text( label, style: TextStyle( fontSize: 10, fontWeight: isSelected ? FontWeight.w700 : FontWeight.w400, color: isSelected ? active : inactive, ), ), ], ), ); }), ); } Widget _buildScannerFAB() { return Container( width: 56, height: 56, decoration: BoxDecoration( shape: BoxShape.circle, gradient: const LinearGradient( colors: [Color(0xFFD4AF37), Color(0xFFF0D060)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), boxShadow: [ BoxShadow( color: const Color(0xFFD4AF37).withValues(alpha: 0.4), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: FloatingActionButton( onPressed: () => Get.toNamed(AppRoutes.SCANNER), backgroundColor: Colors.transparent, elevation: 0, heroTag: 'scanner_fab', child: const Icon(Icons.document_scanner_rounded, color: Colors.white, size: 26), ), ); } Widget _buildUploadOverlay(bool isDark) { final status = _progressService.status.value; final progress = _progressService.progress.value; Color accentColor = status == 'done' ? const Color(0xFF10B981) : const Color(0xFF0F4C81); String statusText = status == 'uploading' ? 'جاري رفع الصور...' : (status == 'processing' ? 'جاري استخراج البيانات...' : 'اكتملت المعالجة ✓'); return Card( elevation: 8, shadowColor: Colors.black26, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), color: isDark ? const Color(0xFF1E1E2E) : Colors.white, child: Padding( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ status == 'done' ? const Icon(Icons.check_circle, color: Color(0xFF10B981), size: 24) : const SizedBox( width: 24, height: 24, child: CircularProgressIndicator( strokeWidth: 2, color: Color(0xFF0F4C81))), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(statusText, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 13)), Text( '${_progressService.companyName.value} • ${_progressService.currentImageIndex.value}/${_progressService.totalImages.value}', style: TextStyle( fontSize: 11, color: isDark ? Colors.white38 : Colors.grey), ), ], ), ), Text( '${(progress * 100).toInt()}%', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14, color: accentColor), ), ], ), const SizedBox(height: 10), ClipRRect( borderRadius: BorderRadius.circular(4), child: LinearProgressIndicator( value: progress, backgroundColor: isDark ? Colors.white10 : const Color(0xFFE2E8F0), color: accentColor, minHeight: 6, ), ), ], ), ), ); } }