import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; // import 'package:google_maps_flutter/google_maps_flutter.dart'; // import 'package:flutter_map/flutter_map.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; // import 'package:latlong2/latlong.dart' // as latlng; // هذا مهم جداً للتعامل مع إحداثيات OSM import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/controller/home/captin/map_driver_controller.dart'; import 'dart:async'; import '../../../constant/links.dart'; import '../../../constant/style.dart'; import '../../../constant/table_names.dart'; import '../../../main.dart'; import '../../../print.dart'; import '../../../views/home/my_wallet/walet_captain.dart'; import '../../../views/widgets/elevated_btn.dart'; import '../../firebase/firbase_messge.dart'; import '../../functions/crud.dart'; import '../../functions/location_background_controller.dart'; import '../../functions/location_controller.dart'; import '../payment/captain_wallet_controller.dart'; class HomeCaptainController extends GetxController { bool isActive = false; DateTime? activeStartTime; Duration activeDuration = Duration.zero; Timer? activeTimer; Map data = {}; BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker; bool isLoading = true; late double kazan = 0; double latePrice = 0; double heavyPrice = 0; double comfortPrice = 0, speedPrice = 0, deliveryPrice = 0, mashwariPrice = 0, familyPrice = 0, fuelPrice = 0; double naturePrice = 0; bool isCallOn = false; String totalMoneyToday = '0'; double? rating = 5; String rideId = '0'; String countRideToday = '0'; String totalMoneyInSEFER = '0'; String totalDurationToday = '0'; Timer? timer; late LatLng myLocation = const LatLng(33.5138, 36.2765); String totalPoints = '0'; String countRefuse = '0'; bool mapType = false; bool mapTrafficON = false; double widthMapTypeAndTraffic = 50; // Inject the LocationController class // final locationController = Get.put(LocationController()); // الكود الصحيح final locationController = Get.find(); // final locationBackController = Get.put(LocationBackgroundController()); String formatDuration(Duration duration) { String twoDigits(int n) => n.toString().padLeft(2, "0"); String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); return "${duration.inHours}:$twoDigitMinutes:$twoDigitSeconds"; } void goToWalletFromConnect() { Get.back(); Get.back(); Get.to(() => WalletCaptainRefactored()); } void changeRideId() { rideId = 'rideId'; update(); } void addCustomCarIcon() { ImageConfiguration config = ImageConfiguration( size: const Size(30, 35), devicePixelRatio: Get.pixelRatio); BitmapDescriptor.asset( config, 'assets/images/car.png', // mipmaps: false, ).then((value) { carIcon = value; update(); }); } String stringActiveDuration = ''; void onButtonSelected() { // totalPoints = Get.find().totalPoints; isActive = !isActive; if (isActive) { if (double.parse(totalPoints) > -30000) { locationController.startLocationUpdates(); HapticFeedback.heavyImpact(); // locationBackController.startBackLocation(); activeStartTime = DateTime.now(); activeTimer = Timer.periodic(const Duration(seconds: 1), (timer) { activeDuration = DateTime.now().difference(activeStartTime!); stringActiveDuration = formatDuration(activeDuration); update(); }); } else { locationController.stopLocationUpdates(); activeStartTime = null; activeTimer?.cancel(); savePeriod(activeDuration); activeDuration = Duration.zero; update(); } } else { locationController.stopLocationUpdates(); activeStartTime = null; activeTimer?.cancel(); savePeriod(activeDuration); activeDuration = Duration.zero; update(); } // } } void getRefusedOrderByCaptain() async { DateTime today = DateTime.now(); int todayDay = today.day; String driverId = box.read(BoxName.driverID).toString(); String customQuery = ''' SELECT COUNT(*) AS count FROM ${TableName.driverOrdersRefuse} WHERE driver_id = '$driverId' AND created_at LIKE '%$todayDay%' '''; try { List> results = await sql.getCustomQuery(customQuery); countRefuse = results[0]['count'].toString(); update(); if (int.parse(countRefuse) > 3 || double.parse(totalPoints) <= -3000) { locationController.stopLocationUpdates(); activeStartTime = null; activeTimer?.cancel(); savePeriod(activeDuration); activeDuration = Duration.zero; update(); Get.defaultDialog( // backgroundColor: CupertinoColors.destructiveRed, barrierDismissible: false, title: 'You Are Stopped For this Day !'.tr, content: Text( 'You Refused 3 Rides this Day that is the reason \nSee you Tomorrow!' .tr, style: AppStyle.title, ), confirm: MyElevatedButton( title: 'Ok , See you Tomorrow'.tr, onPressed: () { Get.back(); Get.back(); })); } } catch (e) {} } void changeMapType() { mapType = !mapType; // heightButtomSheetShown = isButtomSheetShown == true ? 240 : 0; update(); } void changeMapTraffic() { mapTrafficON = !mapTrafficON; update(); } // late GoogleMapController mapHomeCaptainController; GoogleMapController? mapHomeCaptainController; // final locationController = Get.find(); // --- FIX 2: Smart Map Creation --- void onMapCreated(GoogleMapController controller) { mapHomeCaptainController = controller; // Check actual location before moving camera var currentLoc = locationController.myLocation; if (currentLoc.latitude != 0 && currentLoc.longitude != 0) { controller.animateCamera( CameraUpdate.newLatLng(currentLoc), ); } else { // Optional: Move to default city view instead of ocean controller.animateCamera( CameraUpdate.newLatLngZoom(myLocation, 10), ); } } void savePeriod(Duration period) { final periods = box.read>(BoxName.periods) ?? []; periods.add(period.inSeconds); box.write(BoxName.periods, periods); } Duration calculateTotalDuration() { final periods = box.read>(BoxName.periods) ?? []; Duration totalDuration = Duration.zero; for (dynamic periodInSeconds in periods) { final periodDuration = Duration(seconds: periodInSeconds); totalDuration += periodDuration; } return totalDuration; } void startPeriodicExecution() { Timer.periodic(const Duration(seconds: 30), (timer) async { await getCaptainDurationOnToday(); }); } void stopTimer() { timer?.cancel(); } getlocation() async { isLoading = true; update(); // This ensures we try to get a fix, but map doesn't crash if it fails await Get.find().getLocation(); var loc = Get.find().myLocation; if (loc.latitude != 0) { myLocation = loc; } isLoading = false; update(); } Map walletDriverPointsDate = {}; Future getCaptainWalletFromBuyPoints() async { // isLoading = true; update(); var res = await CRUD().getWallet( link: AppLink.getDriverPaymentPoints, payload: {'driverID': box.read(BoxName.driverID).toString()}, ); isLoading = false; // update(); if (res != 'failure') { walletDriverPointsDate = jsonDecode(res); double totalPointsDouble = double.parse( walletDriverPointsDate['message'][0]['total_amount'].toString()); totalPoints = totalPointsDouble.toStringAsFixed(0); update(); } else { totalPoints = '0'; } } @override void onInit() async { // await locationBackController.requestLocationPermission(); Get.put(FirebaseMessagesController()); addToken(); await getlocation(); onButtonSelected(); getDriverRate(); addCustomCarIcon(); getKazanPercent(); getPaymentToday(); getCountRideToday(); getAllPayment(); startPeriodicExecution(); getCaptainWalletFromBuyPoints(); // onMapCreated(mapHomeCaptainController!); // totalPoints = Get.find().totalPoints.toString(); getRefusedOrderByCaptain(); box.write(BoxName.statusDriverLocation, 'off'); locationController.addListener(() { // Only animate if active, map is ready, AND location is valid (not 0,0) if (isActive && mapHomeCaptainController != null) { var loc = locationController.myLocation; if (loc.latitude != 0 && loc.longitude != 0) { mapHomeCaptainController!.animateCamera( CameraUpdate.newCameraPosition( CameraPosition( target: loc, zoom: 17.5, tilt: 50.0, bearing: locationController.heading, ), ), ); } } }); // LocationController().getLocation(); super.onInit(); } addToken() async { String? fingerPrint = await storage.read(key: BoxName.fingerPrint); final payload = { 'token': (box.read(BoxName.tokenDriver)), 'captain_id': (box.read(BoxName.driverID)).toString(), 'fingerPrint': (fingerPrint).toString() }; // Log.print('payload: ${payload}'); CRUD().post(link: AppLink.addTokensDriver, payload: payload); } getPaymentToday() async { var res = await CRUD().getWallet( link: AppLink.getDriverPaymentToday, payload: {'driverID': box.read(BoxName.driverID).toString()}); if (res != 'failure') { data = jsonDecode(res); totalMoneyToday = data['message'][0]['todayAmount'].toString(); update(); } else {} } getKazanPercent() async { var res = await CRUD().get( link: AppLink.getKazanPercent, payload: {'country': box.read(BoxName.countryCode).toString()}, ); if (res != 'failure') { var json = jsonDecode(res); kazan = double.parse(json['message'][0]['kazan']); naturePrice = double.parse(json['message'][0]['naturePrice']); heavyPrice = double.parse(json['message'][0]['heavyPrice']); latePrice = double.parse(json['message'][0]['latePrice']); comfortPrice = double.parse(json['message'][0]['comfortPrice']); speedPrice = double.parse(json['message'][0]['speedPrice']); deliveryPrice = double.parse(json['message'][0]['deliveryPrice']); mashwariPrice = double.parse(json['message'][0]['freePrice']); familyPrice = double.parse(json['message'][0]['familyPrice']); fuelPrice = double.parse(json['message'][0]['fuelPrice']); } update(); } double mpg = 0; calculateConsumptionFuel() { mpg = fuelPrice / 12; //todo in register car add mpg in box } getCountRideToday() async { var res = await CRUD().get( link: AppLink.getCountRide, payload: {'driver_id': box.read(BoxName.driverID).toString()}); data = jsonDecode(res); countRideToday = data['message'][0]['count'].toString(); update(); } getDriverRate() async { var res = await CRUD().get( link: AppLink.getDriverRate, payload: {'driver_id': box.read(BoxName.driverID).toString()}); if (res != 'failure') { var decod = jsonDecode(res); if (decod['message'][0]['rating'] != null) { rating = double.parse(decod['message'][0]['rating'].toString()); } else { rating = 5.0; // Set a default value (e.g., 5.0 for full rating) } } else { rating = 5; } } getAllPayment() async { var res = await CRUD().getWallet( link: AppLink.getAllPaymentFromRide, payload: {'driverID': box.read(BoxName.driverID).toString()}); if (res == 'failure') { totalMoneyInSEFER = '0'; } else { data = jsonDecode(res); totalMoneyInSEFER = data['message'][0]['total_amount']; } update(); } void changeToAppliedRide(String status) { box.write(BoxName.rideStatus, status); Log.print('rideStatus from homcaptain : ${box.read(BoxName.rideStatus)}'); update(); } Future getCaptainDurationOnToday() async { try { var res = await CRUD().get( link: AppLink.getTotalDriverDurationToday, payload: {'driver_id': box.read(BoxName.driverID).toString()}, ); if (res == null || res == 'failure') { totalDurationToday = '0'; update(); return; } var data = jsonDecode(res); totalDurationToday = data['message']?[0]?['total_duration'] ?? '0'; } catch (e) { print('Error in getCaptainDurationOnToday: $e'); totalDurationToday = '0'; } update(); } @override void dispose() { activeTimer?.cancel(); stopTimer(); mapHomeCaptainController?.dispose(); // Dispose controller super.dispose(); } }