import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import '../api_client.dart';
import '../widgets/banner_ad_widget.dart';
import '../widgets/payment_overview.dart';
import '../widgets/payment_bottom_sheet.dart' show showPaymentBottomSheet, showTransactionStatusDialog;

// ── Brand tokens ──────────────────────────────────────────────────────────────
class _Brand {
  static const bg = Color(0xFF0F1114);
  static const card = Color(0xFF21252D);
  static const cardElevated = Color(0xFF272B34);
  static const amber = Color(0xFFFF9500);
  static const amberGlow = Color(0x33FF9500);
  static const green = Color(0xFF34C759);
  static const textPrimary = Color(0xFFF2F2F2);
  static const textMuted = Color(0xFF8A8F99);
  static const divider = Color(0xFF2C3040);
  static const error = Color(0xFFFF4545);
}

// ── Data model (unchanged) ────────────────────────────────────────────────────
class CartItem {
  final int inventoryId;
  final String name;
  final double unitPrice;
  int quantity;

  CartItem({
    required this.inventoryId,
    required this.name,
    required this.unitPrice,
    this.quantity = 1,
  });

  double get lineTotal => unitPrice * quantity;
}

// ─────────────────────────────────────────────────────────────────────────────

class ShopScreen extends StatefulWidget {
  const ShopScreen({super.key, required this.onUnauthorized, this.onOrderCreated});
  final VoidCallback onUnauthorized;
  final VoidCallback? onOrderCreated;

  @override
  State<ShopScreen> createState() => _ShopScreenState();
}

class _ShopScreenState extends State<ShopScreen> {
  late Dio _dio;
  List<dynamic> _categories = [];
  List<dynamic> _products = [];
  List<CartItem> _cart = [];
  List<dynamic> _addresses = [];
  Map? _config;
  Map? _user;
  int? _selectedCategoryId;
  bool _loading = true;
  bool _checkout = false;
  Map? _selectedAddress;
  int _pointsToUse = 0;
  String? _error;

  @override
  void initState() {
    super.initState();
    _dio = createApiClient(() => widget.onUnauthorized());
    _load();
  }

  Future<void> _load() async {
    setState(() => _loading = true);
    try {
      final r = await Future.wait([
        _dio.get('/api/shop/categories'),
        _dio.get('/api/shop/products'),
        _dio.get('/api/addresses'),
        _dio.get('/api/config'),
        _dio.get('/api/auth/me'),
      ]);
      if (!mounted) return;
      setState(() {
        _categories = (r[0].data is Map && r[0].data['data'] is List)
            ? List.from(r[0].data['data'] as List)
            : [];
        _products = (r[1].data is Map && r[1].data['data'] is List)
            ? List.from(r[1].data['data'] as List)
            : [];
        _addresses = (r[2].data is Map && r[2].data['data'] is List)
            ? List.from(r[2].data['data'] as List)
            : [];
        _config = (r[3].data is Map && r[3].data['data'] != null)
            ? r[3].data['data'] as Map
            : null;
        _user = (r[4].data is Map && r[4].data['data'] != null)
            ? r[4].data['data'] as Map
            : null;
        _loading = false;
      });
    } catch (e) {
      if (e is DioException && e.response?.statusCode == 401) {
        widget.onUnauthorized();
      }
      if (mounted) setState(() => _loading = false);
    }
  }

  // ── Computed (unchanged) ───────────────────────────────────────────────────

  double get _serviceFee =>
      (_config != null && _config!['service_fee'] != null)
          ? (double.tryParse(_config!['service_fee'].toString()) ?? 0)
          : 0;
  double get _deliveryFee =>
      (_config != null && _config!['delivery_fee'] != null)
          ? (double.tryParse(_config!['delivery_fee'].toString()) ?? 0)
          : 0;
  double get _subtotal => _cart.fold(0.0, (s, i) => s + i.lineTotal);
  double get _total => _subtotal + _serviceFee + _deliveryFee;

  int get _pointsBalance =>
      (_user != null && _user!['points_balance'] != null)
          ? (int.tryParse(_user!['points_balance'].toString()) ?? 0)
          : 0;

