import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../core/app_colors.dart'; import '../../di/service_locator.dart'; import '../../domain/usecase/apply_promo_code_usecase.dart'; import '../components/custom_app_bar.dart'; import '../event/promo_code_event.dart'; import '../state/promo_code_state.dart'; import '../viewmodel/promo_code_bloc.dart'; class PromoCodeScreen extends StatelessWidget { const PromoCodeScreen({super.key}); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => PromoCodeBloc(getIt()), child: const _PromoCodeScreenContent(), ); } } class _PromoCodeScreenContent extends StatefulWidget { const _PromoCodeScreenContent(); @override State<_PromoCodeScreenContent> createState() => _PromoCodeScreenContentState(); } class _PromoCodeScreenContentState extends State<_PromoCodeScreenContent> { final TextEditingController promoController = TextEditingController(); @override void dispose() { promoController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, body: Container( decoration: const BoxDecoration(gradient: AppColors.phoneScreenBg), child: SafeArea( child: Column( children: [ Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( children: [ const SizedBox(height: 16), CustomAppBar(title: 'Промокоды'), const SizedBox(height: 32), // 🔹 LISTENER: Только сайд-эффекты (SnackBar, навигация) BlocListener( listener: (context, state) { if (state.status == PromoCodeStatus.success) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Промокод активирован! Баланс: ${state.newBalance?.toStringAsFixed(2)} BYN', ), backgroundColor: Colors.green, ), ); // Очищаем поле визуально promoController.clear(); // Ждем чуть меньше, чтобы пользователь увидел успех Future.delayed(const Duration(milliseconds: 1200), () { if (mounted) Navigator.pop(context); }); } else if (state.status == PromoCodeStatus.failure) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(state.errorMessage ?? 'Ошибка активации'), backgroundColor: Colors.red, ), ); } }, child: BlocBuilder( builder: (context, state) { final bool hasError = state.status == PromoCodeStatus.failure; final bool isLoading = state.status == PromoCodeStatus.loading; return Container( padding: const EdgeInsets.all(25), decoration: BoxDecoration( color: const Color(0xFF141530), borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'У вас есть промокод?', style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600), ), const SizedBox(height: 24), const Text( 'Введите промокод и получите скидку на поездку', style: TextStyle(color: AppColors.white70, fontSize: 16), ), const SizedBox(height: 20), TextField( controller: promoController, enabled: !isLoading, style: TextStyle(color: hasError ? Colors.red : Colors.white), decoration: InputDecoration( hintText: 'Введите промокод', hintStyle: const TextStyle(color: AppColors.white70), filled: true, fillColor: Colors.white.withOpacity(0.1), border: OutlineInputBorder( borderRadius: BorderRadius.circular(24), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(24), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(24), borderSide: BorderSide( color: hasError ? Colors.red : AppColors.smsDigit, width: 1.5, ), ), // ✅ Явно убираем ошибку при успехе errorText: hasError ? 'Неверный промокод' : null, ), onSubmitted: (_) => _submit(context), ), const SizedBox(height: 20), Row( children: [ Expanded( child: OutlinedButton( onPressed: isLoading ? null : () => Navigator.pop(context), style: OutlinedButton.styleFrom( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), side: BorderSide(color: AppColors.white70.withOpacity(0.4)), padding: const EdgeInsets.symmetric(vertical: 12), ), child: const Text('Отмена', style: TextStyle(color: AppColors.white70)), ), ), const SizedBox(width: 22), Expanded( child: ElevatedButton( onPressed: isLoading ? null : () => _submit(context), style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), backgroundColor: AppColors.activeButtonGradient.colors[0], padding: const EdgeInsets.symmetric(vertical: 12), ), child: isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(color: AppColors.activeButtonText, strokeWidth: 2), ) : const Text('Активировать', style: TextStyle(color: AppColors.activeButtonText)), ), ), ], ), ], ), ); }, ), ), const Spacer(), ], ), ), ), Image.asset( 'assets/promo_bottom.png', width: double.infinity, fit: BoxFit.contain, alignment: Alignment.center, ), const SizedBox(height: 80), ], ), ), ), ); } void _submit(BuildContext context) { final code = promoController.text.trim(); if (code.isEmpty) return; context.read().add(PromoCodeApplyRequested(code)); } }