import 'package:flutter/material.dart'; import '../services/api.dart'; class AddressEditScreen extends StatefulWidget { const AddressEditScreen({super.key}); @override State createState() => _AddressEditScreenState(); } class _AddressEditScreenState extends State { final _formKey = GlobalKey(); final _labelController = TextEditingController(); final _line1Controller = TextEditingController(); final _line2Controller = TextEditingController(); final _cityController = TextEditingController(); final _zipCodeController = TextEditingController(); bool _isLoading = true; bool _isSaving = false; bool _setAsDefault = false; int? _selectedStateId; List _states = []; DeliveryAddress? _existingAddress; bool get _isEditing => _existingAddress != null; @override void initState() { super.initState(); _loadStates(); } Future _loadStates() async { try { final states = await Api.getStates(); if (mounted) { setState(() { _states = states; // Default to Texas (44) if no address is being edited if (_selectedStateId == null && _existingAddress == null) { _selectedStateId = 44; } _isLoading = false; }); } } catch (e) { debugPrint('Error loading states: $e'); if (mounted) { setState(() => _isLoading = false); } } } @override void didChangeDependencies() { super.didChangeDependencies(); final args = ModalRoute.of(context)?.settings.arguments; if (args is DeliveryAddress && _existingAddress == null) { _existingAddress = args; _labelController.text = args.label; _line1Controller.text = args.line1; _line2Controller.text = args.line2; _cityController.text = args.city; _zipCodeController.text = args.zipCode; _selectedStateId = args.stateId > 0 ? args.stateId : 44; _setAsDefault = args.isDefault; } } @override void dispose() { _labelController.dispose(); _line1Controller.dispose(); _line2Controller.dispose(); _cityController.dispose(); _zipCodeController.dispose(); super.dispose(); } Future _saveAddress() async { if (!_formKey.currentState!.validate()) return; if (_selectedStateId == null) return; setState(() => _isSaving = true); try { await Api.addDeliveryAddress( line1: _line1Controller.text.trim(), line2: _line2Controller.text.trim().isEmpty ? null : _line2Controller.text.trim(), city: _cityController.text.trim(), stateId: _selectedStateId!, zipCode: _zipCodeController.text.trim(), label: _labelController.text.trim().isEmpty ? null : _labelController.text.trim(), setAsDefault: _setAsDefault, ); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(_isEditing ? 'Address updated' : 'Address added', style: const TextStyle(color: Colors.black)), backgroundColor: const Color(0xFF90EE90), behavior: SnackBarBehavior.floating, margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16), ), ); Navigator.pop(context, true); } } catch (e) { debugPrint('Error saving address: $e'); if (mounted) { setState(() => _isSaving = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to save: $e', style: const TextStyle(color: Colors.black)), backgroundColor: const Color(0xFF90EE90), behavior: SnackBarBehavior.floating, margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16), ), ); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(_isEditing ? 'Edit Address' : 'Add Address'), actions: [ TextButton( onPressed: _isSaving || _isLoading ? null : _saveAddress, child: _isSaving ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Save'), ), ], ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( controller: _labelController, decoration: const InputDecoration( labelText: 'Label (optional)', hintText: 'e.g., Home, Work, Office', border: OutlineInputBorder(), prefixIcon: Icon(Icons.label_outline), ), textCapitalization: TextCapitalization.words, ), const SizedBox(height: 16), TextFormField( controller: _line1Controller, decoration: const InputDecoration( labelText: 'Street Address', border: OutlineInputBorder(), prefixIcon: Icon(Icons.location_on_outlined), ), textCapitalization: TextCapitalization.words, validator: (value) { if (value == null || value.trim().isEmpty) { return 'Please enter a street address'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _line2Controller, decoration: const InputDecoration( labelText: 'Apt, Suite, Unit (optional)', border: OutlineInputBorder(), prefixIcon: Icon(Icons.apartment), ), textCapitalization: TextCapitalization.words, ), const SizedBox(height: 16), TextFormField( controller: _cityController, decoration: const InputDecoration( labelText: 'City', border: OutlineInputBorder(), prefixIcon: Icon(Icons.location_city), ), textCapitalization: TextCapitalization.words, validator: (value) { if (value == null || value.trim().isEmpty) { return 'Please enter a city'; } return null; }, ), const SizedBox(height: 16), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( flex: 2, child: DropdownButtonFormField( value: _selectedStateId, decoration: const InputDecoration( labelText: 'State', border: OutlineInputBorder(), ), items: _states.map((state) { return DropdownMenuItem( value: state.stateId, child: Text(state.abbr), ); }).toList(), onChanged: (value) { if (value != null) { setState(() => _selectedStateId = value); } }, validator: (value) { if (value == null || value <= 0) { return 'Select a state'; } return null; }, ), ), const SizedBox(width: 16), Expanded( flex: 2, child: TextFormField( controller: _zipCodeController, decoration: const InputDecoration( labelText: 'ZIP Code', border: OutlineInputBorder(), ), keyboardType: TextInputType.number, validator: (value) { if (value == null || value.trim().isEmpty) { return 'Enter ZIP'; } if (value.trim().length < 5) { return 'Invalid ZIP'; } return null; }, ), ), ], ), const SizedBox(height: 24), SwitchListTile( title: const Text('Set as default address'), subtitle: const Text('Use this address for deliveries by default'), value: _setAsDefault, onChanged: (value) => setState(() => _setAsDefault = value), contentPadding: EdgeInsets.zero, ), ], ), ), ), ); } }