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/custom_app_bar.dart'; import '../components/gradient_button.dart'; import '../components/payment_option.dart'; import '../components/sheet/payment_method_sheet.dart'; import '../event/payment_confirm_event.dart'; import '../event/payment_method_sheet_event.dart'; import '../state/payment_confirm_state.dart'; import '../viewmodel/payment_confirm_bloc.dart'; import '../viewmodel/payment_method_sheet_bloc.dart'; class PaymentConfirmScreen extends StatelessWidget { final int orderId; final List photoIds; const PaymentConfirmScreen({ super.key, required this.orderId, required this.photoIds, }); @override Widget build(BuildContext context) { return _PaymentConfirmScreenContent(orderId: orderId, photoIds: photoIds); } } class _PaymentConfirmScreenContent extends StatelessWidget { final int orderId; final List photoIds; const _PaymentConfirmScreenContent({ required this.orderId, required this.photoIds, }); @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration(gradient: AppColors.phoneScreenBg), child: SafeArea( child: Stack( children: [ Positioned( bottom: 60, left: 0, right: 0, child: Image.asset( 'assets/wave.png', fit: BoxFit.fitWidth, color: Colors.white.withOpacity(0.1), ), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 16), const Padding( padding: EdgeInsets.symmetric(horizontal: 20), child: CustomAppBar(title: 'Завершение поездки'), ), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 24), child: BlocConsumer( listenWhen: (previous, current) { return current.status != previous.status; }, listener: (context, state) { if (state.status == PaymentConfirmStatus.success && state.paymentCompleted) { context.go('/home'); } else if (state.status == PaymentConfirmStatus.failure) { ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( state.errorMessage ?? 'Произошла ошибка при оплате', style: const TextStyle(color: Colors.white), ), backgroundColor: Colors.redAccent.withOpacity(0.9), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), margin: const EdgeInsets.all(20), duration: const Duration(seconds: 3), ), ); } }, builder: (context, state) { final order = state.order; if (state.status == PaymentConfirmStatus.loading && order == null) { return const Center( child: CircularProgressIndicator(), ); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 30), _buildInfoLabel('Самокат:'), _buildValueRow( 'qr_icon.png', "${order?.scooter?.number}", ), const SizedBox(height: 24), _buildInfoLabel('Расстояние:'), _buildValueRow( 'distance_icon.png', "${order?.mileage} km", ), const SizedBox(height: 24), _buildInfoLabel('Начислено баллов:'), _buildValueRow('points_icon.png', '2 балла'), const SizedBox(height: 24), Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoLabel('Стоимость поездки:'), _buildValueRow( 'money_icon.png', '17,17 BYN', ), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoLabel('Оплачено:'), _buildValueRow( 'money_icon.png', '10,00 BYN', ), ], ), ), ], ), const SizedBox(height: 40), // 🔹 БЛОК СУММЫ К ОПЛАТЕ Center( child: Column( children: [ Text( 'Сумма к оплате:', style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 16, ), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'assets/icons/money_icon.png', width: 40, ), const SizedBox(width: 12), const Text( '7,17 BYN', style: TextStyle( color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold, ), ), ], ), ], ), ), const SizedBox(height: 40), // 🔹 КАРТА ОПЛАТЫ (state.useBalance || state.selectedCard != null) ? Padding(padding: const EdgeInsets.symmetric(horizontal: 20), child: PaymentOption( title: state.useBalance ? 'Баланс' : state.selectedCard!.type, subtitle: state.useBalance ? '${state.userBalance.toStringAsFixed(2)} BYN' : '****${state.selectedCard!.cardLastNumber}', isSelected: true, onTap: () async { final result = await showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (innerContext) => BlocProvider( create: (context) => PaymentMethodSheetBloc( getIt(), )..add(PaymentMethodSheetStarted()), child: PaymentMethodSheet( initialSelectedCard: state.useBalance ? null : state.selectedCard, ), ), ); if (result != null) { if (result is PaymentCard) { context.read().add(PaymentCardChanged(result)); } else if (result == 'balance') { context.read().add(SelectBalancePressed()); } } }, ), ) : 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), ), ], ), ), ), ), ), ), ], ); }, ), ), ), Padding( padding: const EdgeInsets.all(24.0), child: BlocConsumer( listener: (context, state) { if (state.status == PaymentConfirmStatus.success && state.paymentCompleted) { context.go('/home'); } else if (state.status == PaymentConfirmStatus.failure) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( state.errorMessage ?? 'Ошибка оплаты', ), ), ); } }, builder: (context, state) { return GradientButton( text: state.status == PaymentConfirmStatus.loading ? 'Обработка...' : 'Оплатить', showArrows: true, height: 56, width: double.infinity, onTap: (state.status == PaymentConfirmStatus.loading || (!state.useBalance && state.selectedCard == null)) ? null : () { context.read().add( PayRide( cardId: state.useBalance ? null : state.selectedCard?.id, isBalance: state.useBalance, orderId: orderId, photoIds: photoIds, ), ); }, ); }, ), ), ], ), ], ), ), ), ); } // Вспомогательный метод для подзаголовков Widget _buildInfoLabel(String text) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Text( text, style: TextStyle(color: Colors.white.withOpacity(0.7), fontSize: 15), ), ); } // Вспомогательный метод для строк со значениями и иконками Widget _buildValueRow(String iconName, String value) { return Row( children: [ Image.asset('assets/icons/$iconName', width: 24, height: 24), const SizedBox(width: 12), Text( value, style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500, ), ), ], ); } String _formatDuration(int minutes) { final h = minutes ~/ 60; final m = minutes % 60; return '${h.toString().padLeft(2, '0')}:${m.toString().padLeft(2, '0')}'; } }