import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:cashumit/providers/receipt_provider.dart'; import 'package:cashumit/utils/currency_format.dart'; import 'package:cashumit/utils/app_text_styles.dart'; class ReceiptTotal extends StatelessWidget { final double total; final VoidCallback? onSetTip; final VoidCallback? onClearTip; const ReceiptTotal({ super.key, required this.total, this.onSetTip, this.onClearTip, }); String _fmt(num v) { final s = v.abs().toStringAsFixed(0).replaceAllMapped( RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},'); return v < 0 ? '-$s' : s; } @override Widget build(BuildContext context) { final receiptProvider = Provider.of(context); final state = receiptProvider.state; final paymentAmount = state.paymentAmount; final changeAmount = paymentAmount - total; final hasSufficientPayment = paymentAmount >= total; final hasTip = state.hasTip; final primaryColor = Theme.of(context).colorScheme.primary; return Container( width: double.infinity, padding: const EdgeInsets.all(8.0), color: Colors.white, child: SingleChildScrollView( child: Column( children: [ // Total - Tap to open payment dialog GestureDetector( onTap: () { receiptProvider.showPaymentTipDialog(context); }, child: Container( padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( border: Border.all(color: Colors.grey[300]!), borderRadius: BorderRadius.circular(4), color: Colors.grey[50], ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 4, child: Text( 'TOTAL:', style: CourierStyles.big, ), ), Expanded( flex: 4, child: Text( _fmt(total), style: CourierStyles.big.copyWith(color: primaryColor), textAlign: TextAlign.right, ), ), ], ), ), ), const SizedBox(height: 8), // Payment Amount Display Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 4, child: Text( 'BAYAR:', style: CourierStyles.base .copyWith(color: Colors.grey[700]), ), ), Expanded( flex: 4, child: Text( paymentAmount > 0 ? _fmt(paymentAmount) : '0', style: CourierStyles.base .copyWith(color: Colors.grey[700]), textAlign: TextAlign.right, ), ), ], ), const SizedBox(height: 8), // Change Amount if (paymentAmount > 0) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 4, child: Text( 'KEMBALI:', style: CourierStyles.base.copyWith( color: hasSufficientPayment ? Colors.grey[700] : Colors.red, ), ), ), Expanded( flex: 4, child: Text( _fmt(changeAmount), style: CourierStyles.base.copyWith( color: hasSufficientPayment && changeAmount >= 0 ? Colors.green : Colors.red, ), textAlign: TextAlign.right, ), ), ], ), // Tip control: tampilkan hanya jika ada kembalian if (paymentAmount > total) Padding( padding: const EdgeInsets.only(top: 8), child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: hasTip ? Colors.orange[50] : Colors.grey[50], borderRadius: BorderRadius.circular(4), border: Border.all( color: hasTip ? Colors.orange : Colors.grey[300]!, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( 'SEBAGAI TIP:', style: CourierStyles.base .copyWith(color: Colors.grey[700]), ), ), if (hasTip) Text( CurrencyFormat.formatRupiah(state.tipAmount), style: CourierStyles.bold.copyWith( color: Colors.orange[800], fontSize: 13), ) else Text( 'Tidak', style: CourierStyles.base .copyWith(color: Colors.grey[600]), ), ], ), if (hasTip && state.tipSourceAccountName != null) Padding( padding: const EdgeInsets.only(top: 4), child: Text( 'Sumber: ${state.tipSourceAccountName}', style: CourierStyles.base.copyWith( fontSize: 12, color: Colors.orange[800], fontStyle: FontStyle.italic, ), ), ), const SizedBox(height: 6), Row( children: [ if (!hasTip) Expanded( child: ElevatedButton.icon( onPressed: onSetTip, icon: const Icon(Icons.volunteer_activism, size: 16), label: const Text('Jadikan Tip', style: TextStyle(fontSize: 12)), style: ElevatedButton.styleFrom( backgroundColor: Colors.orange, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4), ), ), ) else Expanded( child: OutlinedButton.icon( onPressed: onClearTip, icon: const Icon(Icons.close, size: 16), label: const Text('Batal Tip', style: TextStyle(fontSize: 12)), style: OutlinedButton.styleFrom( foregroundColor: Colors.red, padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4), ), ), ), ], ), if (!hasTip) Padding( padding: const EdgeInsets.only(top: 4), child: Text( 'Kembalian sebesar ${CurrencyFormat.formatRupiah(changeAmount)} bisa dijadikan tip ke akun sumber tertentu.', style: TextStyle( fontSize: 11, color: Colors.grey[600], fontStyle: FontStyle.italic, ), ), ), ], ), ), ), ], ), ), ); } }