import 'dart:ui'; import 'package:be_happy/presentation/components/payment_option.dart'; import 'package:be_happy/presentation/components/sheet/payment_method_sheet.dart'; import 'package:be_happy/presentation/components/sheet/tariff_info_sheet.dart'; import 'package:be_happy/presentation/viewmodel/payment_method_sheet_bloc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../../di/service_locator.dart'; import '../../../domain/entities/payment_card.dart'; import '../../../domain/entities/scooter.dart'; import '../../../domain/entities/tariff.dart'; import '../../../domain/usecase/get_payment_cards_usecase.dart'; import '../../event/payment_method_sheet_event.dart'; import '../../event/tariff_sheet_event.dart'; import '../../state/tariff_sheet_state.dart'; import '../../viewmodel/tariff_sheet_bloc.dart'; import '../gradient_button.dart'; import '../scooter/mini_battery_indicator.dart'; class TariffSheet extends StatefulWidget { final Scooter scooter; const TariffSheet({super.key, required this.scooter}); @override State createState() => _TariffSheetState(); } class _TariffSheetState extends State { int? _selectedTariffIndex; bool _hasPaymentCard = true; @override void initState() { super.initState(); context.read().add(TariffSheetStarted(widget.scooter.id)); } @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { if (state.status == TariffSheetStatus.loading) { return Align( alignment: Alignment.bottomCenter, child: ClipRRect( borderRadius: const BorderRadius.vertical( top: Radius.circular(30), ), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), child: Container( height: 520, decoration: BoxDecoration( color: const Color(0xFF000032).withOpacity(0.88), borderRadius: const BorderRadius.vertical( top: Radius.circular(30), ), ), child: const Center( child: CircularProgressIndicator(color: Colors.white), ), ), ), ), ); } if (state.status == TariffSheetStatus.failure) { return Align( alignment: Alignment.bottomCenter, child: ClipRRect( borderRadius: const BorderRadius.vertical( top: Radius.circular(30), ), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), child: Container( height: 520, decoration: BoxDecoration( color: const Color(0xFF000032).withOpacity(0.88), borderRadius: const BorderRadius.vertical( top: Radius.circular(30), ), ), child: Center( child: Text( state.errorMessage ?? 'Ошибка загрузки тарифов', style: const TextStyle(color: Colors.white), ), ), ), ), ), ); } return Align( alignment: Alignment.bottomCenter, child: ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), child: Container( height: 520, padding: const EdgeInsets.only(top: 20, bottom: 10), decoration: BoxDecoration( color: const Color(0xFF000032).withOpacity(0.88), borderRadius: const BorderRadius.vertical( top: Radius.circular(30), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 🔹 HEADER Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Row( children: [ GestureDetector( onTap: () => Navigator.pop(context), child: Row( children: [ Icon( Icons.arrow_back_ios_sharp, color: const Color(0x99FFFFFF), size: 20, ), Icon( Icons.arrow_back_ios_sharp, color: const Color(0x66FFFFFF), size: 20, ), Icon( Icons.arrow_back_ios_sharp, color: const Color(0x22FFFFFF), size: 20, ), ], ), ), const SizedBox(width: 12), Expanded( child: Text( 'Самокат ${widget.scooter.number}', style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600, ), overflow: TextOverflow.ellipsis, ), ), ], ), ), const SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Row( children: [ SizedBox( height: 80, child: Image.asset( 'assets/icons/e6a5dcb6a3e2ec2362c25ea49509ab10d2312b19-reverse.png', fit: BoxFit.contain, ), ), const SizedBox(width: 16), Expanded( child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(16), ), child: Row( children: [ Stack( clipBehavior: Clip.none, children: [ MiniBatteryIndicator( percent: widget.scooter.batteryLevel, ), Positioned( left: 0, right: 0, top: 0, bottom: 0, child: Center( child: Text( '${widget.scooter.batteryLevel.toInt()}%', // ✅ Цифры style: const TextStyle( color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold, ), ), ), ), ], ), const SizedBox(width: 12), Expanded( child: Text( 'Заряда хватит на 4 часа 17 минут\nили 47 км', style: const TextStyle( color: Colors.white, fontSize: 13, height: 1.4, ), ), ), ], ), ), ), ], ), ), const SizedBox(height: 20), SizedBox( height: 150, child: ListView.builder( scrollDirection: Axis.horizontal, padding: const EdgeInsets.only(left: 20), itemCount: state.tariffs.length, itemBuilder: (context, index) { final tariff = state.tariffs[index]; return Row( children: [ _TariffCard( title: tariff.title, price: tariff.startPrice.toStringAsFixed(2), currency: tariff.currency, subtitle: 'Старт поездки', details: [ 'Далее ${tariff.drivePrice.toStringAsFixed(2)} ${tariff.currency}/мин.', 'Минута на паузе ${tariff.pausePrice.toStringAsFixed(0)} ${tariff.currency}', ], isSelected: _selectedTariffIndex == index, tariff: tariff, onTap: () { setState(() { _selectedTariffIndex = index; }); }, ), if (index < state.tariffs.length - 1) const SizedBox(width: 12), ], ); }, ), ), const SizedBox(height: 16), if (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 && mounted) { if (result is PaymentCard) { context.read().add( PaymentCardChanged(result), ); } else if (result == 'balance') { context.read().add( SelectBalancePressed(), ); } } }, ), ) else 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), ), ], ), ), ), ), ), ), const SizedBox(height: 12), // 🔹 КНОПКА "ЗАБРОНИРОВАТЬ" Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: GradientButton( text: 'Забронировать', showArrows: true, height: 56, width: double.infinity, fontSize: 16, enabled: _selectedTariffIndex != null && (state.selectedCard != null || state.useBalance), onTap: (_selectedTariffIndex != null && (state.selectedCard != null || state.useBalance)) ? () { context.read().add( BookScooterPressed( widget.scooter.id, state.tariffs[_selectedTariffIndex!].id, 0, state.useBalance ? null : state.selectedCard?.id, state.useBalance, false ) ); context.pushReplacement('/home/current-rides-sheet'); } : null, ), ), ], ), ), ), ), ); }, ); } String _getCardType(String lastNumber) { if (lastNumber.isEmpty) return 'Card'; final firstDigit = lastNumber[0]; switch (firstDigit) { case '4': return 'Visa'; case '5': return 'Mastercard'; case '9': return 'BelCard'; default: return 'Card'; } } } class _TariffCard extends StatelessWidget { final String title; final Tariff tariff; final String price; final String currency; final String subtitle; final List details; final bool isSelected; final VoidCallback onTap; const _TariffCard({ required this.title, required this.tariff, required this.price, required this.currency, required this.subtitle, required this.details, required this.isSelected, required this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( width: 220, padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: isSelected ? const Color(0xFF1A1F3E) : Colors.white.withOpacity(0.19), borderRadius: BorderRadius.circular(20), ), // Используем Stack, чтобы наложить кнопку поверх контента child: Stack( children: [ // Основной контент карточки Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Заголовок с иконкой часов Row( children: [ const Icon( Icons.timer_outlined, size: 16, color: Color(0xFF66E3C4), ), const SizedBox(width: 8), Expanded( child: Text( title, style: const TextStyle( color: Color(0xFF66E3C4), fontSize: 13, fontWeight: FontWeight.w600, ), overflow: TextOverflow.ellipsis, ), ), // Резервируем место под иконку инфо справа, // чтобы текст не залез под неё const SizedBox(width: 24), ], ), const SizedBox(height: 12), // Цена + текст рядом Row( crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ Text( '$price $currency', style: const TextStyle(color: Colors.white, fontSize: 24), ), if (subtitle.isNotEmpty) ...[ const SizedBox(width: 6), Expanded( child: Text( subtitle, style: TextStyle( color: isSelected ? Colors.white : Colors.white70, fontSize: 12, ), ), ), ], ], ), const SizedBox(height: 12), // Детали ...details.map( (detail) => Padding( padding: const EdgeInsets.only(bottom: 4), child: Text( detail, style: TextStyle( color: isSelected ? Colors.white : Colors.white70, fontSize: 12, ), ), ), ), ], ), // Кнопка-иконка в верхнем правом углу Positioned( top: 0, right: 0, child: GestureDetector( onTap: () { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => TariffInfoSheet(tariff: tariff), ); print('Info pressed for $title'); }, child: Image.asset( 'assets/icons/info_icon.png', width: 20, height: 20, fit: BoxFit.contain, ), ), ), ], ), ), ); } }