import 'package:business_panel/core/config/app_colors.dart'; import 'package:business_panel/domain/entities/discount_entity.dart'; import 'package:business_panel/gen/assets.gen.dart'; import 'package:business_panel/presentation/discount_management/bloc/discount_management_bloc.dart'; import 'package:business_panel/presentation/pages/add_discount_page.dart'; import 'package:business_panel/presentation/pages/sales_analysis_page.dart'; import 'package:business_panel/presentation/widgets/delete_confirmation_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:persian_datetime_picker/persian_datetime_picker.dart'; import 'package:slide_countdown/slide_countdown.dart'; class AnalyticsDiscountCard extends StatelessWidget { final DiscountEntity discount; const AnalyticsDiscountCard({super.key, required this.discount}); @override Widget build(BuildContext context) { final remaining = discount.endDate != null ? discount.endDate!.difference(DateTime.now()) : const Duration(seconds: -1); final bool isExpired = remaining.isNegative; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (!isExpired) _buildActionButtons(context), const SizedBox( height: 5, ), Card( color: Colors.white, elevation: 0, margin: const EdgeInsets.symmetric(vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), side: BorderSide(color: Colors.grey.shade300, width: 1), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildProductImage(), const SizedBox(width: 16), _buildCardDetails(context, remaining), ], ), ), ), ], ); } Widget _buildProductImage() { return ClipRRect( borderRadius: BorderRadius.circular(15), child: (discount.images.isNotEmpty && discount.images.first.isNotEmpty) ? Image.network( discount.images.first, width: 100, height: 100, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) => _buildImagePlaceholder(), ) : _buildImagePlaceholder(), ); } Widget _buildImagePlaceholder() { return Container( width: 100, height: 100, decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.circular(15), ), child: const Icon(Icons.store, color: Colors.grey, size: 50), ); } Widget _buildCardDetails(BuildContext context, Duration remaining) { return Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox(height: 5), _buildInfoRow( icon: Assets.icons.shoppingCart, text: discount.name, textColor: Colors.grey.shade600), const SizedBox(height: 5), if (discount.endDate == null) _buildStatusText('تاریخ نامعتبر', Colors.orange) else if (remaining.isNegative) _buildExpiredDateRange() else _buildCountdownSection(remaining), const SizedBox(height: 10), InkWell( onTap: () { Navigator.of(context).push( MaterialPageRoute( builder: (_) => SalesAnalysisPage(discount: discount), ), ); }, child: _buildInfoRow( icon: Assets.icons.chart, text: "آنالیز فروش", textColor: AppColors.active, isBold: true, ), ), ], ), ); } Widget _buildInfoRow( {required String icon, required String text, Color? textColor, bool isBold = false}) { return Row( children: [ SvgPicture.asset(icon, width: 18, color: Colors.grey.shade700), const SizedBox(width: 10), Expanded( child: Text( text, style: TextStyle( fontSize: 17, color: textColor ?? Colors.black, fontWeight: FontWeight.normal, ), overflow: TextOverflow.ellipsis, ), ), ], ); } Widget _buildStatusText(String text, Color color) { return Text( text, style: TextStyle(color: color, fontWeight: FontWeight.bold), ); } Widget _buildExpiredDateRange() { final jalaliStart = Jalali.fromDateTime(discount.startDate!); final jalaliEnd = Jalali.fromDateTime(discount.endDate!); final formattedDateRange = '${jalaliStart.day} ${jalaliStart.formatter.mN} تا ${jalaliEnd.day} ${jalaliEnd.formatter.mN} ${jalaliEnd.year}'; return Row( children: [ SvgPicture.asset(Assets.icons.clunder, width: 18, color: Colors.grey.shade700), const SizedBox(width: 10), Expanded( child: Text( formattedDateRange, style: const TextStyle( color: AppColors.secTitle, fontWeight: FontWeight.normal, fontSize: 14, ), overflow: TextOverflow.ellipsis, ), ), ], ); } Widget _buildCountdownSection(Duration remaining) { return Row( children: [ SvgPicture.asset(Assets.icons.timerPause, width: 18, color: Colors.grey.shade700), const SizedBox(width: 5), Expanded(child: _buildCountdownTimer(remaining)), ], ); } Widget _buildActionButtons(BuildContext context) { return Padding( padding: const EdgeInsets.only(right: 8), child: Row( children: [ InkWell( onTap: () => _showDeleteConfirmation(context), borderRadius: BorderRadius.circular(8), child: Container( padding: const EdgeInsets.symmetric(vertical: 8.0), decoration: BoxDecoration( color: AppColors.backDelete, borderRadius: BorderRadius.circular(8), border: Border.all(color: AppColors.expiryReserve)), child: Padding( padding: const EdgeInsets.fromLTRB(15, 0, 15, 0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset(Assets.icons.trash, width: 20, color: AppColors.expiryReserve), const SizedBox(width: 5), const Text("حذف", style: TextStyle( color: AppColors.expiryReserve, fontWeight: FontWeight.bold)), ], ), ), ), ), const SizedBox(width: 15), InkWell( onTap: () { Navigator.of(context) .push( MaterialPageRoute( builder: (_) => AddDiscountPage(discountId: discount.id), ), ) .then((value) { if (value == true) { final bloc = context.read(); bloc.add( FetchManagedDiscounts(status: 1)); } }); }, borderRadius: BorderRadius.circular(8), child: Container( padding: const EdgeInsets.symmetric(vertical: 8.0), decoration: BoxDecoration( color: AppColors.backEdit, borderRadius: BorderRadius.circular(8), border: Border.all(color: AppColors.selectedImg)), child: Padding( padding: const EdgeInsets.fromLTRB(15, 0, 15, 0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset(Assets.icons.edit, width: 20, color: AppColors.selectedImg), const SizedBox(width: 5), const Text("ویرایش", style: TextStyle( color: AppColors.selectedImg, fontWeight: FontWeight.bold)), ], ), ), ), ), ], ), ); } void _showDeleteConfirmation(BuildContext context) { showDeleteConfirmationDialog( context, title: 'حذف تخفیف', content: 'با حذف این تخفیف، رزروهای احتمالی هم غیرفعال می‌شن و دیگه برای مشتری‌ها نمایش داده نمی‌شه.', onConfirm: () { context .read() .add(DeleteDiscount(discount.id)); }, ); } Widget _buildCountdownTimer(Duration remaining) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Directionality( textDirection: TextDirection.ltr, child: SlideCountdown( duration: remaining, slideDirection: SlideDirection.up, separator: ':', style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: AppColors.countdown), separatorStyle: const TextStyle(fontSize: 15, color: AppColors.countdown), decoration: const BoxDecoration(color: Colors.transparent), shouldShowDays: (d) => d.inDays > 0, shouldShowHours: (d) => true, shouldShowMinutes: (d) => true, ), ), const SizedBox(height: 4), _buildTimerLabels(remaining), ], ); } Widget _buildTimerLabels(Duration duration) { const labelStyle = TextStyle(fontSize: 9, color: AppColors.selectedImg); List labels = []; if (duration.inDays > 0) { labels.add(const SizedBox(width: 30, child: Text("روز", style: labelStyle))); } if (duration.inHours > 0 || duration.inDays > 0) { labels .add(const SizedBox(width: 35, child: Text("ساعت", style: labelStyle))); } labels .add(const SizedBox(width: 35, child: Text("دقیقه", style: labelStyle))); labels .add(const SizedBox(width: 35, child: Text(" ثانیه", style: labelStyle))); return Row( mainAxisAlignment: MainAxisAlignment.start, children: labels.reversed.toList(), ); } }