import 'dart:io'; import 'package:wanisdriver/Provider/utils_singleton.dart'; import 'package:wanisdriver/utils/colors.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:image_picker/image_picker.dart'; import 'package:provider/provider.dart'; import '../Provider/ThemeProvider.dart'; import '../Provider/authentification_provider.dart'; import '../Provider/driver_provider.dart'; import '../Provider/language_provider.dart'; import '../config/AppSnackbar.dart'; import '../config/constants/app_constant.dart'; import '../config/language/language_enum.dart'; import '../widgets/DottedBorderContainer.dart'; import '../widgets/custom_button.dart'; import '../widgets/custom_text.dart'; class UpdateProfileScreen extends StatefulWidget { const UpdateProfileScreen({Key? key}) : super(key: key); @override _UpdateProfileScreenState createState() => _UpdateProfileScreenState(); } class _UpdateProfileScreenState extends State { final TextEditingController nameController = TextEditingController(); final TextEditingController emailController = TextEditingController(); final TextEditingController phoneController = TextEditingController(); final TextEditingController idCardController = TextEditingController(); late final AuthProvider authProvider; final ImagePicker _picker = ImagePicker(); File? _profileImage; List _cinImages = []; List _permisImages = []; List _cinImageUrls = []; List _permisImageUrls = []; @override void initState() { super.initState(); authProvider = context.read(); _initializeData(); } void _initializeData() { nameController.text = utils.user?.name ?? ''; emailController.text = utils.user?.email ?? ''; phoneController.text = utils.user?.phoneNumber ?? ''; idCardController.text = utils.user?.driver?.nationalid ?? ''; // Load existing CIN images if (utils.user?.driver?.nationalidmedia != null) { _cinImageUrls = utils.user!.driver!.nationalidmedia !.map((img) => img.url ?? '') .where((url) => url.isNotEmpty) .toList(); } // Load existing Permis images if (utils.user?.driver?.driverLicence != null) { _permisImageUrls = utils.user!.driver!.driverLicence !.map((img) => img.url ?? '') .where((url) => url.isNotEmpty) .toList(); } } @override void dispose() { nameController.dispose(); emailController.dispose(); phoneController.dispose(); idCardController.dispose(); super.dispose(); } Future _selectProfileImage() async { showModalBottomSheet( context: context, builder: (BuildContext context) { return SafeArea( child: Wrap( children: [ ListTile( leading: const Icon(Icons.photo_library), title: const Text('Choose from Gallery'), onTap: () async { Navigator.pop(context); final XFile? image = await _picker.pickImage( source: ImageSource.gallery, imageQuality: 85, ); if (image != null) { setState(() { _profileImage = File(image.path); }); await authProvider.updateProfilePicture(File(image.path)); } }, ), ListTile( leading: const Icon(Icons.camera_alt), title: const Text('Take a Photo'), onTap: () async { Navigator.pop(context); final XFile? image = await _picker.pickImage( source: ImageSource.camera, imageQuality: 85, ); if (image != null) { setState(() { _profileImage = File(image.path); }); await authProvider.updateProfilePicture(File(image.path)); } }, ), ], ), ); }, ); } Future _pickMultipleImages(String type) async { showModalBottomSheet( context: context, builder: (BuildContext context) { return SafeArea( child: Wrap( children: [ ListTile( leading: const Icon(Icons.photo_library), title: const Text('Choose Multiple from Gallery'), onTap: () async { Navigator.pop(context); final List images = await _picker.pickMultiImage( imageQuality: 85, ); if (images.isNotEmpty) { setState(() { if (type == 'cin') { _cinImages.addAll(images.map((img) => File(img.path))); } else if (type == 'permis') { _permisImages.addAll(images.map((img) => File(img.path))); } }); } }, ), ListTile( leading: const Icon(Icons.camera_alt), title: const Text('Take a Photo'), onTap: () async { Navigator.pop(context); final XFile? image = await _picker.pickImage( source: ImageSource.camera, imageQuality: 85, ); if (image != null) { setState(() { if (type == 'cin') { _cinImages.add(File(image.path)); } else if (type == 'permis') { _permisImages.add(File(image.path)); } }); } }, ), ], ), ); }, ); } void _removeImage(int index, bool isLocal, String type) { setState(() { if (type == 'cin') { if (isLocal) { _cinImages.removeAt(index); } else { _cinImageUrls.removeAt(index); } } else if (type == 'permis') { if (isLocal) { _permisImages.removeAt(index); } else { _permisImageUrls.removeAt(index); } } }); } @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Column( children: [ // Header Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: Row( children: [ Container( decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.grey.shade200, ), child: IconButton( icon: const Icon( Icons.arrow_back, color: Colors.black, size: 20, ), onPressed: () => Navigator.pop(context), ), ), const Expanded( child: Center( child: Text( 'User Informations', style: TextStyle( color: Colors.black, fontSize: 17, fontFamily: 'Inter', fontWeight: FontWeight.w600, ), ), ), ), const SizedBox(width: 48), ], ), ), // Content Expanded( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox(height: 16), // Profile Image Stack( alignment: Alignment.center, clipBehavior: Clip.none, children: [ Container( width: 140, height: 140, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: const Color(0xFFE0E0E0), width: 3, ), ), child: ClipOval( child: _profileImage != null ? Image.file( _profileImage!, fit: BoxFit.cover, ) : CachedNetworkImage( imageUrl: '$mediaUrl${authProvider.profile?.image?.url}', fit: BoxFit.cover, placeholder: (context, url) => const Center( child: CircularProgressIndicator(), ), errorWidget: (context, url, error) => Image.asset( 'assets/images/user_avatar.png', fit: BoxFit.cover, ), ), ), ), // Rating badge (optional) Positioned( top: 0, right: 0, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.orange, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.star, color: Colors.white, size: 14, ), const SizedBox(width: 4), Text( utils.user?.driver?.rating?.toStringAsFixed(1) ?? '4.9', style: const TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, ), ), ], ), ), ), // Edit button Positioned( bottom: 0, child: GestureDetector( onTap: _selectProfileImage, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: const Color(0xFF8979FF), borderRadius: BorderRadius.circular(8), ), child: authProvider.loaderImage ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : const Row( mainAxisSize: MainAxisSize.min, children: [ Icon( LucideIcons.pen, size: 14, color: Colors.white, ), SizedBox(width: 6), Text( 'Edit', style: TextStyle( color: Colors.white, fontSize: 13, fontWeight: FontWeight.w600, ), ), ], ), ), ), ), ], ), const SizedBox(height: 32), // Name Field _buildTextField( icon: LucideIcons.user, hint: 'Your Name', controller: nameController, ), const SizedBox(height: 16), // Email Field _buildTextField( icon: LucideIcons.mail, hint: 'Your email', controller: emailController, readOnly: true, ), const SizedBox(height: 16), // Phone Field _buildTextField( icon: LucideIcons.phone, hint: 'Your Number', controller: phoneController, ), const SizedBox(height: 16), // ID Card Number Field _buildTextField( icon: LucideIcons.credit_card, hint: 'ID Card Number', controller: idCardController, ), const SizedBox(height: 24), // CIN Images Section _buildDocumentSection( label: 'CIN', type: 'cin', ), const SizedBox(height: 24), // Permis Images Section _buildDocumentSection( label: 'Permis', type: 'permis', ), const SizedBox(height: 32), // Update Button CustomButton( borderRadius: 12, height: 55, isloading: false, loadercolor: Colors.white, onClick: () async { final driverProvider = Provider.of(context, listen: false); // TODO: Implement update with all fields including images bool hasChanges = nameController.text != (utils.user?.name ?? '') || phoneController.text != (utils.user?.phoneNumber ?? '') || idCardController.text != (utils.user?.driver?.nationalid ?? '') || _cinImages.isNotEmpty || _permisImages.isNotEmpty; if (!hasChanges) { AppSnackbar.showInfo("Info", "No changes to save"); return; } // Call update method with all data bool success = await driverProvider.updateVehicleImages( name: nameController.text, phone: phoneController.text, cin: idCardController.text, cinImages: _cinImages, permisImages: _permisImages, ); if (success) { // Navigate back or show success message Navigator.pop(context); } }, title: 'Update', width: MediaQuery.of(context).size.width, backgroundColor: Theme.of(context).brightness == Brightness.dark ? AppColors.darkPrimaryColor : AppColors.primaryColor, ), const SizedBox(height: 24), ], ), ), ), ], ), ), ); } Widget _buildTextField({ required IconData icon, required String hint, required TextEditingController controller, bool readOnly = false, }) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), decoration: BoxDecoration( color: const Color(0xFFFAFAFA), borderRadius: BorderRadius.circular(12), border: Border.all( color: const Color(0xFFE0E0E0), width: 1, ), ), child: Row( children: [ Icon( icon, size: 20, color: const Color(0xFF8C929C), ), const SizedBox(width: 12), Expanded( child: TextField( controller: controller, readOnly: readOnly, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w400, color: Colors.black, ), decoration: InputDecoration( hintText: hint, hintStyle: const TextStyle( color: Color(0xFFCCCCCC), fontSize: 15, fontWeight: FontWeight.w400, ), border: InputBorder.none, isDense: true, contentPadding: const EdgeInsets.symmetric(vertical: 12), ), ), ), ], ), ); } Widget _buildDocumentSection({ required String label, required String type, }) { final localImages = type == 'cin' ? _cinImages : _permisImages; final urlImages = type == 'cin' ? _cinImageUrls : _permisImageUrls; final totalImages = localImages.length + urlImages.length; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: const TextStyle( color: Color(0xFF8C929C), fontSize: 13, fontFamily: 'Inter', fontWeight: FontWeight.w500, ), ), const SizedBox(height: 10), if (totalImages > 0) GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 8, mainAxisSpacing: 8, childAspectRatio: 1, ), itemCount: totalImages + 1, itemBuilder: (context, index) { if (index == totalImages) { return _buildAddButton(type); } if (index < localImages.length) { return _buildImageItem( image: localImages[index], index: index, isLocal: true, type: type, ); } final urlIndex = index - localImages.length; return _buildImageItem( imageUrl: urlImages[urlIndex], index: urlIndex, isLocal: false, type: type, ); }, ) else _buildAddButton(type), ], ); } Widget _buildAddButton(String type) { return GestureDetector( onTap: () => _pickMultipleImages(type), child: DottedBorderContainer( child: Container( decoration: BoxDecoration( color: const Color(0xFFFAFAFA), borderRadius: BorderRadius.circular(10), ), child: Center( child: Image.asset( 'assets/images/icon_button.png', width: 75, height: 75, ), ), ), ), ); } Widget _buildImageItem({ File? image, String? imageUrl, required int index, required bool isLocal, required String type, }) { return Stack( children: [ DottedBorderContainer( child: ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( decoration: BoxDecoration( color: const Color(0xFFFAFAFA), borderRadius: BorderRadius.circular(10), ), child: isLocal && image != null ? Image.file( image, fit: BoxFit.cover, width: double.infinity, height: double.infinity, ) : CachedNetworkImage( imageUrl: '$mediaUrl$imageUrl', fit: BoxFit.cover, width: double.infinity, height: double.infinity, placeholder: (context, url) => const Center( child: CircularProgressIndicator( strokeWidth: 2, color: Color(0xFFAAAAAA), ), ), errorWidget: (context, url, error) => Center( child: Image.asset( 'assets/images/icon_button.png', width: 40, height: 40, ), ), ), ), ), ), Positioned( top: 4, right: 4, child: GestureDetector( onTap: () => _removeImage(index, isLocal, type), child: Container( padding: const EdgeInsets.all(4), decoration: const BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), child: const Icon( Icons.close, color: Colors.white, size: 14, ), ), ), ), ], ); } }