import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_otp_text_field/flutter_otp_text_field.dart'; import 'package:injector/injector.dart'; import 'package:intl_phone_field/intl_phone_field.dart'; import 'package:prosappco/blocs/auth_bloc/auth_bloc.dart'; import 'package:prosappco/screens/authentication/sign_screen.dart'; class WelcomeScreen extends StatefulWidget { const WelcomeScreen({super.key}); @override State createState() => _WelcomeScreenState(); } class _WelcomeScreenState extends State { late final AuthBloc authBloc; String? _phone; String _otpCode = ''; bool _codeSent = false; int _resendSeconds = 0; Timer? _timer; @override void initState() { super.initState(); authBloc = Injector.appInstance.get(); } @override void dispose() { _timer?.cancel(); super.dispose(); } void _startResendTimer() { setState(() => _resendSeconds = 60); _timer?.cancel(); _timer = Timer.periodic(const Duration(seconds: 1), (t) { if (_resendSeconds == 0) { t.cancel(); } else { setState(() => _resendSeconds--); } }); } void _sendCode() { final phone = _phone; if (phone == null || phone.isEmpty) return; authBloc.add(AuthEventLoginOAuth(phone: phone)); setState(() { _codeSent = true; _otpCode = ''; }); _startResendTimer(); } @override Widget build(BuildContext context) { return BlocProvider( create: (_) => authBloc, child: BlocConsumer( listener: (context, state) { if (state is AuthStateFailure) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(state.message ?? 'Error al enviar código')), ); } else if (state is AuthStateVerifyOAuth && state.isWrongCode) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Código incorrecto, intenta de nuevo')), ); } }, builder: (context, state) { return Scaffold( body: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFF42A4EF), Color(0xFF1565C0)], ), ), child: SafeArea( child: Column( children: [ const SizedBox(height: 36), _buildHero(), const SizedBox(height: 24), Expanded( child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(32)), ), padding: const EdgeInsets.fromLTRB(28, 32, 28, 20), child: SingleChildScrollView( child: _codeSent ? _buildOtpSection(state) : _buildPhoneSection(state), ), ), ), ], ), ), ), ); }, ), ); } Widget _buildHero() { return Column( children: [ Image.asset('images/logo_prosapp.png', width: 180), const SizedBox(height: 12), const Text( 'Conecta con los mejores profesionales', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 15, fontWeight: FontWeight.w400, letterSpacing: 0.3, ), ), ], ); } Widget _buildPhoneSection(AuthState state) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Iniciar sesión', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFF1A1A2E)), ), const SizedBox(height: 6), const Text( 'Ingresa tu número para recibir un código de verificación', style: TextStyle(color: Colors.grey, fontSize: 13), ), const SizedBox(height: 24), IntlPhoneField( initialCountryCode: 'CO', keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], onChanged: (phone) => _phone = phone.completeNumber, decoration: InputDecoration( hintText: 'Número de celular', filled: true, fillColor: const Color(0xFFF5F8FF), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFFE0E7FF), width: 1.5), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF42A4EF), width: 2), ), ), ), const SizedBox(height: 8), const Text( 'Te enviaremos un SMS con tu código. Máx 160 caracteres.', style: TextStyle(color: Colors.grey, fontSize: 11), ), const SizedBox(height: 24), if (state is AuthStateProcess) const Center(child: CircularProgressIndicator()) else SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _sendCode, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF42A4EF), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), elevation: 0, ), child: const Text('Enviar código', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), ), ), const SizedBox(height: 24), Row( children: const [ Expanded(child: Divider()), Padding( padding: EdgeInsets.symmetric(horizontal: 12), child: Text('o', style: TextStyle(color: Colors.grey)), ), Expanded(child: Divider()), ], ), const SizedBox(height: 16), SizedBox( width: double.infinity, child: OutlinedButton( onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const SignScreen(initialIndex: 0)), ), style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), side: const BorderSide(color: Color(0xFF42A4EF)), ), child: const Text('Iniciar sesión con email', style: TextStyle(color: Color(0xFF42A4EF), fontWeight: FontWeight.w600)), ), ), const SizedBox(height: 12), Center( child: TextButton( onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const SignScreen(initialIndex: 1)), ), child: RichText( text: const TextSpan( style: TextStyle(color: Colors.grey, fontSize: 14), children: [ TextSpan(text: '¿No tienes cuenta? '), TextSpan( text: 'Regístrate', style: TextStyle(color: Color(0xFF42A4EF), fontWeight: FontWeight.w600), ), ], ), ), ), ), ], ); } Widget _buildOtpSection(AuthState state) { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ const Icon(Icons.sms_outlined, size: 48, color: Color(0xFF42A4EF)), const SizedBox(height: 12), const Text( 'Código de verificación', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Color(0xFF1A1A2E)), ), const SizedBox(height: 8), Text( 'Enviamos un código a\n${_phone ?? ''}', textAlign: TextAlign.center, style: const TextStyle(color: Colors.grey, fontSize: 14), ), const SizedBox(height: 32), OtpTextField( numberOfFields: 6, borderColor: const Color(0xFFE0E7FF), focusedBorderColor: const Color(0xFF42A4EF), showFieldAsBox: true, fieldWidth: 46, borderRadius: BorderRadius.circular(10), textStyle: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold), onCodeChanged: (code) => _otpCode = code, onSubmit: (code) => authBloc.add(AuthEventVerifyOAuth(code: code)), ), const SizedBox(height: 32), if (state is AuthStateProcess) const CircularProgressIndicator() else SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () { if (_otpCode.length == 6) { authBloc.add(AuthEventVerifyOAuth(code: _otpCode)); } }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF42A4EF), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), elevation: 0, ), child: const Text('Verificar código', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)), ), ), const SizedBox(height: 20), _resendSeconds > 0 ? Text( 'Reenviar en $_resendSeconds s', style: const TextStyle(color: Colors.grey, fontSize: 13), ) : TextButton( onPressed: _sendCode, child: const Text('Reenviar código', style: TextStyle(color: Color(0xFF42A4EF), fontWeight: FontWeight.w600)), ), const SizedBox(height: 8), TextButton( onPressed: () => setState(() { _codeSent = false; _otpCode = ''; }), child: const Text('← Cambiar número', style: TextStyle(color: Colors.grey, fontSize: 13)), ), ], ); } }