import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_retailer_model.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:shimmer/shimmer.dart'; import 'package:url_launcher/url_launcher.dart'; class WalaPlusRetailerDetailsScreen extends StatefulWidget { final WalaPlusRetailerModel? retailer; final String? retailerId; const WalaPlusRetailerDetailsScreen({ Key? key, this.retailer, this.retailerId, }) : super(key: key); @override State createState() => _WalaPlusRetailerDetailsScreenState(); } class _WalaPlusRetailerDetailsScreenState extends State { WalaPlusRetailerModel? _retailer; bool _isLoading = false; String? _effectiveRetailerId; @override void initState() { super.initState(); _retailer = widget.retailer; _effectiveRetailerId = widget.retailerId ?? widget.retailer?.id; } @override void didChangeDependencies() { super.didChangeDependencies(); if (_retailer == null && _effectiveRetailerId == null) { Object? args = ModalRoute.of(context)?.settings.arguments; if (args is WalaPlusRetailerModel) { _retailer = args; _effectiveRetailerId = args.id; } else if (args is String) { _effectiveRetailerId = args; } } if (_retailer == null && _effectiveRetailerId != null && !_isLoading) { _fetchRetailerDetails(); } } Future _fetchRetailerDetails() async { if (_effectiveRetailerId == null) return; setState(() { _isLoading = true; }); try { WalaPlusRetailerModel? result = await OffersAndDiscountsApiClient().getWalaPlusRetailerById( retailerId: _effectiveRetailerId!, context: context, ); if (result != null && mounted) { setState(() { _retailer = result; }); } } catch (e) { debugPrint("Error fetching WalaPlus retailer by ID: $e"); } finally { if (mounted) { setState(() { _isLoading = false; }); } } } void _onUseOffer() async { String? website = _retailer?.resolvedWebsite; if (website != null && website.isNotEmpty) { try { Uri uri = Uri.parse(website); if (!uri.hasScheme) { uri = Uri.parse("https://$website"); } await launchUrl(uri, mode: LaunchMode.externalApplication); return; } catch (e) { debugPrint("Error launching website: $e"); } } // If promo pin exists, display a dialog with the promo code to copy if (_retailer?.pin != null && _retailer!.pin!.isNotEmpty) { _showPromoCodeDialog(_retailer!.pin!); return; } // Otherwise show terms/usage dialog _showTermsDialog(); } void _showPromoCodeDialog(String pin) { bool isAr = AppState().isArabic(context); showDialog( context: context, builder: (cxt) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), title: Text( isAr ? "كود الخصم" : "Promo Code", style: const TextStyle(fontWeight: FontWeight.bold), ), content: Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: const Color(0xFFF3F4F6), borderRadius: BorderRadius.circular(10), border: Border.all(color: const Color(0xFF20A4A8), width: 1.2), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( pin, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, letterSpacing: 2, color: Color(0xFF1E293B), ), ), IconButton( icon: const Icon(Icons.copy_rounded, color: Color(0xFF20A4A8)), onPressed: () { Clipboard.setData(ClipboardData(text: pin)); Navigator.pop(cxt); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(isAr ? "تم نسخ الكود بنجاح" : "Promo code copied"), duration: const Duration(seconds: 2), ), ); }, ), ], ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(cxt), child: Text(isAr ? "إغلاق" : "Close", style: const TextStyle(color: Color(0xFF20A4A8))), ), ], ), ); } void _showTermsDialog() { bool isAr = AppState().isArabic(context); String content = _retailer?.howToUse ?? _retailer?.arHowToUse ?? _retailer?.enHowToUse ?? _retailer?.usage?.toString() ?? (isAr ? "تطبق الشروط والأحكام الخاصة بالعرض." : "Terms and conditions apply for this offer."); // Clean html tags if simple content = content.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ').trim(); showModalBottomSheet( context: context, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), builder: (cxt) => SafeArea( child: Padding( padding: const EdgeInsets.all(20.0), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( isAr ? "الشروط والأحكام" : "Terms and Conditions", style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1E293B), ), ), IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.pop(cxt), ), ], ), const SizedBox(height: 12), Text( content, style: const TextStyle(fontSize: 14, color: Color(0xFF4B5563), height: 1.5), ), const SizedBox(height: 20), ], ), ), ), ); } @override Widget build(BuildContext context) { bool isAr = AppState().isArabic(context); String title = _retailer?.name ?? (isAr ? "تفاصيل العرض" : "Offer Details"); return Scaffold( backgroundColor: const Color(0xFFF8F9FA), appBar: AppBarWidget( context, title: title, showHomeButton: true, onHomeTapped: () { if (ApiConsts.isDependetLogin) { Navigator.popUntil(context, ModalRoute.withName(AppRoutes.dashboardScreenForDependet)); } else { Navigator.popUntil(context, ModalRoute.withName(AppRoutes.dashboard)); } }, ), body: _isLoading && _retailer == null ? _buildLoadingSkeleton() : Column( children: [ Expanded( child: SingleChildScrollView( physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(22), border: Border.all(color: const Color(0xFFF1F5F9), width: 1.2), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 12, offset: const Offset(0, 4), ), ], ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 1. Top Banner Image with rounded corners ClipRRect( borderRadius: BorderRadius.circular(16), child: SizedBox( height: 190, width: double.infinity, child: (_retailer?.image != null && _retailer!.image!.isNotEmpty) ? Image.network( _retailer!.image!, fit: BoxFit.cover, errorBuilder: (_, __, ___) => Container( color: const Color(0xFFF3F4F6), child: const Icon(Icons.broken_image, size: 48, color: Color(0xFF9CA3AF)), ), ) : Container( color: const Color(0xFFF3F4F6), child: const Icon(Icons.image_outlined, size: 48, color: Color(0xFF9CA3AF)), ), ), ), 14.height, // 2. Brand Strip (Human Resources - Retailer Logo - Dr Sulaiman Al Habib) _buildBrandStrip(isAr), 18.height, // 3. Retailer Name (Centered, Bold) Center( child: Text( _retailer?.name ?? "", textAlign: TextAlign.center, style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Color(0xFF1E293B), ), ), ), 18.height, // 4. 3 Info Badges Row (Store Type, Validity, City) _buildInfoBadgesRow(isAr), 22.height, // 5. Description Section Text( isAr ? "الوصف:" : "description:", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Color(0xFF1E293B), ), ), 8.height, Text( _getCleanDescription(), style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF4B5563), height: 1.45, ), ), 16.height, // 6. Terms and Conditions Link (Right aligned) Align( alignment: isAr ? Alignment.centerLeft : Alignment.centerRight, child: InkWell( onTap: _showTermsDialog, child: Text( isAr ? "الشروط والأحكام" : "terms and conditions", style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFF20A4A8), decoration: TextDecoration.underline, ), ), ), ), ], ), ), ), ), // 7. Bottom Action Button Container( padding: const EdgeInsets.fromLTRB(16, 10, 16, 20), color: Colors.white, child: SizedBox( width: double.infinity, height: 50, child: ElevatedButton( onPressed: _onUseOffer, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF20A4A8), foregroundColor: Colors.white, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: Text( isAr ? "استخدام العرض" : "Use Offer", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w700, color: Colors.white, ), ), ), ), ), ], ), ); } Widget _buildBrandStrip(bool isAr) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ // Left: Human Resources branding Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: const [ Text( "الموارد البشرية", style: TextStyle( color: Color(0xFFED1C2B), fontSize: 10, fontWeight: FontWeight.w700, ), ), Text( "Human Resources", style: TextStyle( color: Color(0xFFED1C2B), fontSize: 8.5, fontWeight: FontWeight.w600, ), ), ], ), // Center: Retailer Logo if (_retailer?.logo != null && _retailer!.logo!.isNotEmpty) Image.network( _retailer!.logo!, height: 36, width: 36, fit: BoxFit.contain, errorBuilder: (_, __, ___) => const SizedBox(width: 36, height: 36), ) else const SizedBox(width: 36, height: 36), // Right: Dr Sulaiman Al Habib branding with red cross Row( mainAxisSize: MainAxisSize.min, children: [ Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: const [ Text( "سليمان الحبيب", style: TextStyle( color: Color(0xFF4B5563), fontSize: 9, fontWeight: FontWeight.w700, ), ), Text( "DR SULAIMAN AL HABIB", style: TextStyle( color: Color(0xFF4B5563), fontSize: 8, fontWeight: FontWeight.w600, ), ), ], ), const SizedBox(width: 5), SvgPicture.asset( "assets/icons/mazaya_brand.svg", height: 22, fit: BoxFit.contain, ), ], ), ], ); } Widget _buildInfoBadgesRow(bool isAr) { String storeTypeText = (_retailer?.type?.toLowerCase() == 'online') ? (isAr ? "عبر الإنترنت" : "online") : (isAr ? "في المتجر" : "in store"); IconData storeIcon = (_retailer?.type?.toLowerCase() == 'online') ? Icons.language_rounded : Icons.storefront_rounded; String cityText = _retailer?.displayCity ?? ""; if (cityText.isEmpty) { cityText = isAr ? "الرياض" : "Riyadh"; } String validityText = isAr ? "٣ أشهر" : "3 Month"; return Row( children: [ Expanded( child: _buildInfoCard( icon: storeIcon, label: storeTypeText, ), ), 12.width, Expanded( child: _buildInfoCard( icon: Icons.check_circle_outline_rounded, label: validityText, ), ), 12.width, Expanded( child: _buildInfoCard( icon: Icons.location_on_rounded, label: cityText, ), ), ], ); } Widget _buildInfoCard({required IconData icon, required String label}) { return Container( padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 8), decoration: BoxDecoration( color: const Color(0xFFF4F6F9), borderRadius: BorderRadius.circular(14), ), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: const Color(0xFF20A4A8), size: 26), const SizedBox(height: 8), Text( label, textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF334155), ), ), ], ), ); } String _getCleanDescription() { String desc = _retailer?.description ?? _retailer?.info ?? _retailer?.offerTitle ?? ""; if (desc.isEmpty) { return AppState().isArabic(context) ? "لا توجد تفاصيل إضافية متاحة." : "No additional details available."; } // Remove HTML tags if string contains them return desc.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ').trim(); } Widget _buildLoadingSkeleton() { return Shimmer.fromColors( baseColor: const Color(0xFFE2E8F0), highlightColor: const Color(0xFFF8FAFC), child: Padding( padding: const EdgeInsets.all(16.0), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(22), ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 190, width: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), ), const SizedBox(height: 16), Center( child: Container( height: 24, width: 160, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(6), ), ), ), const SizedBox(height: 20), Row( children: List.generate( 3, (index) => Expanded( child: Container( height: 75, margin: EdgeInsets.symmetric(horizontal: index == 1 ? 8 : 0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14), ), ), ), ), ), const SizedBox(height: 24), Container( height: 16, width: 100, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), ), ), const SizedBox(height: 10), Container( height: 14, width: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), ), ), const SizedBox(height: 6), Container( height: 14, width: 220, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), ), ), ], ), ), ), ); } }