import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../core/app_colors.dart'; import '../../di/service_locator.dart'; import '../../domain/entities/payment_card.dart'; import '../../domain/usecase/get_payment_cards_usecase.dart'; import '../components/app_checkbox.dart'; import '../components/custom_app_bar.dart'; // ✅ Уже есть import '../components/gradient_button.dart'; import '../components/payment_option.dart'; import '../components/sheet/payment_method_sheet.dart'; import '../event/payment_method_sheet_event.dart'; import '../event/top_up_event.dart'; import '../state/top_up_state.dart'; import '../viewmodel/payment_method_sheet_bloc.dart'; import '../viewmodel/top_up_bloc.dart'; class TopUpScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration(gradient: AppColors.phoneScreenBg), child: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( children: [ const SizedBox(height: 16), const CustomAppBar(title: 'Пополнение баланса'), const SizedBox(height: 20), BlocBuilder( builder: (context, state) { if (state.isLoading) { return const Center(child: CircularProgressIndicator()); } return Expanded( child: Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildTariffList(state, context), const SizedBox(height: 30), _buildPriceInfo(state), const SizedBox(height: 40), const Text( 'Способ оплаты', style: TextStyle(color: Colors.white70), ), const SizedBox(height: 15), _buildCardSelector(state, context), const SizedBox(height: 20), _buildAgreement(state, context), const Spacer(), _buildPayButton(state), const SizedBox(height: 30), ], ), ], ), ); }, ), ], ), ), ) ), ); } Widget _buildTariffList(TopUpState state, BuildContext context) { return SizedBox( height: 120, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: state.certificates.length, separatorBuilder: (_, __) => const SizedBox(width: 12), itemBuilder: (context, index) { final tariff = state.certificates[index]; final isSelected = state.selectedTariff == tariff; return GestureDetector( onTap: () => context.read().add(SelectCertificate(tariff)), child: Container( width: 140, decoration: BoxDecoration( color: isSelected ? const Color(0xFF80FFC1) : Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.white24), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ if (tariff.discount != null) Text( 'скидка: ${tariff.discount!.toInt()}%', style: TextStyle( color: isSelected ? Colors.black87 : Colors.tealAccent, ), ), Text( '${tariff.value} баллов', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: isSelected ? Colors.black : Colors.white, ), ), ], ), ), ); }, ), ); } Widget _buildPriceInfo(TopUpState state) { if (state.selectedTariff == null) return const SizedBox.shrink(); return Center( child: Column( children: [ Text( 'Купить со скидкой ${state.selectedTariff!.discount?.toInt()}%:', style: const TextStyle(color: Colors.white, fontSize: 16), ), const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset("assets/icons/money_icon.png", width: 24, height: 24), const SizedBox(width: 8), Text( '${state.selectedTariff!.price.toStringAsFixed(2)} BYN', style: const TextStyle( color: Color(0xFF80FFC1), fontSize: 28, fontWeight: FontWeight.bold, ), ), ], ), ], ), ); } Widget _buildCardSelector(TopUpState state, BuildContext context) { return state.selectedCard != null ? Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: PaymentOption( title: state.selectedCard!.type, subtitle: '****${state.selectedCard!.cardLastNumber}', isSelected: true, onTap: () async { final selectedCard = await showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (innerContext) => BlocProvider( create: (context) => PaymentMethodSheetBloc(getIt()) ..add(PaymentMethodSheetStarted()), child: const PaymentMethodSheet(showBalance: false,), ), ); if (selectedCard != null) { context.read().add(SelectCard(selectedCard)); } }, ), ) : Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Container( height: 56, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), border: Border.all( color: Colors.white.withOpacity(0.4), width: 1, ), ), child: Material( color: Colors.transparent, child: InkWell( onTap: () { context.pushReplacement('/home/payment-method-sheet'); }, borderRadius: BorderRadius.circular(24), child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'Способ оплаты', style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600, ), ), const SizedBox(width: 8), Icon( Icons.arrow_forward_ios, size: 12, color: Colors.white.withOpacity(0.6), ), Icon( Icons.arrow_forward_ios, size: 12, color: Colors.white.withOpacity(0.4), ), Icon( Icons.arrow_forward_ios, size: 12, color: Colors.white.withOpacity(0.2), ), ], ), ), ), ), ), ); } Widget _buildAgreement(TopUpState state, BuildContext context) { return Row( children: [ AppCheckbox( value: state.isAgreed, onChanged: (v) => context.read().add(ToggleAgreement(v ?? false)), ), const SizedBox(width: 12), Flexible( child: Text.rich( TextSpan( text: 'Я принимаю условия покупки бонусного пакета, при котором денежные средства не подлежат возврату... ', style: const TextStyle( color: AppColors.white70, fontSize: 12, ), ), ), ), ], ); } Widget _buildPayButton(TopUpState state) { return GradientButton( text: 'Оплатить', onTap: state.isAgreed ? () {} : null, enabled: state.isAgreed, showArrows: true, height: 56, width: double.infinity, fontSize: 16, ); } }