import 'package:flutter/material.dart'; import '../app_config.dart'; import '../models/address_entry.dart'; import '../models/auth_session.dart'; import '../services/auth_repository.dart'; import '../services/address_repository.dart'; import 'dashboard_screen.dart'; class AddressScreen extends StatefulWidget { const AddressScreen({ super.key, required this.authRepository, required this.addressRepository, required this.session, this.enableLiveFeatures = true, }); final AuthRepository authRepository; final AddressRepository addressRepository; final AuthSession session; final bool enableLiveFeatures; @override State createState() => _AddressScreenState(); } class _AddressScreenState extends State { final GlobalKey _formKey = GlobalKey(); final TextEditingController _houseNumberController = TextEditingController(); final TextEditingController _coloniaController = TextEditingController(); final TextEditingController _streetController = TextEditingController(); bool _isSaving = false; String? _errorMessage; @override void dispose() { _houseNumberController.dispose(); _coloniaController.dispose(); _streetController.dispose(); super.dispose(); } Future _saveAddress() async { if (!(_formKey.currentState?.validate() ?? false)) { return; } setState(() { _isSaving = true; _errorMessage = null; }); try { await widget.addressRepository.saveAddress( session: widget.session, address: AddressEntry( houseNumber: _houseNumberController.text.trim(), colonia: _coloniaController.text.trim(), street: _streetController.text.trim(), ), ); if (!mounted) { return; } Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (_) => DashboardScreen( authRepository: widget.authRepository, addressRepository: widget.addressRepository, session: widget.session, savedAddress: AddressEntry( houseNumber: _houseNumberController.text.trim(), colonia: _coloniaController.text.trim(), street: _streetController.text.trim(), ), enableLiveFeatures: widget.enableLiveFeatures, ), ), (route) => false, ); } on AddressException catch (error) { if (!mounted) { return; } setState(() { _errorMessage = error.message; }); } catch (_) { if (!mounted) { return; } setState(() { _errorMessage = 'No se pudo guardar la dirección. Revisa el backend.'; }); } finally { if (mounted) { setState(() { _isSaving = false; }); } } } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFFF8FAFC), Color(0xFFE2E8F0), Color(0xFFCCFBF1)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), child: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(20), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 520), child: Card( elevation: 12, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)), child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( 'Dirección', style: TextStyle(fontSize: 30, fontWeight: FontWeight.w800), ), const SizedBox(height: 8), Text( 'Ingresa la dirección de tu casa y se enviará al backend para guardarla en PostgreSQL.', style: TextStyle(color: Colors.grey.shade700, height: 1.4), ), const SizedBox(height: 20), if (_errorMessage != null) ...[ _AddressStatusBanner(message: _errorMessage!), const SizedBox(height: 16), ], Form( key: _formKey, child: Column( children: [ TextFormField( controller: _houseNumberController, keyboardType: TextInputType.text, decoration: const InputDecoration( labelText: 'Número de casa', prefixIcon: Icon(Icons.home_outlined), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Ingresa el número de casa'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _coloniaController, decoration: const InputDecoration( labelText: 'Colonia', prefixIcon: Icon(Icons.location_city_outlined), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Ingresa la colonia'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _streetController, decoration: const InputDecoration( labelText: 'Calle', prefixIcon: Icon(Icons.signpost_outlined), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Ingresa la calle'; } return null; }, ), const SizedBox(height: 20), SizedBox( width: double.infinity, height: 52, child: FilledButton( onPressed: _isSaving ? null : _saveAddress, child: _isSaving ? const SizedBox( width: 22, height: 22, child: CircularProgressIndicator(strokeWidth: 2.2, color: Colors.white), ) : const Text('Guardar dirección'), ), ), const SizedBox(height: 12), Text( 'Base URL configurada: ${AppConfig.apiBaseUrl}', style: TextStyle(fontSize: 12, color: Colors.grey.shade600), textAlign: TextAlign.center, ), ], ), ), ], ), ), ), ), ), ), ), ), ); } } class _AddressStatusBanner extends StatelessWidget { const _AddressStatusBanner({required this.message}); final String message; @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xFFFEE2E2), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFFCA5A5)), ), child: Text( message, style: const TextStyle(color: Color(0xFF991B1B), height: 1.35), ), ); } }