import 'dart:convert'; import 'package:crypto/crypto.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:service/constant/box_name.dart'; import 'package:service/constant/links.dart'; import 'package:service/controller/functions/crud.dart'; import 'package:service/main.dart'; import 'package:service/print.dart'; import 'package:service/views/widgets/my_dialog.dart'; import 'pages/registration_captain_page.dart'; class RegisterCaptainServiceController extends GetxController { // --- UI State Management --- var isLoading = true.obs; late PageController pageController; var currentPageIndex = 0.obs; var driverId = ''.obs; var phone = ''.obs; var serverData = {}.obs; // En tu archivo registration_captain_controller.dart final phoneController = TextEditingController(); // --- Dynamic Document Image URLs --- final Map docUrls = { 'driver_license_front': ''.obs, 'driver_license_back': ''.obs, 'car_license_front': ''.obs, 'car_license_back': ''.obs, }; // --- Text Field Controllers --- late TextEditingController firstNameController; late TextEditingController lastNameController; late TextEditingController siteController; late TextEditingController nationalNumberController; late TextEditingController birthdateController; late TextEditingController licenseCategoriesController; late TextEditingController expiryDateController; late TextEditingController ownerController; late TextEditingController colorController; late TextEditingController carPlateController; late TextEditingController vinController; late TextEditingController licenseIssueDateController; late TextEditingController carLicenseExpiryDateController; late TextEditingController makeController; late TextEditingController modelController; late TextEditingController yearController; // --- Reactive State for Dropdowns --- var selectedGender = ''.obs; var colorHex = ''.obs; var selectedFuel = ''.obs; @override void onInit() { super.onInit(); pageController = PageController(); // final arguments = Get.arguments; // driverId.value = arguments?['driverId']; // Fallback for testing // phone.value = arguments?['phone']; // Fallback for testing _initializeTextControllers(); _initializeDocUrls(); fetchDataFromServer(); } void _initializeDocUrls() { const baseUrl = "https://syria.intaleq.xyz/intaleq/auth/syria/driversDocs/syria.intaleq.xyz-"; docUrls['driver_license_front']!.value = "$baseUrl${driverId.value}-driver_license_front.jpg"; docUrls['driver_license_back']!.value = "$baseUrl${driverId.value}-driver_license_back.jpg"; docUrls['car_license_front']!.value = "$baseUrl${driverId.value}-car_license_front.jpg"; docUrls['car_license_back']!.value = "$baseUrl${driverId.value}-car_license_back.jpg"; } void _initializeTextControllers() { firstNameController = TextEditingController(); lastNameController = TextEditingController(); siteController = TextEditingController(); nationalNumberController = TextEditingController(); birthdateController = TextEditingController(); licenseCategoriesController = TextEditingController(); expiryDateController = TextEditingController(); ownerController = TextEditingController(); colorController = TextEditingController(); carPlateController = TextEditingController(); vinController = TextEditingController(); licenseIssueDateController = TextEditingController(); carLicenseExpiryDateController = TextEditingController(); makeController = TextEditingController(); modelController = TextEditingController(); yearController = TextEditingController(); } Future fetchDataFromServer() async { isLoading.value = true; try { var responseString = await CRUD().post( link: AppLink.getDriverDetailsForActivate, payload: {'driverId': driverId.value}); if (responseString != 'failure') { var decodedResponse = jsonDecode(responseString); if (decodedResponse['status'] == 'success' && (decodedResponse['message'] as List).isNotEmpty) { var rawData = decodedResponse['message'][0] as Map; // Sanitize data: ensure all values are strings to prevent type errors serverData.value = rawData .map((key, value) => MapEntry(key, value?.toString() ?? '')); _populateControllersWithServerData(); } } } catch (e) { Get.snackbar('Error', 'An unexpected error occurred: $e'); } finally { isLoading.value = false; } } void _populateControllersWithServerData() { firstNameController.text = serverData['first_name'] ?? ''; lastNameController.text = serverData['last_name'] ?? ''; siteController.text = serverData['site'] ?? ''; nationalNumberController.text = serverData['national_number'] ?? ''; birthdateController.text = serverData['birthdate'] ?? ''; selectedGender.value = serverData['gender'] ?? ''; licenseCategoriesController.text = serverData['license_categories'] ?? ''; expiryDateController.text = serverData['expiry_date'] ?? ''; ownerController.text = serverData['owner'] ?? ''; final serverColorName = serverData['color'] ?? ''; final colorOption = kCarColorOptions.firstWhere( (opt) => opt['key'] == serverColorName, orElse: () => {'key': serverColorName, 'hex': '#000000'}); // Fallback colorController.text = colorOption['key']!; colorHex.value = colorOption['hex']!; carPlateController.text = serverData['car_plate'] ?? ''; vinController.text = serverData['vin'] ?? ''; licenseIssueDateController.text = serverData['issue_date'] ?? ''; carLicenseExpiryDateController.text = serverData['expiration_date'] ?? ''; makeController.text = serverData['make'] ?? ''; modelController.text = serverData['model'] ?? ''; selectedFuel.value = serverData['fuel'] ?? ''; yearController.text = serverData['year'] ?? ''; } Future selectDate( BuildContext context, TextEditingController controller) async { DateTime initialDate = DateTime.now(); try { if (controller.text.isNotEmpty) initialDate = DateFormat('yyyy-MM-dd').parse(controller.text); } catch (e) {/* Use default if parsing fails */} DateTime? pickedDate = initialDate; await showCupertinoModalPopup( context: context, builder: (BuildContext context) => Container( height: 280, color: CupertinoColors.systemBackground.resolveFrom(context), child: Column( children: [ SizedBox( height: 200, child: CupertinoDatePicker( initialDateTime: initialDate, minimumDate: DateTime(1950), maximumDate: DateTime(2050), mode: CupertinoDatePickerMode.date, onDateTimeChanged: (DateTime newDate) { pickedDate = newDate; }, ), ), CupertinoButton( child: Text('Done'.tr), onPressed: () { if (pickedDate != null) controller.text = DateFormat('yyyy-MM-dd').format(pickedDate!); Navigator.of(context).pop(); }, ), ], ), ), ); } void nextPage() { if (currentPageIndex.value < 3) pageController.nextPage( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut); } void previousPage() { if (currentPageIndex.value > 0) pageController.previousPage( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut); } void updateAndActivateSyrianDriver() { isLoading.value = true; var bytes = utf8.encode(phoneController.text); // 2. Genera el hash MD5 completo var digest = md5.convert(bytes); // 3. Convierte el hash a un string (tendrá 32 caracteres) String fullMd5Hash = digest.toString(); // 4. Trunca el string a los primeros 20 caracteres driverId.value = fullMd5Hash.substring(0, 20); Map dataToSend = { // Driver fields from all pages 'id': driverId.value, 'phone': phoneController.text, 'first_name': firstNameController.text, 'last_name': lastNameController.text, 'site': siteController.text, 'national_number': nationalNumberController.text, 'gender': selectedGender.value, 'birthdate': birthdateController.text, 'license_categories': licenseCategoriesController.text, 'expiry_date': expiryDateController.text, 'license_issue_date': licenseIssueDateController.text, 'password': md5.convert(utf8.encode('123456')).toString(), 'status': 'actives', // Car fields from all pages 'owner': ownerController.text, 'color': colorController.text, 'color_hex': colorHex.value, 'car_plate': carPlateController.text, 'maritalStatus': box.read(BoxName.employeename) ?? 'unknown', // 'vin': vinController.text, 'expiration_date': carLicenseExpiryDateController.text, 'make': makeController.text, 'model': modelController.text, 'fuel': selectedFuel.value, 'year': yearController.text, }; print("--- Submitting Data to Server ---"); print(dataToSend); CRUD() .post( link: '${AppLink.server}/serviceapp/registerDriverAndCarService.php', payload: dataToSend) .then((response) { isLoading.value = false; var decodedResponse = (response); Log.print('decodedResponse: ${decodedResponse}'); if (decodedResponse != 'failure') { MyDialog().getDialog('Success'.tr, '', Text('Driver has been activated successfully!'.tr), () { Get.back(); Get.back(); // fetchDataFromServer(); Get.back(); // Get.off(() => RegisterCaptain()); }); } else { Get.snackbar( 'Error'.tr, 'Failed to update driver: ${decodedResponse['message']}'.tr, backgroundColor: Colors.red, colorText: Colors.white, ); } }).catchError((error) { isLoading.value = false; Get.snackbar( 'Error'.tr, 'An error occurred: $error'.tr, backgroundColor: Colors.red, colorText: Colors.white, ); }); } static const List> kCarColorOptions = [ {'key': 'white', 'hex': '#FFFFFF'}, {'key': 'black', 'hex': '#000000'}, {'key': 'silver', 'hex': '#C0C0C0'}, {'key': 'gray', 'hex': '#808080'}, {'key': 'gunmetal', 'hex': '#2A3439'}, {'key': 'red', 'hex': '#C62828'}, {'key': 'blue', 'hex': '#1565C0'}, {'key': 'navy', 'hex': '#0D47A1'}, {'key': 'green', 'hex': '#2E7D32'}, {'key': 'darkGreen', 'hex': '#1B5E20'}, {'key': 'beige', 'hex': '#D7CCC8'}, {'key': 'brown', 'hex': '#5D4037'}, {'key': 'maroon', 'hex': '#800000'}, {'key': 'burgundy', 'hex': '#800020'}, {'key': 'yellow', 'hex': '#F9A825'}, {'key': 'orange', 'hex': '#EF6C00'}, {'key': 'gold', 'hex': '#D4AF37'}, {'key': 'bronze', 'hex': '#CD7F32'}, {'key': 'champagne', 'hex': '#EFE1C6'}, {'key': 'purple', 'hex': '#6A1B9A'}, ]; static const List kFuelOptions = [ 'بنزين', 'ديزل', 'هايبرد', 'كهربائي' ]; Color hexToColor(String code) => Color(int.parse(code.substring(1, 7), radix: 16) + 0xFF000000); void updateColorSelection(String hex) { colorHex.value = hex; colorController.text = kCarColorOptions.firstWhere((o) => o['hex'] == hex)['key']!; } @override void onClose() { pageController.dispose(); firstNameController.dispose(); lastNameController.dispose(); siteController.dispose(); nationalNumberController.dispose(); birthdateController.dispose(); licenseCategoriesController.dispose(); expiryDateController.dispose(); ownerController.dispose(); colorController.dispose(); carPlateController.dispose(); vinController.dispose(); licenseIssueDateController.dispose(); carLicenseExpiryDateController.dispose(); makeController.dispose(); modelController.dispose(); yearController.dispose(); super.onClose(); } }