import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:get/get.dart'; import 'package:wordpress/providers/api_controller.dart'; import 'package:wordpress/utils/ftaf.dart'; import 'package:wordpress/viewmodel/cart_screen.dart'; // Providers final selectedColorProvider = StateProvider((ref) => null); final selectedWeightProvider = StateProvider((ref) => null); final quantityProvider = StateProvider((ref) => 1); final currentImageIndexProvider = StateProvider((ref) => 0); final isFavoriteProvider = StateProvider((ref) => false); class BigBasketDetailsScreen extends ConsumerWidget { final int productId; const BigBasketDetailsScreen({super.key, required this.productId}); @override Widget build(BuildContext context, WidgetRef ref) { final detailAsync = ref.watch(productDetailProvider(productId)); final selectedColor = ref.watch(selectedColorProvider); final selectedWeight = ref.watch(selectedWeightProvider); final quantity = ref.watch(quantityProvider); final currentImageIndex = ref.watch(currentImageIndexProvider); final isFavorite = ref.watch(isFavoriteProvider); return Scaffold( backgroundColor: Colors.grey[50], body: detailAsync.when( data: (product) { final images = product.images ?? []; String? mainImage = images.isNotEmpty ? images.first.src : null; // Update main image based on selected color if (selectedColor != null && images.isNotEmpty) { final match = images.firstWhere( (img) => (img.name != null && img.name!.toLowerCase() == selectedColor.toLowerCase()) || (img.alt != null && img.alt!.toLowerCase() == selectedColor.toLowerCase()), orElse: () => images.first, ); mainImage = match.src ?? mainImage; } return CustomScrollView( slivers: [ // Custom App Bar with image SliverAppBar( expandedHeight: 350, pinned: true, backgroundColor: Colors.white, elevation: 0, leading: Container( margin: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.9), borderRadius: BorderRadius.circular(8), ), child: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.black), onPressed: () => Navigator.pop(context), ), ), actions: [ Container( margin: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.9), borderRadius: BorderRadius.circular(8), ), child: IconButton( icon: Icon( isFavorite ? Icons.favorite : Icons.favorite_border, color: isFavorite ? Colors.red : Colors.black, ), onPressed: () { ref.read(isFavoriteProvider.notifier).state = !isFavorite; }, ), ), Container( margin: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.9), borderRadius: BorderRadius.circular(8), ), child: IconButton( icon: const Icon(Icons.share, color: Colors.black), onPressed: () { // Share functionality }, ), ), ], flexibleSpace: FlexibleSpaceBar( background: Container( color: Colors.white, child: images.isNotEmpty ? PageView.builder( itemCount: images.length, onPageChanged: (index) { ref .read(currentImageIndexProvider.notifier) .state = index; }, itemBuilder: (context, index) { return Container( margin: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.grey[100], ), child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Image.network( images[index].src ?? '', fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { return Container( color: Colors.grey[200], child: const Center( child: Icon( Icons.image_not_supported, size: 80, color: Colors.grey, ), ), ); }, ), ), ); }, ) : Container( margin: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.grey[200], ), child: const Center( child: Icon( Icons.image_not_supported, size: 100, color: Colors.grey, ), ), ), ), ), ), // Product Content SliverToBoxAdapter( child: Container( color: Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Image indicators if (images.length > 1) Container( padding: const EdgeInsets.symmetric(vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate( images.length, (index) => Container( margin: const EdgeInsets.symmetric( horizontal: 4, ), width: 8, height: 8, decoration: BoxDecoration( shape: BoxShape.circle, color: currentImageIndex == index ? Colors.green[600] : Colors.grey[300], ), ), ), ), ), const SizedBox(height: 16), // Product Title & Brand Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( product.name ?? "Product Name", style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87, ), ), Text( 'Price : ₹ ${product.price.toString()}', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ], ), const SizedBox(height: 8), Row( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: Colors.green[50], borderRadius: BorderRadius.circular(4), border: Border.all( color: Colors.green[200]!, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.star, size: 14, color: Colors.green[600], ), const SizedBox(width: 4), Text( "4.2", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Colors.green[600], ), ), ], ), ), const SizedBox(width: 12), Text( "1,234 reviews", style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ], ), ), const SizedBox(height: 16), const SizedBox(height: 24), // Attributes Section if (product.attributes != null && product.attributes!.isNotEmpty) _buildAttributesSection( product, ref, selectedColor, selectedWeight, ), const SizedBox(height: 24), // Quantity Selector Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[300]!), ), child: Row( children: [ const Text( "Quantity:", style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), const Spacer(), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.grey[300]!), ), child: Row( children: [ InkWell( onTap: () { if (quantity > 1) { ref .read(quantityProvider.notifier) .state--; } }, child: Container( padding: const EdgeInsets.all(12), child: const Icon( Icons.remove, size: 18, color: Colors.grey, ), ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), decoration: BoxDecoration( border: Border.symmetric( vertical: BorderSide( color: Colors.grey[300]!, ), ), ), child: Text( quantity.toString(), style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), InkWell( onTap: () { ref .read(quantityProvider.notifier) .state++; }, child: Container( padding: const EdgeInsets.all(12), child: Icon( Icons.add, size: 18, color: Colors.green[600], ), ), ), ], ), ), ], ), ), const SizedBox(height: 24), // Product Description if (product.shortDescription != null && product.shortDescription!.isNotEmpty) Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[300]!), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Product Details", style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), HtmlWidget( product.shortDescription!, textStyle: TextStyle( fontSize: 14, color: Colors.grey[700], height: 1.5, ), ), ], ), ), const SizedBox(height: 24), // Delivery Info Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.blue[50], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.blue[100]!), ), child: Column( children: [ Row( children: [ Icon( Icons.local_shipping, color: Colors.blue[700], ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Free Delivery", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 14, ), ), Text( "Get it by tomorrow, 6:00 AM - 10:00 AM", style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ), ], ), const SizedBox(height: 12), Row( children: [ Icon( Icons.assignment_return, color: Colors.blue[700], ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Easy Return", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 14, ), ), Text( "7 days return policy", style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ), ], ), ], ), ), const SizedBox(height: 100), // Space for bottom buttons ], ), ), ), ], ); }, loading: () => const Scaffold(body: Center(child: CircularProgressIndicator())), error: (err, stack) => Scaffold(body: Center(child: Text("Error: $err"))), ), bottomNavigationBar: detailAsync.when( data: (product) => _buildBottomBar( context, ref, product, selectedColor, selectedWeight, quantity, ), loading: () => const SizedBox.shrink(), error: (err, stack) => const SizedBox.shrink(), ), ); } Widget _buildAttributesSection( product, WidgetRef ref, String? selectedColor, String? selectedWeight, ) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[300]!), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: product.attributes!.map((attr) { final attrName = attr.name?.toLowerCase(); if (attrName == "color") { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Available Colors", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 12), Wrap( spacing: 12, runSpacing: 8, children: attr.options!.map((option) { final isSelected = option == selectedColor; Color colorValue = _getColorFromName(option); return GestureDetector( onTap: () { ref.read(selectedColorProvider.notifier).state = option; }, child: Container( width: 45, height: 45, decoration: BoxDecoration( color: colorValue, shape: BoxShape.circle, border: Border.all( color: isSelected ? Colors.green[600]! : Colors.grey[400]!, width: isSelected ? 3 : 1, ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: isSelected ? Icon( Icons.check, color: colorValue == Colors.white ? Colors.black : Colors.white, size: 20, ) : null, ), ); }).toList(), ), const SizedBox(height: 16), ], ); } else if (attrName == "weight" || attrName == "size") { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Select ${attr.name}", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), Wrap( spacing: 12, runSpacing: 8, children: attr.options!.map((option) { final isSelected = option == selectedWeight; return GestureDetector( onTap: () { ref.read(selectedWeightProvider.notifier).state = option; }, child: Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), decoration: BoxDecoration( color: isSelected ? Colors.green[600] : Colors.white, border: Border.all( color: isSelected ? Colors.green[600]! : Colors.grey[400]!, width: 1.5, ), borderRadius: BorderRadius.circular(25), ), child: Text( option, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: isSelected ? Colors.white : Colors.black, ), ), ), ); }).toList(), ), const SizedBox(height: 8), ], ); } return const SizedBox.shrink(); }).toList(), ), ); } Widget _buildBottomBar( BuildContext context, WidgetRef ref, product, String? selectedColor, String? selectedWeight, int quantity, ) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, -5), ), ], ), child: SafeArea( child: Row( children: [ Expanded( child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.green[600], foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), elevation: 2, ), onPressed: () { if (_validateSelection( context, selectedColor, selectedWeight, product, )) { // Handle Add to Cart ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( "Added $quantity x ${product.name} to cart", ), backgroundColor: Colors.green[600], action: SnackBarAction( label: "View Cart", textColor: Colors.white, onPressed: () async { await CartButtonHelper.addToCartAndNavigate( context: context, ref: ref, product: product, quantity: quantity, selectedColor: selectedColor, selectedWeight: selectedWeight, ); }, ), ), ); } }, child: const Text( "Add to Cart", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ), ], ), ), ); } bool _validateSelection( BuildContext context, String? selectedColor, String? selectedWeight, product, ) { bool hasColorAttribute = product.attributes?.any( (attr) => attr.name?.toLowerCase() == "color", ) ?? false; bool hasWeightAttribute = product.attributes?.any( (attr) => attr.name?.toLowerCase() == "weight" || attr.name?.toLowerCase() == "size", ) ?? false; if (hasColorAttribute && selectedColor == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Please select a color"), backgroundColor: Colors.red, ), ); return false; } if (hasWeightAttribute && selectedWeight == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Please select size/weight"), backgroundColor: Colors.red, ), ); return false; } return true; } Color _getColorFromName(String colorName) { if (colorName.startsWith("#") && colorName.length == 7) { return Color( int.parse(colorName.substring(1, 7), radix: 16) + 0xFF000000, ); } switch (colorName.toLowerCase()) { case "red": return Colors.red; case "blue": return Colors.blue; case "green": return Colors.green; case "black": return Colors.black; case "white": return Colors.white; case "orange": return Colors.orange; case "yellow": return Colors.yellow; case "purple": return Colors.purple; case "pink": return Colors.pink; case "brown": return Colors.brown; default: return Colors.grey; } } }