import 'package:equatable/equatable.dart'; import 'package:intaleq_maps/intaleq_maps.dart'; /// استجابة مسار من انطلق — مع polyline مشفر وإطار خريطة. class RouteModel extends Equatable { final int distanceMeters; final int durationSeconds; final String? polyline; final String? routeName; final String? startName; final String? endName; final List? tags; final List? bbox; final double? trafficFactor; const RouteModel({ required this.distanceMeters, required this.durationSeconds, this.polyline, this.routeName, this.startName, this.endName, this.tags, this.bbox, this.trafficFactor, }); /// استجابة مسار انطلق الحقيقية (تُمرر عبر الباك إند كما هي). factory RouteModel.fromJson(Map j) { final dist = (j['distance'] ?? 0) as num; final dur = (j['duration'] ?? 0) as num; return RouteModel( distanceMeters: dist.toInt(), durationSeconds: dur.toInt(), polyline: j['points'] as String?, routeName: j['routeName'] as String?, startName: j['startName'] as String?, endName: j['endName'] as String?, tags: (j['tags'] as List?)?.cast(), bbox: (j['bbox'] as List?)?.map((e) => (e as num).toDouble()).toList(), trafficFactor: (j['trafficFactor'] as num?)?.toDouble(), ); } String get distanceText { if (distanceMeters < 1000) return '$distanceMeters m'; return '${(distanceMeters / 1000).toStringAsFixed(1)} km'; } String get durationText { final min = durationSeconds ~/ 60; if (min < 60) return '$min min'; final h = min ~/ 60; final rem = min % 60; return '$h h ${rem > 0 ? '$rem min' : ''}'; } /// تحويل bbox إلى LatLngBounds لضبط الكاميرا مع حماية للمواقع القريبة على iOS. LatLngBounds? getLatLngBounds() { if (bbox == null || bbox!.length < 4) return null; var minLat = bbox![1]; var minLng = bbox![0]; var maxLat = bbox![3]; var maxLng = bbox![2]; // إذا كانت المسافة بين النقاط قريبة جداً (أقل من 0.002 درجة)، نضمن توسعاً أمنياً أدنى لمنع عطل وقفل كاميرا MapLibre على iOS if ((maxLat - minLat).abs() < 0.002) { minLat -= 0.001; maxLat += 0.001; } if ((maxLng - minLng).abs() < 0.002) { minLng -= 0.001; maxLng += 0.001; } return LatLngBounds( southwest: LatLng(minLat, minLng), northeast: LatLng(maxLat, maxLng), ); } /// فك الـ polyline عبر PolylineUtils من الباكيج. List decodePolyline() { if (polyline == null || polyline!.isEmpty) return []; return PolylineUtils.decode(polyline!); } /// هل المسار مباشر (لا أضلاع)? bool get isStraightLine => tags?.contains('straight-line') ?? false; @override List get props => [ distanceMeters, durationSeconds, polyline, routeName, startName, endName, tags, bbox, trafficFactor, ]; }