import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; import '../models/econtrol_model.dart'; class GasStationCard extends StatelessWidget { final EControlModel station; final int index; final double originLatitude; final double originLongitude; const GasStationCard({ super.key, required this.station, required this.index, required this.originLatitude, required this.originLongitude, }); Color _getPriceColor(double? price) { if (price == null) return Colors.grey; if (price < 1.50) return Colors.green; if (price < 1.70) return Colors.orange; return Colors.red; } String _formatDistance(double? distance) { if (distance == null) return 'N/A'; if (distance < 1) { return '${(distance * 1000).toStringAsFixed(0)} m'; } else { return '${distance.toStringAsFixed(2)} km'; } } Future _openInGoogleMaps(BuildContext context) async { final location = station.location; final destination = location?.latitude != null && location?.longitude != null ? '${location!.latitude},${location.longitude}' : [ station.name, location?.address, location?.postalCode, location?.city, ] .whereType() .where((value) => value.trim().isNotEmpty) .join(', '); if (destination.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Für diese Tankstelle ist kein Standort verfügbar.'), ), ); return; } final origin = '$originLatitude,$originLongitude'; final mapsUri = Uri.https('www.google.com', '/maps/dir/', { 'api': '1', 'origin': origin, 'destination': destination, 'travelmode': 'driving', }); final didLaunch = await launchUrl( mapsUri, mode: LaunchMode.platformDefault, webOnlyWindowName: '_blank', ); if (!didLaunch && context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Google Maps konnte nicht geöffnet werden.'), ), ); } } // Hilfsmethode zur Erstellung eines einzelnen Preis-Badges Widget _buildPriceBadge(Prices? priceInfo) { if (priceInfo == null || priceInfo.amount == null) { return const SizedBox.shrink(); } final double price = priceInfo.amount!; final String label = priceInfo.label ?? priceInfo.fuelType ?? ''; final Color badgeColor = _getPriceColor(price); return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: badgeColor.withAlpha(35), borderRadius: BorderRadius.circular(12), border: Border.all(color: badgeColor, width: 1.5), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.local_gas_station, color: badgeColor, size: 22), const SizedBox(width: 6), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( '€ ${price.toStringAsFixed(3)}', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: badgeColor, ), ), if (label.isNotEmpty) Text( label, style: TextStyle( fontSize: 10, color: Colors.grey[700], fontWeight: FontWeight.w500, ), ), ], ), ], ), ); } @override Widget build(BuildContext context) { // Suchen nach Diesel und Super/Benzin im Prices-Array final dieselPrice = station.prices?.firstWhere( (p) => p.fuelType == 'DIE' || (p.label?.toLowerCase().contains('diesel') ?? false), orElse: () => station.prices?.isNotEmpty == true ? station.prices!.first : Prices(), ); final supPrice = station.prices?.firstWhere( (p) => p.fuelType == 'SUP' || (p.label?.toLowerCase().contains('benzin') ?? false) || (p.label?.toLowerCase().contains('super') ?? false), orElse: () => Prices(), ); return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), elevation: 4, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), clipBehavior: Clip.antiAlias, child: InkWell( onTap: () => _openInGoogleMaps(context), child: Ink( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Colors.white, Colors.grey[50]!], ), ), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Row Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: Colors.blueGrey[700], borderRadius: BorderRadius.circular(20), ), child: Text( '#${index + 1}', style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: station.open == true ? Colors.green[400] : Colors.red[400], borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( station.open == true ? Icons.check_circle : Icons.cancel, color: Colors.white, size: 16, ), const SizedBox(width: 4), Text( station.open == true ? 'Geöffnet' : 'Geschlossen', style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), ], ), ), ], ), const SizedBox(height: 12), // Station Name Text( station.name ?? 'Unbekannte Tankstelle', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 8), // Address Row( children: [ Icon( Icons.location_on, size: 16, color: Colors.blueGrey[600], ), const SizedBox(width: 4), Expanded( child: Text( '${station.location?.address ?? ''}, ' '${station.location?.postalCode ?? ''} ' '${station.location?.city ?? ''}', style: TextStyle(fontSize: 13, color: Colors.grey[700]), maxLines: 2, overflow: TextOverflow.ellipsis, ), ), ], ), const SizedBox(height: 12), // Prices & Distance Row Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Diesel & Benzin Preise nebeneinander Expanded( child: Wrap( spacing: 8, runSpacing: 8, children: [ if (dieselPrice?.amount != null) _buildPriceBadge(dieselPrice), if (supPrice?.amount != null) _buildPriceBadge(supPrice), ], ), ), // Distance Badge Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), decoration: BoxDecoration( color: Colors.blue[50], borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.navigation, color: Colors.blue[700], size: 18, ), const SizedBox(width: 6), Text( _formatDistance(station.distance), style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.blue[700], ), ), ], ), ), ], ), ], ), ), ), ), ); } }