  int get _maxRedeemablePoints {
    final totalInt = _total.floor();
    if (totalInt <= 0 || _pointsBalance <= 0) return 0;
    return totalInt.clamp(0, _pointsBalance);
  }

  double get _amountAfterPoints {
    final use = _pointsToUse.clamp(0, _maxRedeemablePoints);
    return (_total - use).clamp(0.0, double.infinity);
  }

  List<dynamic> get _filteredProducts {
    if (_selectedCategoryId == null) return _products;
    return _products
        .where((p) =>
            p is Map &&
            (p['category_id'] == _selectedCategoryId ||
                p['shop_category_id'] == _selectedCategoryId))
        .toList();
  }

  void _updateCart(int invId, String name, double unitPrice, int delta) {
    setState(() {
      final i = _cart.indexWhere((e) => e.inventoryId == invId);
      if (i >= 0) {
        _cart[i].quantity += delta;
        if (_cart[i].quantity <= 0) _cart.removeAt(i);
      } else if (delta > 0) {
        _cart.add(CartItem(
            inventoryId: invId,
            name: name,
            unitPrice: unitPrice,
            quantity: delta));
      }
    });
  }

  void _showProductDetail(
    BuildContext context,
    Map<dynamic, dynamic> product,
    int id,
    String name,
    double price,
    int qty,
  ) {
    final imageUrl = product['image_url']?.toString();
    showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (ctx) => _ProductDetailSheet(
        name: name,
        price: price,
        imageUrl: (imageUrl != null && imageUrl.isNotEmpty) ? imageUrl : null,
        qty: qty,
        onAdd: () {
          _updateCart(id, name, price, 1);
        },
        onRemove: () {
          _updateCart(id, name, price, -1);
        },
        onClose: () => Navigator.of(ctx).pop(),
      ),
    );
  }

  // ── Build ──────────────────────────────────────────────────────────────────

  @override
  Widget build(BuildContext context) {
    if (_loading && _categories.isEmpty) {
      return const Center(
        child: SizedBox(
          width: 32,
          height: 32,
          child: CircularProgressIndicator(
            strokeWidth: 2.5,
            valueColor: AlwaysStoppedAnimation(_Brand.amber),
          ),
        ),
      );
    }
    if (_checkout) return _buildCheckout();
    return _buildShop();
  }

  // ── Shop view ──────────────────────────────────────────────────────────────

  Widget _buildShop() {
    final cartCount = _cart.length;
    final cartTotal = _total;

    return Scaffold(
      backgroundColor: _Brand.bg,
      appBar: AppBar(
        backgroundColor: _Brand.bg,
        elevation: 0,
        scrolledUnderElevation: 0,
        title: const Row(
          children: [
            Icon(Icons.shopping_bag_rounded, color: _Brand.amber, size: 20),
            SizedBox(width: 8),
            Text(
              'SHOP',
              style: TextStyle(
                fontFamily: 'RobotoMono',
                color: _Brand.textPrimary,
                fontSize: 16,
                fontWeight: FontWeight.w700,
                letterSpacing: 3,
              ),
            ),
          ],
        ),
        actions: [
          if (cartCount > 0)
            Padding(
              padding: const EdgeInsets.only(right: 12),
              child: GestureDetector(
                onTap: () => setState(() => _checkout = true),
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                  decoration: BoxDecoration(
                    color: _Brand.amberGlow,
                    borderRadius: BorderRadius.circular(20),
                    border: Border.all(
                        color: _Brand.amber.withOpacity(0.4), width: 1),
                  ),
                  child: Row(
                    children: [
                      const Icon(Icons.shopping_cart_rounded,
                          color: _Brand.amber, size: 14),
                      const SizedBox(width: 5),
                      Text(
                        '$cartCount',
                        style: const TextStyle(
                          color: _Brand.amber,
                          fontSize: 13,
                          fontWeight: FontWeight.w700,
                          fontFamily: 'RobotoMono',
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
        ],
      ),
      body: Column(
        children: [
          // ── Category filter ──────────────────────────────────────────────
          if (_categories.isNotEmpty)
            SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              padding:
                  const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
              child: Row(
                children: [
                  _CategoryChip(
                    label: 'All',
                    selected: _selectedCategoryId == null,
                    onTap: () => setState(() => _selectedCategoryId = null),
                  ),
                  ..._categories.map<Widget>((c) {
                    final m = c is Map ? c : {};
                    final id = m['id'];
                    return Padding(
                      padding: const EdgeInsets.only(left: 8),
                      child: _CategoryChip(
                        label: m['name']?.toString() ?? '',
                        selected: _selectedCategoryId == id,
                        onTap: () =>
                            setState(() => _selectedCategoryId = id),
                      ),
                    );
                  }),
                ],
              ),
            ),

          // ── Product list ─────────────────────────────────────────────────
          Expanded(
            child: ListView.builder(
              padding: const EdgeInsets.fromLTRB(16, 4, 16, 100),
              itemCount: _filteredProducts.length + 1,
              itemBuilder: (context, i) {
                if (i == 0) {
                  return const Padding(
                    padding: EdgeInsets.only(bottom: 12),
                    child: BannerAdWidget(),
                  );
                }
                final p = _filteredProducts[i - 1] as Map;
                final id = p['id'];
                final name =
                    p['item_name']?.toString() ?? p['name']?.toString() ?? '';
                final price =
                    double.tryParse(p['price'].toString()) ?? 0;
                final imageUrl = p['image_url']?.toString();
                final inCart =
                    _cart.where((e) => e.inventoryId == id).toList();
                final qty = inCart.isEmpty ? 0 : inCart.first.quantity;

                return Padding(
                  padding: const EdgeInsets.only(bottom: 10),
                  child: _ProductCard(
                    name: name,
                    price: price,
                    imageUrl: imageUrl?.isNotEmpty == true ? imageUrl : null,
                    qty: qty,
                    onAdd: () => _updateCart(id, name, price, 1),
                    onRemove: () => _updateCart(id, name, price, -1),
                    onTap: () => _showProductDetail(context, p, id, name, price, qty),
                  ),
                );
              },
            ),
          ),
        ],
      ),

      // ── Floating cart bar ─────────────────────────────────────────────────
      bottomNavigationBar: cartCount > 0
          ? _CartBar(
              itemCount: cartCount,
              total: cartTotal,
              onCheckout: () => setState(() => _checkout = true),
            )
          : null,
    );
  }

  // ── Checkout view ──────────────────────────────────────────────────────────

  Widget _buildCheckout() {
    return Scaffold(
      backgroundColor: _Brand.bg,
      appBar: AppBar(
        backgroundColor: _Brand.bg,
        elevation: 0,
        scrolledUnderElevation: 0,
        leading: GestureDetector(
          onTap: () => setState(() => _checkout = false),
          child: Container(
            margin: const EdgeInsets.all(10),
            decoration: BoxDecoration(
              color: _Brand.card,
              borderRadius: BorderRadius.circular(9),
              border: Border.all(color: _Brand.divider),
            ),
            child: const Icon(Icons.arrow_back_ios_new,
                size: 13, color: _Brand.textMuted),
          ),
        ),
        title: const Text(
          'CHECKOUT',
          style: TextStyle(
            fontFamily: 'RobotoMono',
            color: _Brand.textPrimary,
            fontSize: 15,
            fontWeight: FontWeight.w700,
            letterSpacing: 3,
          ),
        ),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.fromLTRB(20, 8, 20, 40),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Error
            if (_error != null) ...[
              _ErrorBanner(_error!),
              const SizedBox(height: 16),
            ],

            // Cart summary
            _SectionLabel('ORDER SUMMARY'),
            const SizedBox(height: 12),
            ..._cart.map((item) => Padding(
                  padding: const EdgeInsets.only(bottom: 8),
                  child: _CartItemRow(item: item),
                )),

            const SizedBox(height: 24),

            // Address picker
            _SectionLabel('DELIVERY ADDRESS'),
            const SizedBox(height: 12),

            if (_addresses.isEmpty)
              Container(
                padding: const EdgeInsets.all(14),
                decoration: BoxDecoration(
                  color: _Brand.card,
                  borderRadius: BorderRadius.circular(12),
                  border: Border.all(color: _Brand.divider),
                ),
                child: const Row(
                  children: [
                    Icon(Icons.location_off_rounded,
                        color: _Brand.textMuted, size: 16),
                    SizedBox(width: 10),
                    Text('No addresses saved. Add one in Settings.',
                        style: TextStyle(
                            color: _Brand.textMuted, fontSize: 13)),
                  ],
                ),
              )
            else
              ..._addresses.map<Widget>((a) {
                final m = a is Map ? a : {};
                final label = m['address_name']?.toString() ??
                    m['plus_code']?.toString() ??
                    '${m['latitude']}, ${m['longitude']}';
                final selected = _selectedAddress == m;
                return Padding(
                  padding: const EdgeInsets.only(bottom: 8),
                  child: GestureDetector(
                    onTap: () => setState(() => _selectedAddress = m),
                    child: Container(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 14, vertical: 12),
                      decoration: BoxDecoration(
                        color: selected
                            ? _Brand.amberGlow
                            : _Brand.card,
                        borderRadius: BorderRadius.circular(12),
                        border: Border.all(
                          color: selected
                              ? _Brand.amber.withOpacity(0.5)
                              : _Brand.divider,
                          width: selected ? 1.5 : 1,
                        ),
                      ),
                      child: Row(
                        children: [
                          Icon(
                            selected
                                ? Icons.radio_button_checked_rounded
                                : Icons.radio_button_unchecked_rounded,
                            color: selected
                                ? _Brand.amber
                                : _Brand.textMuted,
                            size: 18,
                          ),
                          const SizedBox(width: 10),
                          Expanded(
                            child: Text(label,
                                style: TextStyle(
                                  color: selected
                                      ? _Brand.textPrimary
                                      : _Brand.textMuted,
                                  fontSize: 13,
                                  fontWeight: selected
                                      ? FontWeight.w600
                                      : FontWeight.normal,
                                )),
                          ),
                          if (selected)
                            const Icon(Icons.check_circle_rounded,
                                color: _Brand.amber, size: 16),
                        ],
                      ),
                    ),
                  ),
                );
              }),

            const SizedBox(height: 24),

            // Use Jambo Points
            _SectionLabel('JAMBO POINTS'),
            const SizedBox(height: 12),
            PointsRedeemSection(
              pointsBalance: _pointsBalance,
              maxRedeemable: _maxRedeemablePoints,
              pointsToUse: _pointsToUse,
              totalUgx: _total,
              onChanged: (v) => setState(() => _pointsToUse = v),
            ),
            const SizedBox(height: 24),

            // Payment overview
            PaymentOverview(
              data: PaymentOverviewData(
                addressSummary: _selectedAddress != null
                    ? (_selectedAddress!['address_name']?.toString() ??
                        _selectedAddress!['plus_code']?.toString() ??
                        '${_selectedAddress!['latitude']}, ${_selectedAddress!['longitude']}')
                    : '—',
                serviceSummary: 'Shop (${_cart.length} items)',
                subtotal: _subtotal,
                serviceFee: _serviceFee,
                deliveryFee: _deliveryFee,
                total: _amountAfterPoints,
                pointsDiscount: _pointsToUse.toDouble(),
                pointsUsed: _pointsToUse,
              ),
              onMakePayment: _selectedAddress == null
                  ? () {}
                  : () => showPaymentBottomSheet(
                        context,
                        amount: _amountAfterPoints,
                        dio: _dio,
                        callbackBaseUrl: baseUrl,
                        onSuccess: () {
                          _createOrder().then((success) {
                            if (!mounted) return;
                            showTransactionStatusDialog(
                              context,
                              success: success,
                              onDone: () => widget.onOrderCreated?.call(),
                            );
                          });
                        },
                      ),
              onCompleteOrder: _selectedAddress != null && _amountAfterPoints <= 0
                  ? () {
                      _createOrder().then((success) {
                        if (!mounted) return;
                        showTransactionStatusDialog(
                          context,
                          success: success,
                          onDone: () => widget.onOrderCreated?.call(),
                        );
                      });
                    }
                  : null,
            ),
          ],
        ),
      ),
    );
  }

  // ── Order creation (unchanged) ─────────────────────────────────────────────

  Future<bool> _createOrder() async {
    setState(() {
      _loading = true;
      _error = null;
    });
    try {
      await _dio.post('/api/orders', data: {
        'order_type': 'shop',
        'location_id': _selectedAddress!['id'],
        'total_amount': _total,
        'points_used': _pointsToUse,
        'items': _cart
            .map((e) => {
                  'inventory_id': e.inventoryId,
                  'quantity': e.quantity,
                  'unit_price': e.unitPrice,
                })
            .toList(),
      });
      if (!mounted) return false;
      // Order created successfully — dialog should show success. Refresh user/points in background.
      _refreshUserAfterOrder();
      setState(() {
        _cart = [];
        _checkout = false;
        _loading = false;
      });
      return true;
    } catch (e) {
      if (e is DioException && e.response?.statusCode == 401) {
        widget.onUnauthorized();
      }
      if (mounted) {
        setState(() {
          _loading = false;
          _error = e is DioException
              ? (e.response?.data is Map
                      ? e.response?.data['message']?.toString()
                      : null) ??
                  'Failed'
              : 'Failed';
        });
      }
      return false;
    }
  }

  void _refreshUserAfterOrder() {
    _dio.get('/api/auth/me').then((meResp) {
      if (!mounted) return;
      if (meResp.data is Map && meResp.data['data'] != null) {
        setState(() => _user = meResp.data['data'] as Map);
      }
    }).catchError((_) {
      // Ignore — order was already placed; points will refresh on next load
    });
  }
}

// ── Sub-widgets ───────────────────────────────────────────────────────────────

class _CategoryChip extends StatelessWidget {
  final String label;
  final bool selected;
  final VoidCallback onTap;
  const _CategoryChip(
      {required this.label, required this.selected, required this.onTap});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 180),
        padding:
            const EdgeInsets.symmetric(horizontal: 14, vertical: 7),
        decoration: BoxDecoration(
          color: selected ? _Brand.amber : _Brand.card,
          borderRadius: BorderRadius.circular(20),
          border: Border.all(
            color: selected ? _Brand.amber : _Brand.divider,
            width: 1,
          ),
        ),
        child: Text(
          label,
          style: TextStyle(
            color: selected ? Colors.black : _Brand.textMuted,
            fontSize: 12,
            fontWeight:
                selected ? FontWeight.w700 : FontWeight.normal,
            letterSpacing: 0.3,
          ),
        ),
      ),
    );
  }
}

