import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../application/void/void_form/void_form_bloc.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; import '../../../../common/types/void_type.dart'; import '../../../components/button/button.dart'; import '../../../components/dialog/order/order_void_confirm_dialog.dart'; import '../../../components/field/field.dart'; import '../../../components/spaces/space.dart'; import 'void_radio.dart'; class VoidRightPanel extends StatefulWidget { final VoidFormState state; const VoidRightPanel({super.key, required this.state}); @override State createState() => _VoidRightPanelState(); } class _VoidRightPanelState extends State { final ScrollController _scrollController = ScrollController(); @override void dispose() { super.dispose(); _scrollController.dispose(); } @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( border: Border( bottom: BorderSide(width: 1, color: AppColor.border), ), borderRadius: BorderRadius.only( topLeft: Radius.circular(12), topRight: Radius.circular(12), ), ), child: Row( children: [ Text( 'Konfigurasi Void', style: AppStyle.xxl.copyWith( fontWeight: FontWeight.bold, color: AppColor.primary, ), ), ], ), ), Expanded( child: Scrollbar( controller: _scrollController, thumbVisibility: true, child: SingleChildScrollView( controller: _scrollController, padding: EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Tipe Void *', style: AppStyle.lg.copyWith( fontWeight: FontWeight.bold, color: AppColor.primary, ), ), SpaceHeight(12), VoidRadio( voidType: widget.state.voidType, value: VoidType.all, title: 'Batalkan Seluruh Pesanan', subtitle: "Batalkan pesanan lengkap dan semua item", onChanged: (VoidType? value) { context.read().add( VoidFormEvent.clearSelectedItem(), ); context.read().add( VoidFormEvent.voidTypeChanged(value!), ); }, ), SpaceHeight(12), VoidRadio( voidType: widget.state.voidType, value: VoidType.item, title: 'Batalkan Barang/Jumlah Tertentu', subtitle: "Mengurangi atau membatalkan jumlah item tertentu", onChanged: (VoidType? value) { context.read().add( VoidFormEvent.voidTypeChanged(value!), ); }, ), SpaceHeight(24), // Selected Items Summary (only show for item void) if (widget.state.voidType.isItem) ...[ Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( color: widget.state.selectedItemQuantities.isEmpty ? AppColor.warning.withOpacity(0.1) : AppColor.success.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all( color: widget.state.selectedItemQuantities.isEmpty ? AppColor.warning.withOpacity(0.6) : AppColor.success.withOpacity(0.6), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( widget.state.selectedItemQuantities.isEmpty ? Icons.warning : Icons.check_circle, color: widget .state .selectedItemQuantities .isEmpty ? AppColor.warning : AppColor.success, size: 20, ), SpaceWidth(8), Expanded( child: Text( widget.state.selectedItemQuantities.isEmpty ? 'Silakan pilih item dan jumlah yang akan dibatalkan' : 'Item yang dipilih untuk dibatalkan:', style: AppStyle.md.copyWith( fontWeight: FontWeight.w500, color: widget .state .selectedItemQuantities .isEmpty ? AppColor.warning : AppColor.success, ), ), ), ], ), if (widget .state .selectedItemQuantities .isNotEmpty) ...[ SpaceHeight(12), Container( constraints: BoxConstraints(maxHeight: 150), child: Scrollbar( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: widget .state .selectedItemQuantities .entries .map((entry) { final item = widget .state .order .orderItems .firstWhere( (item) => item.id == entry.key, ); return Container( margin: EdgeInsets.only( bottom: 8, ), padding: EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(6), border: Border.all( color: AppColor.success, ), ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ Text( item.productName, style: AppStyle.sm .copyWith( fontWeight: FontWeight .w500, ), ), Text( 'Qty: ${entry.value}', style: AppStyle.xs .copyWith( color: AppColor .textSecondary, ), ), ], ), ), Text( ((item.unitPrice) * entry.value) .currencyFormatRpV2, style: AppStyle.xs.copyWith( fontWeight: FontWeight.bold, color: AppColor.error, ), ), ], ), ); }) .toList(), ), ), ), ), Divider(height: 16, thickness: 1), Container( padding: EdgeInsets.all(8), decoration: BoxDecoration( color: AppColor.error, borderRadius: BorderRadius.circular(6), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Jumlah Total Void:', style: AppStyle.md.copyWith( fontWeight: FontWeight.bold, color: Colors.white, ), ), Text( widget .state .totalPriceVoid .currencyFormatRpV2, style: AppStyle.md.copyWith( fontWeight: FontWeight.bold, color: Colors.white, ), ), ], ), ), ], ], ), ), SpaceHeight(24), ], Text( 'Alasan Void *', style: AppStyle.lg.copyWith( fontWeight: FontWeight.bold, color: AppColor.primary, ), ), SpaceHeight(8), AppTextFormField( label: 'Harap berikan alasan untuk membatalkan...', showLabel: false, maxLines: 4, onChanged: (value) { context.read().add( VoidFormEvent.voidReasonChanged(value), ); }, ), SpaceHeight(32), ], ), ), ), ), // Action Buttons Padding( padding: EdgeInsets.all(20), child: Row( children: [ Expanded( child: AppElevatedButton.outlined( onPressed: () => context.router.maybePop(), label: 'Batal', ), ), SpaceWidth(12), Expanded( child: AppElevatedButton.filled( onPressed: _canProcessVoid() ? _processVoid : null, label: widget.state.voidType.isAll ? 'Void Pesanan' : 'Void Produk', ), ), ], ), ), ], ), ); } bool _canProcessVoid() { if (widget.state.voidReason?.isEmpty ?? true) return false; if (widget.state.voidType.isItem && widget.state.selectedItemQuantities.isEmpty) { return false; } return true; } void _processVoid() { String confirmMessage; if (widget.state.voidType.isAll) { confirmMessage = 'Apakah Anda yakin ingin membatalkan seluruh pesanan #${widget.state.order.orderNumber}?\n\nIni akan membatalkan semua item dalam pesanan.'; } else { int totalItems = widget.state.selectedItemQuantities.values.fold( 0, (sum, qty) => sum + qty, ); confirmMessage = 'Apakah Anda yakin ingin membatalkan $totalItems item dari pesanan #${widget.state.order.orderNumber}?\n\nJumlah Batal: ${widget.state.totalPriceVoid.currencyFormatRpV2}'; } showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return OrderVoidConfirmDialog(message: confirmMessage); }, ); } }