import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:drift/drift.dart'; import '../../database/database.dart'; import '../../core/theme/map_style.dart'; import '../../services/location_service.dart'; class MapScreen extends ConsumerStatefulWidget { final int? rideId; const MapScreen({super.key, this.rideId}); @override ConsumerState createState() => _MapScreenState(); } class _MapScreenState extends ConsumerState { GoogleMapController? _mapController; MapType _currentMapType = MapType.normal; bool _isLoadingHistory = true; final Set _polylines = {}; final Set _markers = {}; LatLng? _initialCameraPosition; @override void initState() { super.initState(); if (widget.rideId != null) { _loadRideHistory(); } else { _isLoadingHistory = false; } } Future _loadRideHistory() async { final db = ref.read(databaseProvider); // Fetch telemetry for route final telemetry = await (db.select(db.telemetrySamples) ..where((t) => t.rideId.equals(widget.rideId!)) ..orderBy([(t) => OrderingTerm(expression: t.timestamp)]) ).get(); // Fetch events for markers final events = await (db.select(db.rideEvents) ..where((e) => e.rideId.equals(widget.rideId!)) ).get(); if (telemetry.isNotEmpty) { final List points = telemetry .where((t) => t.latitude != null && t.longitude != null) .map((t) => LatLng(t.latitude!, t.longitude!)) .toList(); if (points.isNotEmpty) { _initialCameraPosition = points.first; _polylines.add( Polyline( polylineId: const PolylineId('route'), points: points, color: Colors.cyanAccent, width: 5, ) ); } } for (final event in events) { if (event.latitude != null && event.longitude != null) { BitmapDescriptor icon = BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed); if (event.eventType == 'Extreme Lean') icon = BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueOrange); if (event.eventType == 'Hard Acceleration') icon = BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen); if (event.eventType == 'High Speed') icon = BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet); _markers.add( Marker( markerId: MarkerId(event.id.toString()), position: LatLng(event.latitude!, event.longitude!), icon: icon, infoWindow: InfoWindow( title: event.eventType, snippet: 'Value: ${event.value.toStringAsFixed(2)}', ), ) ); } } setState(() { _isLoadingHistory = false; }); // Adjust camera to fit route if map is ready _fitRoute(); } void _fitRoute() { if (_mapController == null || _polylines.isEmpty) return; final points = _polylines.first.points; if (points.isEmpty) return; double minLat = points.first.latitude; double maxLat = points.first.latitude; double minLng = points.first.longitude; double maxLng = points.first.longitude; for (final p in points) { if (p.latitude < minLat) minLat = p.latitude; if (p.latitude > maxLat) maxLat = p.latitude; if (p.longitude < minLng) minLng = p.longitude; if (p.longitude > maxLng) maxLng = p.longitude; } _mapController!.animateCamera( CameraUpdate.newLatLngBounds( LatLngBounds( southwest: LatLng(minLat, minLng), northeast: LatLng(maxLat, maxLng), ), 50.0, // padding ) ); } @override Widget build(BuildContext context) { if (_isLoadingHistory) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } Widget mapContent; if (widget.rideId != null) { // Historical Ride View mapContent = GoogleMap( initialCameraPosition: CameraPosition( target: _initialCameraPosition ?? const LatLng(0, 0), zoom: 15.0, ), mapType: _currentMapType, polylines: _polylines, markers: _markers, myLocationEnabled: false, onMapCreated: (controller) { _mapController = controller; _fitRoute(); }, ); } else { // Live Tracking View final locationAsync = ref.watch(locationStreamProvider); mapContent = locationAsync.when( data: (position) { final currentLatLng = LatLng(position.latitude, position.longitude); if (_mapController != null) { _mapController!.animateCamera( CameraUpdate.newCameraPosition( CameraPosition( target: currentLatLng, zoom: 17.0, bearing: position.heading, ), ), ); } return GoogleMap( initialCameraPosition: CameraPosition( target: currentLatLng, zoom: 17.0, ), mapType: _currentMapType, myLocationEnabled: true, myLocationButtonEnabled: true, compassEnabled: true, onMapCreated: (controller) { _mapController = controller; _mapController?.setMapStyle(darkMapStyle); }, ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (error, stack) => Center(child: Text('Error: $error')), ); } return Scaffold( appBar: AppBar( title: Text(widget.rideId != null ? 'Ride ${widget.rideId} Map' : 'Map'), actions: [ IconButton( icon: Icon( _currentMapType == MapType.normal ? Icons.satellite : Icons.map, ), onPressed: () { setState(() { _currentMapType = _currentMapType == MapType.normal ? MapType.satellite : MapType.normal; }); }, ), ], ), body: mapContent, ); } }