class _ProductCard extends StatelessWidget {
  final String name;
  final double price;
  final String? imageUrl;
  final int qty;
  final VoidCallback onAdd;
  final VoidCallback onRemove;
  final VoidCallback? onTap;

  const _ProductCard({
    required this.name,
    required this.price,
    required this.imageUrl,
    required this.qty,
    required this.onAdd,
    required this.onRemove,
    this.onTap,
  });

  String _fmt(double v) {
    final s = v.toStringAsFixed(0).split('');
    final buf = StringBuffer();
    for (int i = 0; i < s.length; i++) {
      if (i > 0 && (s.length - i) % 3 == 0) buf.write(',');
      buf.write(s[i]);
    }
    return buf.toString();
  }

  @override
  Widget build(BuildContext context) {
    final inCart = qty > 0;

    return AnimatedContainer(
      duration: const Duration(milliseconds: 200),
      decoration: BoxDecoration(
        color: _Brand.card,
        borderRadius: BorderRadius.circular(14),
        border: Border.all(
          color: inCart ? _Brand.amber.withOpacity(0.35) : _Brand.divider,
          width: inCart ? 1.5 : 1,
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Row(
          children: [
            // Tappable image + text area (opens detail / larger image)
            Expanded(
              child: GestureDetector(
                onTap: onTap,
                behavior: HitTestBehavior.opaque,
                child: Row(
                  children: [
                    Container(
                      width: 60,
                      height: 60,
                      decoration: BoxDecoration(
                        color: _Brand.amberGlow,
                        borderRadius: BorderRadius.circular(10),
                      ),
                      clipBehavior: Clip.antiAlias,
                      child: imageUrl != null
                          ? Image.network(
                              imageUrl!,
                              fit: BoxFit.cover,
                              errorBuilder: (_, __, ___) => const Icon(
                                  Icons.inventory_2_rounded,
                                  color: _Brand.amber,
                                  size: 28),
                            )
                          : const Icon(Icons.inventory_2_rounded,
                              color: _Brand.amber, size: 28),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(name,
                              style: const TextStyle(
                                color: _Brand.textPrimary,
                                fontSize: 14,
                                fontWeight: FontWeight.w600,
                              )),
                          const SizedBox(height: 3),
                          Text(
                            '${_fmt(price)} UGX',
                            style: const TextStyle(
                              color: _Brand.amber,
                              fontSize: 13,
                              fontFamily: 'RobotoMono',
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          if (onTap != null)
                            Padding(
                              padding: const EdgeInsets.only(top: 4),
                              child: Text(
                                'Tap to view',
                                style: TextStyle(
                                  color: _Brand.textMuted.withOpacity(0.8),
                                  fontSize: 11,
                                ),
                              ),
                            ),
                        ],
                      ),
                    ),
                    if (onTap != null)
                      const Icon(Icons.chevron_right_rounded,
                          color: _Brand.textMuted, size: 20),
                  ],
                ),
              ),
            ),

            // Quantity stepper or Add button (does not trigger onTap)
            if (inCart)
              _Stepper(qty: qty, onAdd: onAdd, onRemove: onRemove)
            else
              GestureDetector(
                onTap: onAdd,
                child: Container(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 14, vertical: 7),
                  decoration: BoxDecoration(
                    color: _Brand.amberGlow,
                    borderRadius: BorderRadius.circular(8),
                    border: Border.all(
                        color: _Brand.amber.withOpacity(0.4), width: 1),
                  ),
                  child: const Text(
                    'Add',
                    style: TextStyle(
                      color: _Brand.amber,
                      fontSize: 12,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

/// Bottom sheet showing larger product image, name, price, and add/stepper.
class _ProductDetailSheet extends StatefulWidget {
  final String name;
  final double price;
  final String? imageUrl;
  final int qty;
  final VoidCallback onAdd;
  final VoidCallback onRemove;
  final VoidCallback onClose;

  const _ProductDetailSheet({
    required this.name,
    required this.price,
    required this.imageUrl,
    required this.qty,
    required this.onAdd,
    required this.onRemove,
    required this.onClose,
  });

  @override
  State<_ProductDetailSheet> createState() => _ProductDetailSheetState();
}

class _ProductDetailSheetState extends State<_ProductDetailSheet> {
  late int _qty;

  @override
  void initState() {
    super.initState();
    _qty = widget.qty;
  }

  @override
  void didUpdateWidget(covariant _ProductDetailSheet oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.qty != widget.qty) _qty = widget.qty;
  }

  String _fmt(double v) {
    final s = v.toStringAsFixed(0).split('');
    final buf = StringBuffer();
    for (int i = 0; i < s.length; i++) {
      if (i > 0 && (s.length - i) % 3 == 0) buf.write(',');
      buf.write(s[i]);
    }
    return buf.toString();
  }

  void _add() {
    setState(() => _qty++);
    widget.onAdd();
  }

  void _remove() {
    if (_qty > 0) {
      setState(() => _qty--);
      widget.onRemove();
    }
  }

  @override
  Widget build(BuildContext context) {
    final inCart = _qty > 0;
    return Container(
      decoration: const BoxDecoration(
        color: _Brand.card,
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      child: DraggableScrollableSheet(
        initialChildSize: 0.72,
        minChildSize: 0.4,
        maxChildSize: 0.92,
        expand: false,
        builder: (context, scrollController) {
          return ListView(
            controller: scrollController,
            padding: EdgeInsets.only(
              top: 8,
              left: 20,
              right: 20,
              bottom: MediaQuery.of(context).padding.bottom + 24,
            ),
            children: [
              Center(
                child: Container(
                  width: 40,
                  height: 4,
                  decoration: BoxDecoration(
                    color: _Brand.divider,
                    borderRadius: BorderRadius.circular(2),
                  ),
                ),
              ),
              const SizedBox(height: 12),
              GestureDetector(
                onTap: widget.onClose,
                child: Align(
                  alignment: Alignment.centerRight,
                  child: Icon(
                    Icons.close_rounded,
                    color: _Brand.textMuted,
                    size: 28,
                  ),
                ),
              ),
              const SizedBox(height: 8),
              // Large image
              ClipRRect(
                borderRadius: BorderRadius.circular(14),
                child: AspectRatio(
                  aspectRatio: 1.15,
                  child: widget.imageUrl != null
                      ? Image.network(
                          widget.imageUrl!,
                          fit: BoxFit.cover,
                          errorBuilder: (_, __, ___) => _imagePlaceholder(),
                        )
                      : _imagePlaceholder(),
                ),
              ),
              const SizedBox(height: 20),
              Text(
                widget.name,
                style: const TextStyle(
                  color: _Brand.textPrimary,
                  fontSize: 18,
                  fontWeight: FontWeight.w700,
                ),
              ),
              const SizedBox(height: 8),
              Text(
                '${_fmt(widget.price)} UGX',
                style: const TextStyle(
                  color: _Brand.amber,
                  fontSize: 16,
                  fontFamily: 'RobotoMono',
                  fontWeight: FontWeight.w700,
                ),
              ),
              const SizedBox(height: 24),
              if (inCart)
                _Stepper(qty: _qty, onAdd: _add, onRemove: _remove)
              else
                SizedBox(
                  width: double.infinity,
                  height: 52,
                  child: FilledButton(
                    onPressed: _add,
                    style: FilledButton.styleFrom(
                      backgroundColor: _Brand.amber,
                      foregroundColor: Colors.black,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(12),
                      ),
                    ),
                    child: const Text('Add to cart'),
                  ),
                ),
            ],
          );
        },
      ),
    );
  }

  Widget _imagePlaceholder() {
    return Container(
      color: _Brand.amberGlow,
      child: const Center(
        child: Icon(
          Icons.inventory_2_rounded,
          color: _Brand.amber,
          size: 64,
        ),
      ),
    );
  }
}

class _Stepper extends StatelessWidget {
  final int qty;
  final VoidCallback onAdd;
  final VoidCallback onRemove;
  const _Stepper(
      {required this.qty, required this.onAdd, required this.onRemove});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: _Brand.amberGlow,
        borderRadius: BorderRadius.circular(8),
        border:
            Border.all(color: _Brand.amber.withOpacity(0.4), width: 1),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          _StepBtn(icon: Icons.remove, onTap: onRemove),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10),
            child: Text(
              '$qty',
              style: const TextStyle(
                color: _Brand.amber,
                fontFamily: 'RobotoMono',
                fontWeight: FontWeight.w700,
                fontSize: 14,
              ),
            ),
          ),
          _StepBtn(icon: Icons.add, onTap: onAdd),
        ],
      ),
    );
  }
}

class _StepBtn extends StatelessWidget {
  final IconData icon;
  final VoidCallback onTap;
  const _StepBtn({required this.icon, required this.onTap});

  @override
  Widget build(BuildContext context) => GestureDetector(
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.all(7),
          child: Icon(icon, color: _Brand.amber, size: 16),
        ),
      );
}

class _CartBar extends StatelessWidget {
  final int itemCount;
  final double total;
  final VoidCallback onCheckout;
  const _CartBar(
      {required this.itemCount,
      required this.total,
      required this.onCheckout});

  String _fmt(double v) {
    final s = v.toStringAsFixed(0).split('');
    final buf = StringBuffer();
    for (int i = 0; i < s.length; i++) {
      if (i > 0 && (s.length - i) % 3 == 0) buf.write(',');
      buf.write(s[i]);
    }
    return buf.toString();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.fromLTRB(20, 12, 20, 28),
      decoration: BoxDecoration(
        color: _Brand.card,
        border: const Border(top: BorderSide(color: _Brand.divider)),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.3),
            blurRadius: 16,
            offset: const Offset(0, -4),
          ),
        ],
      ),
      child: SizedBox(
        height: 52,
        child: ElevatedButton(
          onPressed: onCheckout,
          style: ElevatedButton.styleFrom(
            backgroundColor: _Brand.amber,
            foregroundColor: Colors.black,
            elevation: 0,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12),
            ),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Row(
                children: [
                  const Icon(Icons.shopping_cart_rounded,
                      size: 16, color: Colors.black),
                  const SizedBox(width: 6),
                  Text(
                    '$itemCount ${itemCount == 1 ? 'item' : 'items'}',
                    style: const TextStyle(
                      fontWeight: FontWeight.w700,
                      fontSize: 13,
                    ),
                  ),
                ],
              ),
              const Text('CHECKOUT',
                  style: TextStyle(
                    fontWeight: FontWeight.w800,
                    letterSpacing: 1.5,
                    fontSize: 13,
                  )),
              Text(
                '${_fmt(total)} UGX',
                style: const TextStyle(
                  fontFamily: 'RobotoMono',
                  fontWeight: FontWeight.w700,
                  fontSize: 13,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _CartItemRow extends StatelessWidget {
  final CartItem item;
  const _CartItemRow({required this.item});

  String _fmt(double v) {
    final s = v.toStringAsFixed(0).split('');
    final buf = StringBuffer();
    for (int i = 0; i < s.length; i++) {
      if (i > 0 && (s.length - i) % 3 == 0) buf.write(',');
      buf.write(s[i]);
    }
    return buf.toString();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
      decoration: BoxDecoration(
        color: _Brand.card,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: _Brand.divider),
      ),
      child: Row(
        children: [
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(item.name,
                    style: const TextStyle(
                        color: _Brand.textPrimary,
                        fontSize: 13,
                        fontWeight: FontWeight.w600)),
                const SizedBox(height: 2),
                Text(
                  '${_fmt(item.unitPrice)} UGX × ${item.quantity}',
                  style: const TextStyle(
                      color: _Brand.textMuted,
                      fontSize: 11,
                      fontFamily: 'RobotoMono'),
                ),
              ],
            ),
          ),
          Text(
            '${_fmt(item.lineTotal)} UGX',
            style: const TextStyle(
              color: _Brand.amber,
              fontSize: 13,
              fontFamily: 'RobotoMono',
              fontWeight: FontWeight.w700,
            ),
          ),
        ],
      ),
    );
  }
}

class _SectionLabel extends StatelessWidget {
  final String text;
  const _SectionLabel(this.text);

  @override
  Widget build(BuildContext context) => Text(
        text,
        style: const TextStyle(
          color: _Brand.textMuted,
          fontSize: 10,
          letterSpacing: 2.5,
          fontWeight: FontWeight.w600,
        ),
      );
}

class _ErrorBanner extends StatelessWidget {
  final String message;
  const _ErrorBanner(this.message);

  @override
  Widget build(BuildContext context) => Container(
        padding:
            const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
        decoration: BoxDecoration(
          color: _Brand.error.withOpacity(0.12),
          borderRadius: BorderRadius.circular(10),
          border:
              Border.all(color: _Brand.error.withOpacity(0.4)),
        ),
        child: Row(
          children: [
            const Icon(Icons.warning_amber_rounded,
                color: _Brand.error, size: 18),
            const SizedBox(width: 10),
            Expanded(
              child: Text(message,
                  style: const TextStyle(
                      color: _Brand.error,
                      fontSize: 13,
                      height: 1.4)),
            ),
          ],
        ),
      );
}