// transit_driver_controller.dart — تحكم وضع الباص (جهة السائق) import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; import 'package:intaleq_maps/intaleq_maps.dart' show LatLng; import '../../views/widgets/error_snakbar.dart'; import '../functions/location_controller.dart'; import 'transit_driver_models.dart'; import 'transit_driver_service.dart'; class TransitDriverController extends GetxController { bool isCheckingBusDriver = true; bool isBusDriver = false; int? driverTransitId; String orgName = ''; bool isLoadingTrips = false; List todayTrips = []; TransitDriverTrip? activeTrip; bool isActionInProgress = false; // ── حالة التفعيل ────────────────────────────────────────────── bool isActivating = false; String activationError = ''; // ── جيوفينس المحطات — آخر محطة تم الإعلان عنها ────────────── int _lastAnnouncedStopSeq = 0; @override void onInit() { super.onInit(); checkBusDriverStatus(); } Future checkBusDriverStatus() async { isCheckingBusDriver = true; update(); final res = await TransitDriverService.checkIsBusDriver(); if (res.success && res.data != null) { isBusDriver = res.data!['is_bus_driver'] == true; if (isBusDriver) { driverTransitId = int.tryParse(res.data!['driver_transit_id'].toString()); orgName = res.data!['org_name']?.toString() ?? ''; await fetchTodayTrips(); } } isCheckingBusDriver = false; update(); } /// تفعيل الحساب بتوكن الدعوة Future activateWithToken(String token) async { if (token.trim().isEmpty) return; isActivating = true; activationError = ''; update(); final res = await TransitDriverService.activateByInviteToken(token.trim()); if (res.success) { // أعد فحص الحالة بعد التفعيل await checkBusDriverStatus(); } else { activationError = res.message; } isActivating = false; update(); } Future fetchTodayTrips() async { isLoadingTrips = true; update(); final res = await TransitDriverService.getTodayTrips(); if (res.success) { todayTrips = res.data ?? []; final started = todayTrips.where((t) => t.status == 'started'); activeTrip = started.isNotEmpty ? started.first : null; // إن كانت هناك رحلة قيد التشغيل بالفعل (إعادة فتح التطبيق) if (activeTrip != null && Get.isRegistered()) { Get.find().setBusMode( enabled: true, tripId: activeTrip!.id, routeId: activeTrip!.routeId, ); } } isLoadingTrips = false; update(); } Future startTrip(TransitDriverTrip trip) async { if (isActionInProgress) return false; isActionInProgress = true; update(); LatLng pos = const LatLng(0, 0); if (Get.isRegistered()) { pos = Get.find().myLocation; } final res = await TransitDriverService.startTrip( tripId: trip.id, lat: pos.latitude, lng: pos.longitude, ); if (res.success) { _lastAnnouncedStopSeq = 0; if (Get.isRegistered()) { Get.find().setBusMode( enabled: true, tripId: trip.id, routeId: trip.routeId, ); } await fetchTodayTrips(); } else { mySnackbarError(res.message); } isActionInProgress = false; update(); return res.success; } Future endTrip(TransitDriverTrip trip) async { if (isActionInProgress) return false; isActionInProgress = true; update(); final res = await TransitDriverService.endTrip(tripId: trip.id); if (res.success) { _lastAnnouncedStopSeq = 0; if (Get.isRegistered()) { Get.find().setBusMode(enabled: false); } await fetchTodayTrips(); } else { mySnackbarError(res.message); } isActionInProgress = false; update(); return res.success; } Future reportDelay(TransitDriverTrip trip, int minutes, {String? reason}) async { final res = await TransitDriverService.reportDelay( tripId: trip.id, delayMinutes: minutes, reason: reason, ); if (!res.success) mySnackbarError(res.message); return res.success; } Future boardPassenger(int stopId, String passengerId) async { final res = await TransitDriverService.boardPassenger(stopId, passengerId); return res.success; } Future>> getStopPassengers(int stopId) async { final res = await TransitDriverService.getStopPassengers(stopId); if (res.success && res.data != null) { return res.data!; } return []; } // ── كشف الوصول للمحطات (جيوفينس) ──────────────────────────── // تُستدعى من LocationController عند كل تحديث للموقع أثناء وضع الباص void onLocationUpdate(LatLng pos) { if (activeTrip == null || activeTrip!.stops.isEmpty) return; final stops = activeTrip!.stops; int? nextSeq; // الاتجاه للمحطة التالية بعد آخر معلنة for (final stop in stops) { if (stop.sequence <= _lastAnnouncedStopSeq) continue; final dist = Geolocator.distanceBetween( pos.latitude, pos.longitude, stop.latitude, stop.longitude, ); if (dist <= stop.geofenceRadius) { nextSeq = stop.sequence; break; } } if (nextSeq != null && nextSeq > _lastAnnouncedStopSeq) { _lastAnnouncedStopSeq = nextSeq; // أرسل التسلسل الحالي عبر السوكيت if (Get.isRegistered()) { final lc = Get.find(); lc.emitBusLocationToSocket(pos, 0, 0, currentStopSeq: nextSeq); } update(); } } // عودة بالمحطة الحالية للعرض TransitStop? get currentStop { if (activeTrip == null || _lastAnnouncedStopSeq == 0) return null; try { return activeTrip!.stops .firstWhere((s) => s.sequence == _lastAnnouncedStopSeq); } catch (_) { return null; } } }