import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/models/lakum_inquiry_information_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class LakumWalletDetails extends StatelessWidget { const LakumWalletDetails({super.key}); @override Widget build(BuildContext context) { AppState appState = getIt.get(); return CollapsingListView( title: LocaleKeys.lakumPoints.tr(context: context), child: Consumer( builder: (context, viewModel, child) { // Check if loading if (viewModel.isLakumAccountInfoLoading) { return Center( child: Padding( padding: EdgeInsets.all(32.w), child: CircularProgressIndicator( color: AppColors.primaryRedColor, ), ), ); } // Check if account number is not available if (viewModel.yahalaAccountNumber == "0" || viewModel.yahalaAccountNumber.isEmpty) { return Utils.getNoDataWidget(context); // return Center( // child: Padding( // padding: EdgeInsets.all(32.w), // child: LocaleKeys.lakumMsg.tr().toText14( // color: AppColors.greyTextColor, // ), // ), // ); } // Get all transactions List transactions = viewModel.getAllLakumTransactions(); // Display main UI return SingleChildScrollView( child: Padding( padding: EdgeInsets.all(16.w), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Main Lakum Card with gradient and user info _buildLakumMainCard(viewModel.lakumAccountInfo, appState), SizedBox(height: 24.h), // Redeem Button _buildRedeemButton(context), SizedBox(height: 24.h), // Transaction List Header Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.transactions.tr(context: context).toText16(isBold: true), // if (transactions.isNotEmpty) "${transactions.length} Records".toText12(color: AppColors.greyTextColor), ], ), SizedBox(height: 12.h), // Transaction List Container if (transactions.isEmpty) _buildEmptyTransactions() else _buildTransactionsList(transactions), SizedBox(height: 24.h), ], ), ), ); }, ), ); } Widget _buildLakumMainCard(LakumInquiryInformationResponseModel? accountInfo, AppState appState) { return Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [ AppColors.habibPharmacyColor, AppColors.habibPharmacyColor.withAlpha(220), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(24.r), boxShadow: [ BoxShadow( color: AppColors.habibPharmacyColor.withAlpha(76), blurRadius: 16, offset: Offset(0, 8), ), ], ), child: Padding( padding: EdgeInsets.all(20.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Top Row: User Info and Grid Icon Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "${appState.getAuthenticatedUser()?.firstName ?? ''} ${appState.getAuthenticatedUser()?.lastName ?? ''}".toText18( isBold: true, color: Colors.white, ), SizedBox(height: 4.h), (accountInfo?.accountNumber ?? 0).toString().toText14( color: Colors.white.withAlpha(230), ), ], ), ), Utils.buildImgWithAssets( icon: AppAssets.lakumLogoWhite, width: 110.h, height: 100.h, ), ], ), // SizedBox(height: 24.h), LocaleKeys.lakumPoints.tr().toText18(color: Colors.white.withAlpha(230), isBold: true), SizedBox(height: 8.h), // Points Balance Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ (accountInfo?.pointsBalance?.toString() ?? "0").toText44( isBold: true, color: Colors.white, ), SizedBox(width: 8.w), LocaleKeys.points .tr() .toText18( color: Colors.white.withAlpha(230), isBold: true, ) .paddingOnly(bottom: 8.h), ], ), SizedBox(height: 4.h), // Balance Amount in SAR "≈ ${accountInfo?.pointsBalanceAmount?.toStringAsFixed(2) ?? "0.00"} SAR".toText18( color: Colors.white.withAlpha(204), ), SizedBox(height: 20.h), // Stats Row Row( children: [ Expanded( child: _buildStatChip( LocaleKeys.gained.tr(), accountInfo?.gainedPoints?.toString() ?? "0", Icons.arrow_circle_up, ), ), SizedBox(width: 8.w), Expanded( child: _buildStatChip( LocaleKeys.consumed.tr(), accountInfo?.consumedPoints?.toString() ?? "0", Icons.arrow_circle_down, ), ), SizedBox(width: 8.w), Expanded( child: _buildStatChip( LocaleKeys.expired.tr(), accountInfo?.expiredPoints?.toString() ?? "0", Icons.calendar_month, isSvg: true ), ), ], ), ], ), ), ); } Widget _buildStatChip(String label, String value, IconData icon, {bool isSvg = false}) { return Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.h), decoration: BoxDecoration( color: Colors.white.withAlpha(51), borderRadius: BorderRadius.circular(12.r), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ isSvg ? Utils.buildSvgWithAssets(icon: AppAssets.expired_icon, width: 15.w, height: 15.h, applyThemeColor: false) : Icon(icon, color: Colors.white, size: 16.f), SizedBox(width: 6.w), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ value.toText14(color: Colors.white, isBold: true), label.toText10(color: Colors.white.withAlpha(204)), ], ), ], ), ); } Widget _buildRedeemButton(BuildContext context) { return CustomButton( height: 46.h, icon: AppAssets.redeem_icon, iconColor: AppColors.whiteColor, iconSize: 24.h, backgroundColor: AppColors.habibPharmacyColor, textColor: AppColors.whiteColor, text: LocaleKeys.redeem.tr(context: context), borderWidth: 0.w, fontWeight: FontWeight.w600, borderColor: AppColors.habibPharmacyColor.withAlpha(15), padding: EdgeInsets.fromLTRB(4, 0, 12, 0), fontSize: 14.f, onPressed: () { Uri uri = Uri.parse(ApiConsts.pharmacyRedirectUrl); launchUrl(uri, mode: LaunchMode.externalApplication); }, ); } Widget _buildEmptyTransactions() { return Container( padding: EdgeInsets.all(32.w), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 16.r, hasShadow: false, ), child: Center( child: Column( children: [ Icon(Icons.receipt_long_outlined, size: 48.f, color: AppColors.greyTextColor), SizedBox(height: 12.h), "No transactions found".toText14( color: AppColors.greyTextColor, isCenter: true, ), ], ), ), ); } Widget _buildTransactionsList(List transactions) { return Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 16.r, hasShadow: false, ), child: ListView.separated( padding: EdgeInsets.all(16.w), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: transactions.length, separatorBuilder: (context, index) => Divider( color: AppColors.dividerColor, height: 24.h, ), itemBuilder: (context, index) { return _buildTransactionItem(transactions[index]); }, ), ); } Widget _buildTransactionItem(PointsDetails transaction) { // Determine if points were gained or used bool isGained = transaction.subTransactionType == 1 || transaction.operationType?.toLowerCase() == 'cr' || (transaction.points ?? 0) > 0; Color transactionColor = isGained ? AppColors.habibPharmacyColor : AppColors.primaryRedColor; String pointsText = "${isGained ? '+' : '-'}${transaction.points?.abs() ?? 0}"; // Format date String formattedDate = ""; if (transaction.transactionDate != null) { try { formattedDate = DateUtil.formatDateToDate( DateUtil.convertStringToDate(transaction.transactionDate!), false, ); } catch (e) { formattedDate = transaction.transactionDate ?? ""; } } return Row( children: [ // Transaction Icon // Container( // width: 44.w, // height: 44.h, // decoration: BoxDecoration( // color: transactionColor.withAlpha(25), // borderRadius: BorderRadius.circular(12.r), // ), // child: Icon( // isGained ? Icons.add_rounded : Icons.remove_rounded, // color: transactionColor, // size: 24.f, // ), // ), // SizedBox(width: 12.w), // Transaction Details Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ (isGained ? LocaleKeys.earned.tr() : LocaleKeys.consumed.tr()).toText14( isBold: true, maxlines: 2, ), SizedBox(height: 2.h), formattedDate.toText12(color: AppColors.greyTextColor), ], ), ), // Points Value Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ pointsText.toText18( isBold: true, color: transactionColor, ), if (transaction.amount != null && transaction.amount! > 0) "${transaction.amount?.toStringAsFixed(2) ?? "0.00"} SAR".toText11( color: AppColors.greyTextColor, ), ], ), ], ); } } // Custom painter for wavy background pattern class _WavyBackgroundPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { // Base color from AppColors final baseColor = AppColors.habibPharmacyColor; final paint = Paint() ..color = Colors.white.withAlpha(25) ..style = PaintingStyle.fill; // Draw multiple wave patterns final path1 = Path(); path1.moveTo(0, size.height * 0.3); path1.quadraticBezierTo( size.width * 0.25, size.height * 0.2, size.width * 0.5, size.height * 0.3, ); path1.quadraticBezierTo( size.width * 0.75, size.height * 0.4, size.width, size.height * 0.3, ); path1.lineTo(size.width, 0); path1.lineTo(0, 0); path1.close(); canvas.drawPath(path1, paint); // Second wave with darker shade paint.color = Colors.black.withAlpha(15); final path2 = Path(); path2.moveTo(0, size.height * 0.6); path2.quadraticBezierTo( size.width * 0.3, size.height * 0.5, size.width * 0.6, size.height * 0.6, ); path2.quadraticBezierTo( size.width * 0.8, size.height * 0.7, size.width, size.height * 0.6, ); path2.lineTo(size.width, size.height); path2.lineTo(0, size.height); path2.close(); canvas.drawPath(path2, paint); // Decorative circles with white overlay paint.color = Colors.white.withAlpha(20); canvas.drawCircle(Offset(size.width * 0.85, size.height * 0.15), 30, paint); paint.color = Colors.white.withAlpha(10); canvas.drawCircle(Offset(size.width * 0.15, size.height * 0.75), 40, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }