import 'dart:convert'; import 'dart:ffi'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:http/http.dart' as http; import '../../constant/api_key.dart'; import '../../constant/box_name.dart'; import '../../constant/colors.dart'; import '../../constant/info.dart'; import '../../constant/links.dart'; import '../../constant/style.dart'; import '../../main.dart'; import '../functions/crud.dart'; class RegisterCaptainController extends GetxController { bool isDriverSaved = false; bool isCarSaved = false; Map? arguments; String? driverId; String? email; String? phone; @override void onInit() { super.onInit(); arguments = Get.arguments; initArguments(); } void driveInit() { arguments = Get.arguments; initArguments(); } void initArguments() { if (arguments != null) { driverId = arguments!['driverId']; email = arguments!['email']; phone = arguments!['phone_number']; } else { print('Arguments are null'); } } Map responseMap = {}; Map responseCarLicenseMapJordan = {}; Map responseBackCarLicenseMap = {}; Map responseIdCardMap = {}; Map responseIdCardDriverEgyptBack = {}; Map responseForComplaint = {}; Map responseIdCardDriverEgyptFront = {}; Map responseIdEgyptFront = {}; Map responseCriminalRecordEgypt = {}; Map responseIdEgyptBack = {}; Map responseIdEgyptDriverLicense = {}; String? responseIdCardDriverEgypt1; bool isloading = false; var image; DateTime now = DateTime.now(); bool isLoading = false; Future allMethodForAI(String prompt, imagePath, driverID) async { isLoading = true; update(); var extractedString = await CRUD().arabicTextExtractByVisionAndAI( imagePath: imagePath, driverID: driverID); var json = jsonDecode(extractedString); var textValues = extractTextFromLines(json); // await Get.put(AI()).geminiAiExtraction(prompt, textValues, imagePath); await Get.put(RegisterCaptainController()) .anthropicAI(textValues, prompt, imagePath); isLoading = false; update(); } String extractTextFromLines(Map jsonData) { final readResult = jsonData['readResult']; final blocks = readResult['blocks']; final StringBuffer buffer = StringBuffer(); for (final block in blocks) { final lines = block['lines']; for (final line in lines) { final text = line['text']; buffer.write(text); buffer.write('\n'); } } return buffer.toString().trim(); } List driverNotCompleteRegistration = []; getDriverNotCompleteRegistration() async { var res = await CRUD() .get(link: AppLink.getDriverNotCompleteRegistration, payload: {}); if (res != 'failure') { var d = jsonDecode(res)['message']; driverNotCompleteRegistration = d; update(); } else { Get.snackbar(res, ''); } } final today = DateTime.now(); Future addDriverAndCarEgypt() async { final expiryDate = responseIdEgyptDriverLicense['expiry_date']; final expiryDateTime = DateTime.tryParse(expiryDate); final isExpired = expiryDateTime != null && expiryDateTime.isBefore(today); final taxExpiryDate = responseIdCardDriverEgyptBack['tax_expiry']; // Get the inspection date from the response final inspectionDate = responseIdCardDriverEgyptBack['inspection_date']; final year = int.parse(inspectionDate.split('-')[0]); // Try parsing the tax expiry date. If it fails, set it to null. final taxExpiryDateTime = DateTime.tryParse(taxExpiryDate ?? ''); final isExpiredCar = taxExpiryDateTime != null && taxExpiryDateTime.isBefore(today); // Check if the inspection date is before today final inspectionDateTime = DateTime(year, 1, 1); final isInspectionExpired = inspectionDateTime.isBefore(today); if (isExpiredCar || isInspectionExpired) { Get.defaultDialog( title: 'Expired Driver’s License'.tr, content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.warning, size: 48, color: Colors.red), const SizedBox(height: 16), Text( 'Your driver’s license and/or car tax has expired. Please renew them before proceeding.' .tr, textAlign: TextAlign.center, style: AppStyle.title, ), const SizedBox(height: 16), IconButton( onPressed: () async { // await Get.find().speakText( // 'Your driver’s license and/or car tax has expired. Please renew them before proceeding.' // .tr, // ); }, icon: const Icon(Icons.volume_up), ), ], ), actions: [ TextButton( onPressed: () { Get.back(); }, child: const Text('OK'), ), ], ); } else if (isExpired) { Get.defaultDialog( title: 'Expired Driver’s License'.tr, content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.warning, size: 48, color: Colors.red), const SizedBox(height: 16), Text( 'Your driver’s license has expired. Please renew it before proceeding.' .tr, textAlign: TextAlign.center, style: AppStyle.title, ), const SizedBox(height: 16), IconButton( onPressed: () async { // await Get.find().speakText( // 'Your driver’s license has expired. Please renew it before proceeding.' // .tr, // ); }, icon: const Icon(Icons.volume_up), ), ], ), actions: [ TextButton( onPressed: () { Get.back(); }, child: const Text('OK'), ), ], ); } else if (responseIdEgyptDriverLicense['national_number'] .toString() .substring(0, 12) != responseIdEgyptBack['nationalID'].toString().substring(0, 12)) { Get.defaultDialog( barrierDismissible: false, title: 'ID Mismatch', content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.warning, size: 48, color: Colors.red), const SizedBox(height: 16), Text( 'The national number on your driver’s license does not match the one on your ID document. Please verify and provide the correct documents.' .tr, textAlign: TextAlign.center, style: AppStyle.title, ), const SizedBox(height: 16), IconButton( onPressed: () async { // await Get.find().speakText( // 'The national number on your driver’s license does not match the one on your ID document. Please verify and provide the correct documents.', // ); }, icon: const Icon(Icons.volume_up), ), ], ), actions: [ TextButton( onPressed: () { Get.back(); }, child: const Text('OK'), ), ], ); } // else if (responseCriminalRecordEgypt['FullName'] != // responseIdEgyptDriverLicense['name_arabic']) { // Get.defaultDialog( // barrierDismissible: false, // title: 'Criminal Record Mismatch', // content: Column( // mainAxisSize: MainAxisSize.min, // children: [ // const Icon(Icons.warning, size: 48, color: Colors.red), // const SizedBox(height: 16), // Text( // 'The full name on your criminal record does not match the one on your driver’s license. Please verify and provide the correct documents.' // .tr, // textAlign: TextAlign.center, // style: AppStyle.title, // ), // const SizedBox(height: 16), // IconButton( // onPressed: () async { // await Get.find().speakText( // 'The full name on your criminal record does not match the one on your driver’s license. Please verify and provide the correct documents.' // .tr, // ); // }, // icon: const Icon(Icons.volume_up), // ), // ], // ), // actions: [ // TextButton( // onPressed: () { // Get.back(); // }, // child: const Text('OK'), // ), // ], // ); // } else { await addDriverEgypt(); await addRegistrationCarEgypt(); if (isCarSaved && isDriverSaved) { Get.snackbar('added', '', backgroundColor: AppColor.greenColor); // Get.offAll(() => HomeCaptain()); // Get.offAll(() => HomeCaptain()); } } } Future addDriverEgypt() async { isLoading = true; update(); var payload = { 'first_name': responseIdEgyptDriverLicense['firstName']?.toString() ?? 'Not specified', 'last_name': responseIdEgyptDriverLicense['lastName']?.toString() ?? 'Not specified', 'email': email?.toString() ?? 'Not specified', 'phone': phone?.toString() ?? 'Not specified', 'id': driverId?.toString() ?? 'Not specified', 'password': '123456', 'gender': responseIdEgyptBack['gender']?.toString() ?? 'Not specified', 'license_type': responseIdEgyptDriverLicense['license_type']?.toString() ?? 'Not specified', 'national_number': responseIdEgyptBack['nationalID']?.toString() ?? 'Not specified', 'name_arabic': responseIdEgyptDriverLicense['name_arabic']?.toString() ?? 'Not specified', 'name_english': responseIdEgyptDriverLicense['name_english']?.toString() ?? 'Not specified', 'issue_date': responseIdEgyptDriverLicense['issue_date']?.toString() ?? 'Not specified', 'expiry_date': responseIdEgyptDriverLicense['expiry_date']?.toString() ?? 'Not specified', 'license_categories': responseIdEgyptDriverLicense['license_categories'] is List ? responseIdEgyptDriverLicense['license_categories'].join(', ') : responseIdEgyptDriverLicense['license_categories']?.toString() ?? 'Not specified', 'address': responseIdEgyptFront['address']?.toString() ?? 'Not specified', 'card_id': responseIdEgyptFront['card_id']?.toString() ?? 'Not specified', 'occupation': responseIdEgyptBack['occupation']?.toString() ?? 'Not specified', 'education': responseIdEgyptBack['occupation']?.toString() ?? 'Not specified', 'licenseIssueDate': responseIdEgyptDriverLicense['issue_date']?.toString() ?? 'Not specified', 'religion': responseIdEgyptBack['religion']?.toString() ?? 'Not specified', 'status': 'yet', 'birthdate': responseIdEgyptFront['dob']?.toString() ?? 'Not specified', 'maritalStatus': responseIdEgyptBack['maritalStatus']?.toString() ?? 'Not specified', 'site': responseIdEgyptDriverLicense['address']?.toString() ?? 'Not specified', 'employmentType': responseIdEgyptDriverLicense['employmentType']?.toString() ?? 'Not specified', }; var res = await CRUD().post(link: AppLink.signUpCaptin, payload: payload); var status1 = jsonDecode(res); isLoading = false; update(); // Handle response if (status1['status'] == 'success') { isDriverSaved = true; Get.snackbar('Success', 'Driver data saved successfully', backgroundColor: AppColor.greenColor); } else { Get.snackbar('Error', 'Failed to save driver data', backgroundColor: Colors.red); } } addCriminalDeocuments() async { var res = await CRUD().post(link: AppLink.addCriminalDocuments, payload: { "driverId": box.read(BoxName.driverID), "IssueDate": responseCriminalRecordEgypt['IssueDate'], "InspectionResult": responseCriminalRecordEgypt['InspectionResult'], }); if (res != 'failure') { Get.snackbar('uploaded sucssefuly'.tr, ''); } } Future addRegistrationCarEgypt() async { try { isLoading = true; update(); var res = await CRUD().post(link: AppLink.addRegisrationCar, payload: { 'driverID': driverId, 'vin': responseIdCardDriverEgyptBack['chassis'].toString(), 'car_plate': responseIdCardDriverEgyptFront['car_plate'].toString(), 'make': responseIdCardDriverEgyptBack['make'].toString(), 'model': responseIdCardDriverEgyptBack['model'], 'year': responseIdCardDriverEgyptBack['year'].toString(), 'expiration_date': responseIdCardDriverEgyptFront['LicenseExpirationDate'].toString(), 'color': responseIdCardDriverEgyptBack['color'], 'owner': responseIdCardDriverEgyptFront['owner'], 'color_hex': responseIdCardDriverEgyptBack['color_hex'].toString(), 'address': responseIdCardDriverEgyptFront['address'].toString(), 'displacement': responseIdCardDriverEgyptBack['engine'].toString(), 'fuel': responseIdCardDriverEgyptBack['fuel'].toString(), 'registration_date': '${responseIdCardDriverEgyptBack['inspection_date']}', }); isLoading = false; update(); var status = jsonDecode(res); if (status['status'] == 'success') { isCarSaved = true; Get.snackbar('Success', 'message', backgroundColor: AppColor.greenColor); } } catch (e) {} } Future getComplaintDataToAI() async { var res = await CRUD().get( link: AppLink.getComplaintAllDataForDriver, payload: {'driver_id': driverId.toString()}, ); if (res != 'failure') { var d = jsonDecode(res)['message']; return d; } else { return [ {'data': 'no data'} ]; } } Future anthropicAIForComplaint() async { var dataComplaint = await getComplaintDataToAI(); var messagesData = [ { "role": "user", "content": [ { "type": "text", "text": "$dataComplaint ${AppInformation.complaintPrompt} " } ] } ]; var requestBody = jsonEncode({ "model": "claude-3-haiku-20240307", "max_tokens": 1024, "temperature": 0, "system": "Json output only without any additional ", "messages": messagesData, }); final response = await http.post( Uri.parse('https://api.anthropic.com/v1/messages'), headers: { 'x-api-key': AK.anthropicAIkeySeferNew, 'anthropic-version': '2023-06-01', 'content-type': 'application/json' }, body: requestBody, ); if (response.statusCode == 200) { var responseData = jsonDecode(utf8.decode(response.bodyBytes)); // Process the responseData as needed responseForComplaint = jsonDecode(responseData['content'][0]['text']); } } Future anthropicAI( String payload, String prompt, String idType) async { var messagesData = [ { "role": "user", "content": [ {"type": "text", "text": "$payload $prompt"} ] } ]; var requestBody = jsonEncode({ "model": "claude-3-haiku-20240307", "max_tokens": 1024, "temperature": 0, "system": "Json output only without any additional ", "messages": messagesData, }); final response = await http.post( Uri.parse('https://api.anthropic.com/v1/messages'), headers: { 'x-api-key': AK.anthropicAIkeySeferNew, 'anthropic-version': '2023-06-01', 'content-type': 'application/json' }, body: requestBody, ); if (response.statusCode == 200) { var responseData = jsonDecode(utf8.decode(response.bodyBytes)); // Process the responseData as needed if (idType == 'car_back') { responseIdCardDriverEgyptBack = jsonDecode(responseData['content'][0]['text']); } else if (idType == 'car_front') { responseIdCardDriverEgyptFront = jsonDecode(responseData['content'][0]['text']); } else if (idType == 'id_front') { responseIdEgyptFront = jsonDecode(responseData['content'][0]['text']); } else if (idType == 'id_back') { responseIdEgyptBack = jsonDecode(responseData['content'][0]['text']); } else if (idType == 'driver_license') { responseIdEgyptDriverLicense = jsonDecode(responseData['content'][0]['text']); } else if (idType == 'criminalRecord') { responseCriminalRecordEgypt = jsonDecode(responseData['content'][0]['text']); } update(); return responseData.toString(); } return responseIdCardDriverEgyptBack.toString(); } Future geminiAiExtraction(String prompt, payload, String idType) async { var requestBody = jsonEncode({ "contents": [ { "parts": [ {"text": "$payload $prompt"} ] } ], "generationConfig": { "temperature": 1, "topK": 64, "topP": 0.95, "maxOutputTokens": 8192, "stopSequences": [] }, "safetySettings": [ { "category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE" }, { "category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE" }, { "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_MEDIUM_AND_ABOVE" }, { "category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE" } ] }); final response = await http.post( Uri.parse( // 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent?key=${AK.geminiApi}'), // 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=${AK.geminiApi}'), 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro:generateContent?key=${AK.geminiApi}'), headers: {'Content-Type': 'application/json'}, body: requestBody, ); if (response.statusCode == 200) { var responseData = jsonDecode(response.body); // Process the responseData as needed var result = responseData['candidates'][0]['content']['parts'][0]['text']; RegExp regex = RegExp(r"```json([^`]*)```"); String? jsonString = regex.firstMatch(responseData.toString())?.group(1)?.trim(); if (jsonString != null) { // Convert the JSON object to a String jsonString = jsonEncode(json.decode(jsonString)); if (idType == 'car_back') { responseIdCardDriverEgyptBack = jsonDecode(jsonString); } else if (idType == 'car_front') { responseIdCardDriverEgyptFront = jsonDecode(jsonString); } else if (idType == 'id_front') { responseIdEgyptFront = jsonDecode(jsonString); } else if (idType == 'id_back') { responseIdEgyptBack = jsonDecode(jsonString); } else if (idType == 'driver_license') { responseIdEgyptDriverLicense = jsonDecode(jsonString); } update(); } else { Get.snackbar('Error', "JSON string not found", backgroundColor: AppColor.redColor); } // Rest of your code... } else {} } }