import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../providers/dashboard_providers.dart'; class NewReservationScreen extends ConsumerStatefulWidget { const NewReservationScreen({super.key}); @override ConsumerState createState() => _NewReservationScreenState(); } class _NewReservationScreenState extends ConsumerState { final _formKey = GlobalKey(); bool _loading = false; String? _vehicleId; String? _vehicleName; String? _customerId; String? _customerName; DateTime? _startDate; DateTime? _endDate; final _pickup = TextEditingController(); final _returnLoc = TextEditingController(); final _notes = TextEditingController(); final _deposit = TextEditingController(text: '0'); @override void dispose() { for (final c in [_pickup, _returnLoc, _notes, _deposit]) { c.dispose(); } super.dispose(); } Future _pickDateRange() async { final range = await showDateRangePicker( context: context, firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 365)), initialDateRange: _startDate != null && _endDate != null ? DateTimeRange(start: _startDate!, end: _endDate!) : null, ); if (range != null) { setState(() { _startDate = range.start; _endDate = range.end; }); } } Future _pickVehicle() async { final vehicles = await ref .read(vehicleServiceProvider) .getVehicles(status: 'AVAILABLE', pageSize: 100); if (!mounted) return; final result = await showModalBottomSheet>( context: context, isScrollControlled: true, builder: (_) => DraggableScrollableSheet( initialChildSize: 0.6, expand: false, builder: (_, scroll) => ListView.builder( controller: scroll, padding: const EdgeInsets.symmetric(vertical: 8), itemCount: vehicles.data.length, itemBuilder: (_, i) { final v = vehicles.data[i]; return ListTile( title: Text(v.displayName), subtitle: Text(v.licensePlate), onTap: () => Navigator.pop( context, {'id': v.id, 'name': v.displayName}), ); }, ), ), ); if (result != null) { setState(() { _vehicleId = result['id']; _vehicleName = result['name']; }); } } Future _pickCustomer() async { final customers = await ref.read(customerServiceProvider).getCustomers(pageSize: 100); if (!mounted) return; final result = await showModalBottomSheet>( context: context, isScrollControlled: true, builder: (_) => DraggableScrollableSheet( initialChildSize: 0.6, expand: false, builder: (_, scroll) => ListView.builder( controller: scroll, padding: const EdgeInsets.symmetric(vertical: 8), itemCount: customers.data.length, itemBuilder: (_, i) { final c = customers.data[i]; return ListTile( title: Text(c.fullName), subtitle: Text(c.email ?? c.phone ?? ''), onTap: () => Navigator.pop( context, {'id': c.id, 'name': c.fullName}), ); }, ), ), ); if (result != null) { setState(() { _customerId = result['id']; _customerName = result['name']; }); } } Future _submit() async { if (!_formKey.currentState!.validate()) return; if (_vehicleId == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please select a vehicle'))); return; } if (_customerId == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please select a customer'))); return; } if (_startDate == null || _endDate == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please select dates'))); return; } setState(() => _loading = true); try { final data = { 'vehicleId': _vehicleId!, 'customerId': _customerId!, 'startDate': '${_startDate!.toIso8601String().substring(0, 10)}T00:00:00.000Z', 'endDate': '${_endDate!.toIso8601String().substring(0, 10)}T00:00:00.000Z', if (_pickup.text.isNotEmpty) 'pickupLocation': _pickup.text.trim(), if (_returnLoc.text.isNotEmpty) 'returnLocation': _returnLoc.text.trim(), if (_notes.text.isNotEmpty) 'notes': _notes.text.trim(), 'depositAmount': ((double.tryParse(_deposit.text) ?? 0) * 100).round(), }; await ref.read(reservationServiceProvider).createReservation(data); if (mounted) Navigator.of(context).pop(true); } catch (e) { if (mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('Error: $e'))); } } finally { if (mounted) setState(() => _loading = false); } } @override Widget build(BuildContext context) { final fmt = DateFormat('MMM d, yyyy'); return Scaffold( appBar: AppBar( title: const Text('New Reservation'), actions: [ if (_loading) const Padding( padding: EdgeInsets.all(16), child: SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)), ) else TextButton( onPressed: _submit, child: const Text('Create'), ), ], ), body: Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(16), children: [ _PickerTile( label: 'Vehicle', value: _vehicleName, icon: Icons.directions_car_outlined, onTap: _pickVehicle, placeholder: 'Select available vehicle', ), const SizedBox(height: 12), _PickerTile( label: 'Customer', value: _customerName, icon: Icons.person_outlined, onTap: _pickCustomer, placeholder: 'Select customer', ), const SizedBox(height: 12), _PickerTile( label: 'Rental Period', value: _startDate != null && _endDate != null ? '${fmt.format(_startDate!)} → ${fmt.format(_endDate!)}' : null, icon: Icons.date_range_outlined, onTap: _pickDateRange, placeholder: 'Select start & end dates', ), const SizedBox(height: 16), Card( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Column( children: [ _textField('Pickup Location', _pickup), _textField('Return Location', _returnLoc), _textField('Deposit (\$)', _deposit, inputType: TextInputType.number), _textField('Notes', _notes, maxLines: 3), ], ), ), ), const SizedBox(height: 24), ElevatedButton( onPressed: _loading ? null : _submit, style: ElevatedButton.styleFrom( minimumSize: const Size.fromHeight(48), ), child: const Text('Create Reservation'), ), ], ), ), ); } Widget _textField(String label, TextEditingController ctrl, {TextInputType? inputType, int maxLines = 1}) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: TextFormField( controller: ctrl, keyboardType: inputType, maxLines: maxLines, decoration: InputDecoration(labelText: label), ), ); } } class _PickerTile extends StatelessWidget { final String label; final String? value; final String placeholder; final IconData icon; final VoidCallback onTap; const _PickerTile({ required this.label, required this.value, required this.placeholder, required this.icon, required this.onTap, }); @override Widget build(BuildContext context) { return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: const Color(0xFFE5E7EB)), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon(icon, color: const Color(0xFF6B7280)), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: const TextStyle( fontSize: 11, color: Color(0xFF9CA3AF))), const SizedBox(height: 2), Text( value ?? placeholder, style: TextStyle( fontWeight: value != null ? FontWeight.w500 : FontWeight.normal, color: value != null ? const Color(0xFF111928) : const Color(0xFF9CA3AF), ), ), ], ), ), const Icon(Icons.chevron_right, color: Color(0xFF9CA3AF)), ], ), ), ); } }