import 'dart:developer'; import 'package:enaklo_pos/core/components/buttons.dart'; import 'package:enaklo_pos/core/components/custom_modal_dialog.dart'; import 'package:enaklo_pos/core/components/flushbar.dart'; import 'package:enaklo_pos/core/components/spaces.dart'; import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/extensions/build_context_ext.dart'; import 'package:enaklo_pos/core/extensions/int_ext.dart'; import 'package:enaklo_pos/core/extensions/string_ext.dart'; import 'package:enaklo_pos/data/models/request/payment_request.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart'; import 'package:enaklo_pos/data/models/response/payment_methods_response_model.dart'; import 'package:enaklo_pos/presentation/home/bloc/payment_methods/payment_methods_bloc.dart'; import 'package:enaklo_pos/presentation/sales/blocs/payment_form/payment_form_bloc.dart'; import 'package:enaklo_pos/presentation/success/pages/success_payment_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class PaymentDialog extends StatefulWidget { final Order order; const PaymentDialog({super.key, required this.order}); @override State createState() => _PaymentDialogState(); } class _PaymentDialogState extends State { PaymentMethod? selectedPaymentMethod; final totalPriceController = TextEditingController(); int priceValue = 0; int uangPas = 0; int uangPas2 = 0; int uangPas3 = 0; init() { setState(() { uangPas = widget.order.totalAmount ?? 0; uangPas2 = 50000; uangPas3 = 100000; }); } @override void initState() { super.initState(); context .read() .add(PaymentMethodsEvent.fetchPaymentMethods()); init(); } @override void dispose() { super.dispose(); totalPriceController.dispose(); } @override Widget build(BuildContext context) { return CustomModalDialog( title: 'Pembayaran', subtitle: 'Silahkan lakukan pembayaran', child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: AppColors.grey, ), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Metode Pembayaran', style: TextStyle( color: AppColors.black, fontSize: 16, fontWeight: FontWeight.w600, ), ), const SpaceHeight(12.0), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('No. Pesanan'), Text( widget.order.orderNumber ?? "", style: const TextStyle(fontWeight: FontWeight.bold), ), ], ), const SpaceHeight(6), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Tagihan'), Text( (widget.order.totalAmount ?? 0).currencyFormatRpV2, style: const TextStyle(fontWeight: FontWeight.bold), ), ], ), ], ), ), Container( padding: const EdgeInsets.all(16), width: double.infinity, decoration: BoxDecoration( border: Border( bottom: BorderSide( color: AppColors.grey, width: 1.0, ), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Metode Pembayaran', style: TextStyle( color: AppColors.black, fontSize: 16, fontWeight: FontWeight.w600, ), ), const SpaceHeight(12.0), BlocBuilder( builder: (context, state) { return state.maybeWhen( orElse: () => const Center( child: CircularProgressIndicator(), ), loading: () => const Center( child: Column( children: [ CircularProgressIndicator(), SizedBox(height: 8.0), Text('Loading payment methods...'), ], ), ), error: (message) => Column( children: [ Center( child: Text('Error loading payment methods: $message'), ), const SpaceHeight(16.0), Button.filled( onPressed: () { context.read().add( PaymentMethodsEvent.fetchPaymentMethods()); }, label: 'Retry', ), ], ), loaded: (paymentMethods) { log("Loaded ${paymentMethods.length} payment methods"); paymentMethods.forEach((method) { log("Payment method: ${method.name} (ID: ${method.id})"); }); if (paymentMethods.isEmpty) { return Column( children: [ const Center( child: Text('No payment methods available'), ), const SpaceHeight(16.0), Button.filled( onPressed: () { context.read().add( PaymentMethodsEvent .fetchPaymentMethods()); }, label: 'Retry', ), ], ); } // Set default selected payment method if none selected or if current selection is not in the list if (selectedPaymentMethod == null || !paymentMethods.any((method) => method.id == selectedPaymentMethod?.id)) { selectedPaymentMethod = paymentMethods.first; } return Wrap( spacing: 12.0, runSpacing: 8.0, children: paymentMethods.map((method) { final isSelected = selectedPaymentMethod?.id == method.id; return GestureDetector( onTap: () { setState(() { selectedPaymentMethod = method; }); }, child: Container( height: 60, width: 80, alignment: Alignment.center, padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( color: isSelected ? AppColors.primary : AppColors.white, border: Border.all( color: AppColors.primary, width: 1.0, ), borderRadius: BorderRadius.circular(8.0), ), child: Text( method.name ?? "", style: TextStyle( color: isSelected ? AppColors.white : AppColors.primary, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), ), ); }).toList(), ); }, ); }, ), ], ), ), if (selectedPaymentMethod?.type == "cash") Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: AppColors.grey, width: 1.0, ), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Total Bayar', style: TextStyle( color: AppColors.black, fontSize: 16, fontWeight: FontWeight.w600, ), ), const SpaceHeight(8.0), TextFormField( controller: totalPriceController, keyboardType: TextInputType.number, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), ), hintText: 'Total harga', ), onChanged: (value) { priceValue = value.toIntegerFromText; final int newValue = value.toIntegerFromText; totalPriceController.text = newValue.currencyFormatRp; totalPriceController.selection = TextSelection.fromPosition(TextPosition( offset: totalPriceController.text.length)); }, ), const SpaceHeight(20.0), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ Button.outlined( width: 150.0, onPressed: () { totalPriceController.text = uangPas.toString().currencyFormatRpV2; priceValue = uangPas; }, label: 'UANG PAS', ), const SpaceWidth(20.0), Button.outlined( width: 150.0, onPressed: () { totalPriceController.text = uangPas2.toString().currencyFormatRpV2; priceValue = uangPas2; }, label: uangPas2.toString().currencyFormatRpV2, ), const SpaceWidth(20.0), Button.outlined( width: 150.0, onPressed: () { totalPriceController.text = uangPas3.toString().currencyFormatRpV2; priceValue = uangPas3; }, label: uangPas3.toString().currencyFormatRpV2, ), ], ), ), ], ), ), Padding( padding: const EdgeInsets.symmetric( vertical: 24, horizontal: 16, ), child: BlocListener( listener: (context, state) { state.maybeWhen( orElse: () {}, success: (data) { context.pushReplacement(SuccessPaymentPage( payment: data, )); }, error: (message) { AppFlushbar.showError(context, message); }, ); }, child: BlocBuilder( builder: (context, state) { return state.maybeWhen( orElse: () => Button.filled( onPressed: () { if (selectedPaymentMethod == null) { AppFlushbar.showError(context, 'Pilih metode pembayaran terlebih dahulu'); return; } if (selectedPaymentMethod?.type == "cash") { if (priceValue == 0) { AppFlushbar.showError( context, 'Total bayar tidak boleh 0'); return; } } final request = PaymentRequestModel( amount: widget.order.totalAmount ?? 0, orderId: widget.order.id, paymentMethodId: selectedPaymentMethod?.id, splitDescription: '', splitNumber: 1, splitTotal: 1, transactionId: '', paymentOrderItems: widget.order.orderItems ?.map((item) => PaymentOrderItemModel( orderItemId: item.id, amount: item.totalPrice, )) .toList()); context .read() .add(PaymentFormEvent.create(request)); }, label: 'Bayar', ), loading: () => Center( child: const CircularProgressIndicator(), ), ); }, ), ), ), ], ), ); } }