/// أنواع المقاطع المكتشفة تلقائياً enum SegmentType { warmup, // إحماء - أول 5-10% من المسافة بسرعة منخفضة main, // المرحلة الرئيسية cooldown, // تبريد - آخر 5-10% بسرعة متناقصة stop, // نقطة توقف - سرعة < 0.3 m/s لأكثر من 10 ثوان sprint, // تسارع - سرعة > 120% من المتوسط uphill, // صعود - ارتفاع > 3% grade downhill, // نزول - انخفاض > 3% grade } /// نموذج مقطع من المسار /// يمثل جزء من التمرين تم تقسيمه بناءً على تغيرات السرعة أو الارتفاع class WorkoutSegment { final int segmentIndex; final SegmentType type; final double distanceMeters; final int durationSeconds; final double avgSpeedMps; final double maxSpeedMps; final double elevationChange; // positive = uphill, negative = downhill final int startCoordIndex; // index in coordinates list final int endCoordIndex; WorkoutSegment({ required this.segmentIndex, required this.type, required this.distanceMeters, required this.durationSeconds, required this.avgSpeedMps, this.maxSpeedMps = 0, this.elevationChange = 0, required this.startCoordIndex, required this.endCoordIndex, }); /// Pace in min/km double get paceMinKm { if (avgSpeedMps <= 0) return 0; double kmh = avgSpeedMps * 3.6; return kmh > 0 ? 60.0 / kmh : 0; } /// Gradient percentage (for elevation segments) double get gradientPercent { if (distanceMeters <= 0) return 0; return (elevationChange / distanceMeters) * 100; } Map toMap() { return { 'segment_index': segmentIndex, 'segment_type': type.name, 'distance_meters': distanceMeters, 'duration_seconds': durationSeconds, 'avg_speed_mps': avgSpeedMps, 'max_speed_mps': maxSpeedMps, 'elevation_change': elevationChange, 'start_coord_index': startCoordIndex, 'end_coord_index': endCoordIndex, }; } factory WorkoutSegment.fromMap(Map map) { return WorkoutSegment( segmentIndex: map['segment_index'] as int, type: SegmentType.values.firstWhere( (e) => e.name == map['segment_type'], orElse: () => SegmentType.main, ), distanceMeters: (map['distance_meters'] as num).toDouble(), durationSeconds: map['duration_seconds'] as int, avgSpeedMps: (map['avg_speed_mps'] as num).toDouble(), maxSpeedMps: (map['max_speed_mps'] as num?)?.toDouble() ?? 0, elevationChange: (map['elevation_change'] as num?)?.toDouble() ?? 0, startCoordIndex: map['start_coord_index'] as int, endCoordIndex: map['end_coord_index'] as int, ); } /// Convert to API-compatible map Map toApiMap() { return { 'segment_order': segmentIndex, 'duration_seconds': durationSeconds, 'distance_meters': distanceMeters.toInt(), 'index_in_polyline': startCoordIndex, }; } }