import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../providers/dashboard_providers.dart'; import '../../../widgets/status_badge.dart'; import '../../../widgets/error_view.dart'; class ReservationDetailScreen extends ConsumerWidget { final String id; const ReservationDetailScreen({super.key, required this.id}); @override Widget build(BuildContext context, WidgetRef ref) { final async = ref.watch(reservationDetailProvider(id)); return async.when( loading: () => const Scaffold(body: Center(child: CircularProgressIndicator())), error: (e, _) => Scaffold( appBar: AppBar(), body: ErrorView( message: 'Could not load reservation', onRetry: () => ref.invalidate(reservationDetailProvider(id)), ), ), data: (res) { final fmt = DateFormat('MMM d, yyyy'); final canConfirm = res.status == 'DRAFT'; final canCancel = res.status == 'DRAFT' || res.status == 'CONFIRMED'; final canCheckin = res.status == 'CONFIRMED'; final canCheckout = res.status == 'ACTIVE'; return Scaffold( appBar: AppBar( title: Text('Reservation #${id.substring(0, 8)}'), actions: [ StatusBadge(status: res.status), const SizedBox(width: 16), ], ), body: ListView( padding: const EdgeInsets.all(16), children: [ _Section( title: 'Vehicle', child: res.vehicle != null ? _InfoRow(label: 'Vehicle', value: res.vehicle!.displayName) : const Text('N/A'), ), _Section( title: 'Customer', child: res.customer != null ? Column( children: [ _InfoRow( label: 'Name', value: res.customer!.fullName), if (res.customer!.email != null) _InfoRow( label: 'Email', value: res.customer!.email!), if (res.customer!.phone != null) _InfoRow( label: 'Phone', value: res.customer!.phone!), ], ) : const Text('Walk-in customer'), ), _Section( title: 'Dates', child: Column( children: [ _InfoRow(label: 'Start', value: fmt.format(res.startDate)), _InfoRow(label: 'End', value: fmt.format(res.endDate)), _InfoRow(label: 'Duration', value: '${res.days} days'), ], ), ), _Section( title: 'Payment', child: Column( children: [ _InfoRow( label: 'Total', value: '\$${res.totalAmount.toStringAsFixed(2)}'), Row( children: [ const Text('Status: ', style: TextStyle(color: Color(0xFF6B7280))), const SizedBox(width: 4), StatusBadge(status: res.paymentStatus), ], ), ], ), ), const SizedBox(height: 16), if (canConfirm) _ActionButton( label: 'Confirm Reservation', color: const Color(0xFF0E9F6E), icon: Icons.check_circle_outline, onTap: () async { await ref .read(reservationServiceProvider) .confirmReservation(id); ref.invalidate(reservationDetailProvider(id)); }, ), if (canCheckin) _ActionButton( label: 'Check In', color: const Color(0xFF1A56DB), icon: Icons.login, onTap: () => _showMileageDialog(context, ref, 'checkin'), ), if (canCheckout) _ActionButton( label: 'Check Out', color: const Color(0xFF5521B5), icon: Icons.logout, onTap: () => _showMileageDialog(context, ref, 'checkout'), ), if (canCancel) _ActionButton( label: 'Cancel Reservation', color: const Color(0xFFE02424), icon: Icons.cancel_outlined, onTap: () => _showCancelDialog(context, ref), ), ], ), ); }, ); } void _showMileageDialog( BuildContext context, WidgetRef ref, String type) { final ctrl = TextEditingController(); showDialog( context: context, builder: (_) => AlertDialog( title: Text(type == 'checkin' ? 'Check In' : 'Check Out'), content: TextField( controller: ctrl, keyboardType: TextInputType.number, decoration: const InputDecoration( labelText: 'Current mileage (km)', ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Cancel')), ElevatedButton( onPressed: () async { final mileage = int.tryParse(ctrl.text); if (mileage == null) return; Navigator.pop(context); try { if (type == 'checkin') { await ref .read(reservationServiceProvider) .checkin(id, mileage); } else { await ref .read(reservationServiceProvider) .checkout(id, mileage); } ref.invalidate(reservationDetailProvider(id)); } catch (_) {} }, child: const Text('Confirm'), ), ], ), ); } void _showCancelDialog(BuildContext context, WidgetRef ref) { final ctrl = TextEditingController(); showDialog( context: context, builder: (_) => AlertDialog( title: const Text('Cancel Reservation'), content: TextField( controller: ctrl, decoration: const InputDecoration(labelText: 'Reason'), maxLines: 3, ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Back')), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFE02424)), onPressed: () async { Navigator.pop(context); await ref .read(reservationServiceProvider) .cancelReservation(id, ctrl.text); ref.invalidate(reservationDetailProvider(id)); }, child: const Text('Cancel Reservation'), ), ], ), ); } } class _Section extends StatelessWidget { final String title; final Widget child; const _Section({required this.title, required this.child}); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.only(bottom: 12), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: const TextStyle( fontWeight: FontWeight.bold, color: Color(0xFF6B7280), fontSize: 12)), const SizedBox(height: 10), child, ], ), ), ); } } class _InfoRow extends StatelessWidget { final String label; final String value; const _InfoRow({required this.label, required this.value}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( children: [ Text('$label: ', style: const TextStyle(color: Color(0xFF6B7280))), Expanded( child: Text(value, style: const TextStyle(fontWeight: FontWeight.w500)), ), ], ), ); } } class _ActionButton extends StatelessWidget { final String label; final Color color; final IconData icon; final VoidCallback onTap; const _ActionButton({ required this.label, required this.color, required this.icon, required this.onTap, }); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 10), child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: color, minimumSize: const Size.fromHeight(48), ), icon: Icon(icon), label: Text(label), onPressed: onTap, ), ); } }