import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../database/database.dart'; import '../../models/motorcycle_models.dart'; import 'garage_providers.dart'; class GarageScreen extends ConsumerWidget { const GarageScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final bikesAsync = ref.watch(garageMotorcyclesStreamProvider); return Scaffold( appBar: AppBar( title: const Text('My Garage', style: TextStyle(fontWeight: FontWeight.bold)), actions: [ IconButton( icon: const Icon(Icons.add_circle_outline, color: Colors.cyanAccent), tooltip: 'Add Motorcycle', onPressed: () => context.push('/garage/add'), ), ], ), body: bikesAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('Error loading garage: $err')), data: (bikes) { if (bikes.isEmpty) { return _buildEmptyState(context); } return ListView.builder( padding: const EdgeInsets.all(16.0), itemCount: bikes.length, itemBuilder: (context, index) { final bike = bikes[index]; return _buildMotorcycleCard(context, ref, bike); }, ); }, ), floatingActionButton: bikesAsync.value != null && bikesAsync.value!.isNotEmpty ? FloatingActionButton.extended( backgroundColor: Colors.cyanAccent, foregroundColor: Colors.black, icon: const Icon(Icons.two_wheeler), label: const Text('ADD MOTORCYCLE', style: TextStyle(fontWeight: FontWeight.bold)), onPressed: () => context.push('/garage/add'), ) : null, ); } Widget _buildEmptyState(BuildContext context) { return Center( child: Padding( padding: const EdgeInsets.all(32.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.two_wheeler, size: 80, color: Colors.white24), const SizedBox(height: 24), const Text( 'YOUR GARAGE IS EMPTY', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, letterSpacing: 1.5), ), const SizedBox(height: 12), const Text( 'Add your motorcycle to personalize your ride history and performance data.', textAlign: TextAlign.center, style: TextStyle(color: Colors.white70, height: 1.4), ), const SizedBox(height: 32), ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: Colors.cyanAccent, foregroundColor: Colors.black, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), icon: const Icon(Icons.add), label: const Text('ADD MOTORCYCLE', style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1.2)), onPressed: () => context.push('/garage/add'), ), ], ), ), ); } Widget _buildMotorcycleCard(BuildContext context, WidgetRef ref, GarageMotorcycle bike) { MotorcycleSpecification? spec; if (bike.specificationJson != null) { try { spec = MotorcycleSpecification.fromJson(json.decode(bike.specificationJson!)); } catch (_) {} } final displayName = bike.nickname != null && bike.nickname!.isNotEmpty ? '${bike.nickname} (${bike.year} ${bike.makeName} ${bike.modelName})' : '${bike.year} ${bike.makeName} ${bike.modelName}'; return Card( margin: const EdgeInsets.only(bottom: 16), clipBehavior: Clip.antiAlias, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: BorderSide( color: bike.isDefault ? Colors.cyanAccent : Colors.white12, width: bike.isDefault ? 2 : 1, ), ), child: InkWell( onTap: () => context.push('/garage/${bike.id}'), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white10, borderRadius: BorderRadius.circular(10), ), child: const Icon(Icons.two_wheeler, size: 36, color: Colors.cyanAccent), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( displayName, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), if (bike.isDefault) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: Colors.cyanAccent.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(4), border: Border.all(color: Colors.cyanAccent), ), child: const Text( 'CURRENT', style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: Colors.cyanAccent), ), ), ], ), const SizedBox(height: 6), Text( spec != null ? '${spec.displacementCc?.toStringAsFixed(0) ?? "—"} cc • ${spec.horsepower?.toStringAsFixed(0) ?? "—"} hp' : '${bike.year} • ${bike.makeName}', style: const TextStyle(color: Colors.white70, fontSize: 14), ), ], ), ), ], ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton.icon( icon: const Icon(Icons.directions_bike, size: 18), label: const Text('View Specs & Stats'), onPressed: () => context.push('/garage/${bike.id}'), ), if (!bike.isDefault) OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: Colors.white, side: const BorderSide(color: Colors.white30), ), onPressed: () { ref.read(garageControllerProvider).setDefaultMotorcycle(bike.id); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Set ${bike.makeName} ${bike.modelName} as current motorcycle.')), ); }, child: const Text('Set as Current'), ), ], ), ], ), ), ), ); } }