import 'package:flutter/material.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:miler/views/helpers/constants/Font_constant.dart'; import 'package:miler/views/helpers/constants/Colorconstants.dart'; import 'package:miler/views/helpers/constants/design_constants.dart'; import 'package:miler/views/helpers/widgets/app_widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:slider_button_lite/feature/presentation/slider_button/slider.dart'; import 'package:slider_button_lite/feature/presentation/slider_button/slider_button_prop.dart'; class PaymentScreen extends StatefulWidget { final Map pickup; final Map verificationData; const PaymentScreen({ super.key, required this.pickup, required this.verificationData, }); @override State createState() => _PaymentScreenState(); } class _PaymentScreenState extends State with TickerProviderStateMixin { String _paymentMethod = 'cash'; bool _isProcessing = false; bool _isSuccess = false; bool _paymentVerified = false; double _pickupCharge = 0.0; double _totalAmount = 0.0; late final String _customerName; late final String _orderId; late final String _bookingId; late final String _trackingId; late final String _weight; late final String _description; late AnimationController _successAnimController; late Animation _successScaleAnim; late Animation _successFadeAnim; @override void initState() { super.initState(); final d = widget.pickup; final v = widget.verificationData; _customerName = (d['pickupcustomer'] ?? 'Customer').toString(); _orderId = (d['orderid'] ?? '').toString(); _bookingId = _orderId.isNotEmpty ? _orderId : 'DM${DateTime.now().millisecondsSinceEpoch.toString().substring(5)}'; _trackingId = (d['trackingid'] ?? 'TRK${DateTime.now().millisecondsSinceEpoch.toString().substring(4)}') .toString(); _weight = (v['weight'] ?? '0').toString(); _description = (v['description'] ?? '').toString(); _pickupCharge = double.tryParse(_weight) != null ? double.parse(_weight) * 15.0 : 30.0; _totalAmount = _pickupCharge; _successAnimController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, ); _successScaleAnim = CurvedAnimation( parent: _successAnimController, curve: Curves.elasticOut, ); _successFadeAnim = CurvedAnimation( parent: _successAnimController, curve: Curves.easeOut, ); } @override void dispose() { _successAnimController.dispose(); super.dispose(); } Future _processPayment() async { if (_isProcessing) return; setState(() => _isProcessing = true); // Simulate backend payment verification await Future.delayed(const Duration(milliseconds: 1500)); if (!mounted) return; // Verify payment was successful _paymentVerified = true; setState(() { _isProcessing = false; _isSuccess = true; }); // Start success animation _successAnimController.forward(); // Auto-navigate after showing success (optional) await Future.delayed(const Duration(milliseconds: 2500)); if (mounted && _isSuccess) { _completePayment(); } } void _completePayment({bool goToBookings = false}) { if (!mounted) return; Navigator.pop(context, { 'paid': true, 'goto_bookings': goToBookings, 'verified': true, }); } @override Widget build(BuildContext context) { if (_isSuccess) return _buildSuccessView(); return _buildPaymentView(); } // ────────────────────────────── SUCCESS VIEW ───────────────────────────── Widget _buildSuccessView() { return Scaffold( backgroundColor: ColorConstants.surface, body: SafeArea( child: FadeTransition( opacity: _successFadeAnim, child: Padding( padding: EdgeInsets.all(24.r), child: Column( children: [ const Spacer(flex: 2), // Success animation circle ScaleTransition( scale: _successScaleAnim, child: Container( width: 110.r, height: 110.r, decoration: BoxDecoration( gradient: LinearGradient( colors: [ ColorConstants.success, ColorConstants.acceptGreen, ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), shape: BoxShape.circle, boxShadow: [ BoxShadow( color: ColorConstants.success.withValues(alpha: 0.3), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: Icon( LucideIcons.check, color: Colors.white, size: 52.sp, ), ), ), SizedBox(height: 24.h), Text( 'Payment Collected Successfully', style: TextStyle( fontSize: 26.sp, fontWeight: FontWeight.w800, color: ColorConstants.onSurface, fontFamily: FontConstants.fontFamily, ), ), SizedBox(height: 8.h), Text( '₹${_totalAmount.toStringAsFixed(0)} via ${_paymentMethod.toUpperCase()}', style: TextStyle( fontSize: 15.sp, color: ColorConstants.onSurfaceVariant, fontFamily: FontConstants.fontFamily, ), ), SizedBox(height: 32.h), // Receipt Card - Corporate Design Container( width: double.infinity, decoration: BoxDecoration( color: ColorConstants.pureSurface, borderRadius: BorderRadius.circular( DesignConstants.radiusXl, ), border: Border.all(color: ColorConstants.outlineVariant), boxShadow: DesignConstants.shadowSm, ), child: Column( children: [ // Receipt header Container( padding: EdgeInsets.all(16.r), decoration: BoxDecoration( gradient: LinearGradient( colors: [ ColorConstants.primary.withValues(alpha: 0.08), ColorConstants.primary.withValues(alpha: 0.03), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.vertical( top: Radius.circular(18.r), ), ), child: Row( children: [ Container( padding: EdgeInsets.all(10.r), decoration: BoxDecoration( color: ColorConstants.primaryContainer .withValues(alpha: 0.1), borderRadius: BorderRadius.circular( DesignConstants.radiusLg, ), ), child: Icon( LucideIcons.receiptText, color: ColorConstants.primary, size: 18.sp, ), ), SizedBox(width: 10.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Payment Receipt', style: TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w600, color: ColorConstants.onSurface, fontFamily: FontConstants.fontFamily, ), ), Text( 'Payment verified and recorded', style: TextStyle( fontSize: 12.sp, color: ColorConstants.onSurfaceVariant, fontFamily: FontConstants.fontFamily, ), ), ], ), ), ], ), ), Padding( padding: EdgeInsets.all(16.r), child: Column( children: [ _receiptRow('Booking ID', '#$_bookingId'), SizedBox(height: 10.h), Divider( color: ColorConstants.outlineVariant, height: 1, ), SizedBox(height: 10.h), _receiptRow('Tracking ID', _trackingId), SizedBox(height: 10.h), Divider( color: ColorConstants.outlineVariant, height: 1, ), SizedBox(height: 10.h), _receiptRow('Customer', _customerName), SizedBox(height: 10.h), Divider( color: ColorConstants.outlineVariant, height: 1, ), SizedBox(height: 10.h), _receiptRow( 'Amount Collected', '₹${_totalAmount.toStringAsFixed(0)}', valueColor: ColorConstants.success, valueBold: true, ), ], ), ), ], ), ), const Spacer(flex: 2), // Action Buttons Column( children: [ // Next Booking Button MilerButton( label: 'Move to next booking', onPressed: () => _completePayment(goToBookings: true), ), SizedBox(height: 12.h), TextButton( onPressed: () => _completePayment(goToBookings: false), child: Text( 'Return to Collection', style: TextStyle( fontSize: 14.sp, color: ColorConstants.onSurfaceVariant, fontFamily: FontConstants.fontFamily, ), ), ), ], ), SizedBox(height: 16.h), ], ), ), ), ), ); } Widget _receiptRow( String label, String value, { Color? valueColor, bool valueBold = false, }) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( label, style: TextStyle( fontSize: 13.sp, color: ColorConstants.secondaryText, fontFamily: FontConstants.fontFamily, ), ), Text( value, style: TextStyle( fontSize: 14.sp, fontWeight: valueBold ? FontWeight.w600 : FontWeight.w500, color: valueColor ?? ColorConstants.onSurface, fontFamily: FontConstants.fontFamily, ), ), ], ); } // ────────────────────────────── PAYMENT VIEW ───────────────────────────── Widget _buildPaymentView() { return Scaffold( backgroundColor: ColorConstants.surface, body: Column( children: [ // ── Premium Gradient Header ────────────────────────────────── Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [ ColorConstants.primary, ColorConstants.primaryContainer, ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: SafeArea( bottom: false, child: Column( children: [ // App bar row Padding( padding: EdgeInsets.symmetric( horizontal: 16.w, vertical: 8.h, ), child: Row( children: [ GestureDetector( onTap: () => Navigator.pop(context), child: Container( width: 40.w, height: 40.w, decoration: BoxDecoration( color: ColorConstants.pureSurface.withValues( alpha: 0.15, ), shape: BoxShape.circle, ), child: Icon( LucideIcons.chevronLeft, color: Colors.white, size: 16.sp, ), ), ), SizedBox(width: 12.w), Text( 'Payment Collection', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.w700, color: Colors.white, fontFamily: FontConstants.fontFamily, letterSpacing: 0.5, ), ), ], ), ), // Amount display Padding( padding: EdgeInsets.fromLTRB(20.w, 8.h, 20.w, 24.h), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Amount to Collect', style: TextStyle( fontSize: 12.sp, color: Colors.white.withValues(alpha: 0.75), fontFamily: FontConstants.fontFamily, letterSpacing: 0.3, ), ), SizedBox(height: 4.h), Text( '₹${_totalAmount.toStringAsFixed(0)}', style: TextStyle( fontSize: 36.sp, fontWeight: FontWeight.w800, color: Colors.white, fontFamily: FontConstants.fontFamily, letterSpacing: -1, ), ), ], ), Container( padding: EdgeInsets.symmetric( horizontal: 12.w, vertical: 8.h, ), decoration: BoxDecoration( color: ColorConstants.pureSurface.withValues( alpha: 0.15, ), borderRadius: BorderRadius.circular( DesignConstants.radiusLg, ), border: Border.all( color: Colors.white.withValues(alpha: 0.2), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '#$_orderId', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w600, color: Colors.white, fontFamily: FontConstants.fontFamily, ), ), Text( _customerName, style: TextStyle( fontSize: 11.sp, color: Colors.white.withValues(alpha: 0.8), fontFamily: FontConstants.fontFamily, ), ), ], ), ), ], ), ), ], ), ), ), // ── Scrollable body ────────────────────────────────────────── Expanded( child: SingleChildScrollView( physics: const BouncingScrollPhysics(), padding: EdgeInsets.all(16.r), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 4.h), // ── Booking Summary Card ────────────────────────────── _sectionLabel('Booking Summary'), SizedBox(height: 10.h), Container( width: double.infinity, padding: EdgeInsets.all(16.r), decoration: _cardDecoration(), child: Column( children: [ _summaryRow('Customer', _customerName), _divider(), _summaryRow('Booking', '#$_orderId'), _divider(), _summaryRow('Weight', '$_weight kg'), if (_description.isNotEmpty) ...[ _divider(), _summaryRow('Item', _description), ], _divider(), _summaryRow( 'Collection Charge', '₹${_pickupCharge.toStringAsFixed(2)}', isBold: true, ), Padding( padding: EdgeInsets.symmetric(vertical: 8.h), child: Container( height: 1, color: ColorConstants.primary.withValues( alpha: 0.3, ), ), ), _summaryRow( 'Total', '₹${_totalAmount.toStringAsFixed(2)}', isBold: true, isTotal: true, ), ], ), ), SizedBox(height: 20.h), // ── Payment Method ────────────────────────────────── _sectionLabel('Payment Method'), SizedBox(height: 10.h), _buildPaymentOption( LucideIcons.banknote, 'Cash', 'Pay with cash on collection', 'cash', ColorConstants.success, ), SizedBox(height: 10.h), _buildPaymentOption( LucideIcons.scanLine, 'QR / UPI', 'Scan QR code to pay', 'upi', ColorConstants.upiPurple, ), SizedBox(height: 10.h), _buildPaymentOption( LucideIcons.creditCard, 'Card', 'Swipe / tap card terminal', 'card', ColorConstants.tertiary, ), SizedBox(height: 28.h), // ── Slide to Collect Button ───────────────────────── _isProcessing ? Container( height: ButtonSizes.primary, decoration: BoxDecoration( color: ColorConstants.primary, borderRadius: BorderRadius.circular( DesignConstants.radiusXl, ), ), child: const Center( child: SizedBox( width: 24, height: 24, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ), ), ) : ClipRRect( borderRadius: BorderRadius.circular( DesignConstants.radiusXl, ), child: Container( color: ColorConstants.primary, child: SliderButton( properties: SliderButtonProperties( radius: 24, height: ButtonSizes.primary, buttonSize: 48, width: MediaQuery.of(context).size.width - 32.w, backgroundColor: Colors.transparent, dismissThresholds: 0.85, action: () async { debugPrint( '[PAYMENT_SLIDER] Action called, processing payment', ); await _processPayment(); debugPrint( '[PAYMENT_SLIDER] _processPayment completed, returning true', ); return true; }, label: Text( 'Slide to Collect ₹${_totalAmount.toStringAsFixed(0)}', textAlign: TextAlign.center, style: TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w600, color: Colors.white, fontFamily: FontConstants.fontFamily, ), ), icon: Container( margin: const EdgeInsets.all(4), decoration: BoxDecoration( color: ColorConstants.pureSurface, shape: BoxShape.circle, ), child: Icon( LucideIcons.banknote, size: 22.sp, color: ColorConstants.primary, ), ), ), ), ), ), SizedBox(height: 10.h), Center( child: Text( 'Collect from customer before starting pickup', style: TextStyle( fontSize: 12.sp, color: ColorConstants.onSurfaceVariant, fontFamily: FontConstants.fontFamily, ), ), ), SizedBox(height: 20.h), ], ), ), ), ], ), ); } Widget _sectionLabel(String label) { return Text( label, style: TextStyle( fontSize: 13.sp, fontWeight: FontWeight.w600, color: ColorConstants.onSurfaceVariant, fontFamily: FontConstants.fontFamily, letterSpacing: 0.5, ), ); } Widget _buildPaymentOption( IconData icon, String title, String subtitle, String value, Color accentColor, ) { final isSelected = _paymentMethod == value; return GestureDetector( onTap: () => setState(() => _paymentMethod = value), child: AnimatedContainer( duration: const Duration(milliseconds: 200), width: double.infinity, padding: EdgeInsets.all(14.r), decoration: BoxDecoration( color: isSelected ? accentColor.withValues(alpha: 0.06) : ColorConstants.pureSurface, borderRadius: BorderRadius.circular(DesignConstants.radiusXl), border: Border.all( color: isSelected ? accentColor : ColorConstants.outlineVariant, width: isSelected ? 2 : 1, ), boxShadow: isSelected ? [ BoxShadow( color: accentColor.withValues(alpha: 0.1), blurRadius: 10, offset: const Offset(0, 4), ), ] : [], ), child: Row( children: [ AnimatedContainer( duration: const Duration(milliseconds: 200), padding: EdgeInsets.all(10.r), decoration: BoxDecoration( color: isSelected ? accentColor.withValues(alpha: 0.12) : const Color(0xFFF3F4F6), borderRadius: BorderRadius.circular(DesignConstants.radiusLg), ), child: Icon( icon, color: isSelected ? accentColor : ColorConstants.onSurfaceVariant, size: 22.sp, ), ), SizedBox(width: 14.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontSize: 15.sp, fontWeight: FontWeight.w600, color: ColorConstants.onSurface, fontFamily: FontConstants.fontFamily, ), ), SizedBox(height: 2.h), Text( subtitle, style: TextStyle( fontSize: 12.sp, color: ColorConstants.onSurfaceVariant, fontFamily: FontConstants.fontFamily, ), ), ], ), ), AnimatedContainer( duration: const Duration(milliseconds: 200), width: 22.w, height: 22.w, decoration: BoxDecoration( shape: BoxShape.circle, color: isSelected ? accentColor : Colors.transparent, border: Border.all( color: isSelected ? accentColor : const Color(0xFFD1D5DB), width: isSelected ? 0 : 2, ), ), child: isSelected ? Icon(LucideIcons.check, color: Colors.white, size: 14.sp) : null, ), ], ), ), ); } Widget _summaryRow( String label, String value, { bool isBold = false, bool isTotal = false, }) { return Padding( padding: EdgeInsets.symmetric(vertical: 5.h), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( label, style: TextStyle( fontSize: isTotal ? 15.sp : 13.sp, color: ColorConstants.onSurfaceVariant, fontWeight: isBold ? FontWeight.w500 : FontWeight.normal, fontFamily: FontConstants.fontFamily, ), ), Text( value, style: TextStyle( fontSize: isTotal ? 17.sp : 14.sp, fontWeight: isTotal ? FontWeight.w700 : (isBold ? FontWeight.w600 : FontWeight.w500), color: isTotal ? ColorConstants.primary : ColorConstants.onSurface, fontFamily: FontConstants.fontFamily, ), ), ], ), ); } Widget _divider() => Padding( padding: EdgeInsets.symmetric(vertical: 2.h), child: Divider(color: ColorConstants.outlineVariant, height: 1), ); BoxDecoration _cardDecoration() { return BoxDecoration( color: ColorConstants.pureSurface, borderRadius: BorderRadius.circular(DesignConstants.radiusXl), border: Border.all(color: ColorConstants.outlineVariant), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.03), blurRadius: 8, offset: const Offset(0, 2), ), ], ); } }