import 'dart:async'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:location/location.dart'; import '../../constant/box_name.dart'; import '../../constant/links.dart'; import '../../main.dart'; import '../../print.dart'; import '../home/captin/home_captain_controller.dart'; import '../home/payment/captain_wallet_controller.dart'; import 'crud.dart'; import 'encrypt_decrypt.dart'; class LocationController extends GetxController { LocationData? _currentLocation; late Location location = Location(); bool isLoading = false; late double heading = 0; late double accuracy = 0; late double previousTime = 0; late double latitude; late double totalDistance = 0; late double longitude; late DateTime time; late double speed = 0; late double speedAccuracy = 0; late double headingAccuracy = 0; bool isActive = false; late LatLng myLocation = LatLng(0, 0); // Default value String totalPoints = '0'; LocationData? get currentLocation => _currentLocation; Timer? _locationTimer; @override void onInit() async { super.onInit(); location = Location(); // Initialize the location object await location.changeSettings( accuracy: LocationAccuracy.high, interval: 5000, // 5 seconds distanceFilter: 0); await getLocation(); // Fetch the location immediately await startLocationUpdates(); // Start periodic location updates totalPoints = Get.put(CaptainWalletController()).totalPoints.toString(); isActive = Get.put(HomeCaptainController()).isActive; } // String getLocationArea(double latitude, double longitude) { // if (latitude >= 29.918901 && // latitude <= 30.198857 && // longitude >= 31.215009 && // longitude <= 31.532186) { // return 'Cairo'; // } else if (latitude >= 29.904975 && // latitude <= 30.143372 && // longitude >= 30.787030 && // longitude <= 31.215009) { // return 'Giza'; // } else if (latitude >= 30.396286 && // latitude <= 31.654458 && // longitude >= 29.041139 && // longitude <= 32.626259) { // return 'Alexandria'; // } else { // return 'Cairo'; // } // } String getLocationArea(double latitude, double longitude) { final locations = box.read(BoxName.locationName) ?? []; for (final location in locations) { final locationData = location as Map; // Debugging: Print location data // Convert string values to double final minLatitude = double.tryParse(locationData['min_latitude'].toString()) ?? 0.0; final maxLatitude = double.tryParse(locationData['max_latitude'].toString()) ?? 0.0; final minLongitude = double.tryParse(locationData['min_longitude'].toString()) ?? 0.0; final maxLongitude = double.tryParse(locationData['max_longitude'].toString()) ?? 0.0; // Debugging: Print converted values // 'Converted Values: minLatitude=$minLatitude, maxLatitude=$maxLatitude, minLongitude=$minLongitude, maxLongitude=$maxLongitude'); if (latitude >= minLatitude && latitude <= maxLatitude && longitude >= minLongitude && longitude <= maxLongitude) { box.write(BoxName.serverChosen, EncryptionHelper.instance.decryptData(locationData['server_link'])); // 'locationData----server_link: ${locationData['server_link']}'); return locationData['name']; } } // Default case box.write(BoxName.serverChosen, AppLink.seferCairoServer); return 'Cairo'; } int _insertCounter = 0; Future startLocationUpdates() async { if (box.read(BoxName.driverID) != null) { if (location == null) { location = Location(); // Ensure location is initialized } _locationTimer = Timer.periodic(const Duration(seconds: 5), (timer) async { try { totalPoints = Get.find().totalPoints.toString(); isActive = Get.find().isActive; if (isActive && double.parse(totalPoints) > -300) { await getLocation(); if (myLocation == null) return; String area = getLocationArea(myLocation.latitude, myLocation.longitude); final payload = { 'driver_id': box.read(BoxName.driverID).toString(), 'latitude': myLocation.latitude.toString(), 'longitude': myLocation.longitude.toString(), 'heading': heading.toString(), 'speed': (speed * 3.6).toStringAsFixed(1), 'distance': totalDistance == 0 && (speed * 3.6) < 5 ? '0.0' : totalDistance < 7 ? totalDistance.toStringAsFixed(3) : totalDistance.toStringAsFixed(1), 'status': box.read(BoxName.statusDriverLocation) ?? 'off', }; // 🔁 كل 5 ثواني - تحديث الموقع await CRUD().post( link: box.read(BoxName.serverChosen) + '/ride/location/update.php', payload: payload, ); // 📍 كل 60 ثانية - إدخال جديد _insertCounter++; if (_insertCounter >= 12) { _insertCounter = 0; await CRUD().post( link: box.read(BoxName.serverChosen) + '/ride/location/add.php', payload: payload, ); } // 🔄 تحديث الكاميرا Get.find() .mapHomeCaptainController ?.animateCamera( CameraUpdate.newLatLng( LatLng( Get.find().myLocation.latitude, Get.find().myLocation.longitude, ), ), ); } } catch (e) { print('Location update error: $e'); } }); } } void stopLocationUpdates() { _locationTimer?.cancel(); } Future getLocation() async { if (location == null) { location = Location(); // تأكد من أن `Location` مهيأ } bool serviceEnabled; PermissionStatus permissionGranted; serviceEnabled = await location.serviceEnabled(); if (!serviceEnabled) { serviceEnabled = await location.requestService(); if (!serviceEnabled) { return; } } permissionGranted = await location.hasPermission(); if (permissionGranted == PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != PermissionStatus.granted) { return; } } /// **تجنب استدعاء `getLocation()` مباشرة على الـ Main Thread** Future.delayed(Duration(milliseconds: 500), () async { try { LocationData _locationData = await location.getLocation(); if (_locationData.latitude != null && _locationData.longitude != null) { myLocation = LatLng(_locationData.latitude!, _locationData.longitude!); } else { myLocation = LatLng(0, 0); // Default value } speed = _locationData.speed ?? 0; heading = _locationData.heading ?? 0; if (Get.find().rideId == 'rideId') { if (previousTime > 0) { double distance = calculateDistanceInKmPerHour( previousTime, _locationData.time, speed); totalDistance += distance; } previousTime = _locationData.time ?? 0; } update(); } catch (e) { print("Error getting location: $e"); } }); } // Future getLocation() async { // if (location == null) { // location = Location(); // Ensure location is initialized // } // bool serviceEnabled; // PermissionStatus permissionGranted; // serviceEnabled = await location.serviceEnabled(); // if (!serviceEnabled) { // serviceEnabled = await location.requestService(); // if (!serviceEnabled) { // return; // } // } // permissionGranted = await location.hasPermission(); // if (permissionGranted == PermissionStatus.denied) { // permissionGranted = await location.requestPermission(); // if (permissionGranted != PermissionStatus.granted) { // return; // } // } // LocationData _locationData = await location.getLocation(); // if (_locationData.latitude != null && _locationData.longitude != null) { // myLocation = LatLng(_locationData.latitude!, _locationData.longitude!); // } else { // myLocation = LatLng(0, 0); // Default value // } // speed = _locationData.speed ?? 0; // heading = _locationData.heading ?? 0; // if (Get.find().rideId == 'rideId') { // if (previousTime > 0) { // double distance = calculateDistanceInKmPerHour( // previousTime, _locationData.time, speed); // totalDistance += distance; // } // previousTime = _locationData.time ?? 0; // } // update(); // } double calculateDistanceInKmPerHour( double? startTime, double? endTime, double speedInMetersPerSecond) { double timeDifferenceInHours = (endTime ?? 0 - startTime! ?? 0) / 1000 / 3600; double speedInKmPerHour = speedInMetersPerSecond * 3.6; double distanceInKilometers = speedInKmPerHour * timeDifferenceInHours; double distanceInMeters = distanceInKilometers * 1000; return distanceInMeters < 5 ? 0 : distanceInKilometers; } }