import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/api/api_exception.dart';
import '../../../core/api/api_paths.dart';
import '../../../core/api/api_providers.dart';
import '../../../core/ui/category_then_product_picker.dart';
import '../../../core/ui/product_picker_field.dart';
import '../../../core/utils/pdf_opener.dart';
import '../../../core/utils/global_error_handler.dart';
import '../../admin/data/admin_repository.dart';
import '../../admin/domain/admin_category_node.dart';
import '../../auth/data/auth_providers.dart';
import '../../inventory/data/inventory_providers.dart';
import '../../inventory/domain/inventory_item.dart';
import '../../pantry/data/pantry_providers.dart';
import '../../pantry/domain/pantry_item.dart';
import '../data/import_providers.dart';
import '../data/receipt_import_session.dart';
import '../domain/parsed_receipt_item.dart';

typedef _Destination = ImportDestination;

enum _ProductEntryMode { existing, create }

bool _isPackageLikeUnit(String? unit) {
  if (unit == null) return false;
  const packageUnits = {
    'paket',
    'forpackning',
    'forp',
    'forp.',
    'förpackning',
    'förp',
    'förp.',
    'fp',
    'pkt',
    'pack',
    'pak',
    'st',
    'styck',
  };
  return packageUnits.contains(unit.trim().toLowerCase());
}

({double packQuantity, String packUnit})? _extractPackageSizeFromRawName(
  String rawName,
) {
  final match = RegExp(
    r'(\d+(?:[\.,]\d+)?)\s*(ml|cl|dl|l|g|kg)\b',
    caseSensitive: false,
  ).firstMatch(rawName);
  if (match == null) return null;
  final value = double.tryParse(match.group(1)!.replaceAll(',', '.'));
  final sizeUnit = match.group(2)!.toLowerCase();
  if (value == null) return null;
  return (packQuantity: value, packUnit: sizeUnit);
}

({double? packQuantity, String? packUnit, double packageCount, double? totalQuantity, String? totalUnit})
    _inferPackageFields({
  required String rawName,
  required double? quantity,
  required String? unit,
}) {
  final normalizedUnit = unit?.trim().toLowerCase();
  final safeCount = (quantity != null && quantity > 0) ? quantity : 1.0;
  final extracted = _extractPackageSizeFromRawName(rawName);

  // If the receipt name contains size (e.g. "5dl"), prefer it when unit is
  // missing/unknown or when OCR reports package-like count units (st/pkt/etc).
  if (extracted != null && (normalizedUnit == null || normalizedUnit.isEmpty || _isPackageLikeUnit(normalizedUnit))) {
    return (
      packQuantity: extracted.packQuantity,
      packUnit: extracted.packUnit,
      packageCount: safeCount,
      totalQuantity: extracted.packQuantity * safeCount,
      totalUnit: extracted.packUnit,
    );
  }

  if (quantity == null || normalizedUnit == null || normalizedUnit.isEmpty) {
    return (
      packQuantity: null,
      packUnit: null,
      packageCount: 1,
      totalQuantity: quantity,
      totalUnit: unit,
    );
  }

  final looksLikePackage = _isPackageLikeUnit(normalizedUnit);

  if (looksLikePackage && extracted != null) {
    return (
      packQuantity: extracted.packQuantity,
      packUnit: extracted.packUnit,
      packageCount: quantity,
      totalQuantity: extracted.packQuantity * quantity,
      totalUnit: extracted.packUnit,
    );
  }

  return (
    packQuantity: quantity,
    packUnit: normalizedUnit,
    packageCount: 1,
    totalQuantity: quantity,
    totalUnit: normalizedUnit,
  );
}

String _formatCompactNumber(double value) {
  if (value == value.roundToDouble()) return value.toStringAsFixed(0);
  final formatted = value.toStringAsFixed(3);
  return formatted
      .replaceFirst(RegExp(r'0+$'), '')
      .replaceFirst(RegExp(r'\.$'), '');
}

String _formatSwedishNumber(double value) {
  return _formatCompactNumber(value).replaceAll('.', ',');
}

double? _convertQuantity(double quantity, String fromUnit, String toUnit) {
  final from = fromUnit.trim().toLowerCase();
  final to = toUnit.trim().toLowerCase();
  if (from.isEmpty || to.isEmpty) return null;
  if (from == to) return quantity;

  // Mass
  if (from == 'mg' && to == 'g') return quantity / 1000.0;
  if (from == 'mg' && to == 'kg') return quantity / 1000000.0;
  if (from == 'mg' && to == 'hg') return quantity / 100000.0;

  if (from == 'g' && to == 'mg') return quantity * 1000.0;
  if (from == 'g' && to == 'hg') return quantity / 100.0;
  if (from == 'g' && to == 'kg') return quantity / 1000.0;

  if (from == 'hg' && to == 'mg') return quantity * 100000.0;
  if (from == 'hg' && to == 'g') return quantity * 100.0;
  if (from == 'hg' && to == 'kg') return quantity / 10.0;

  if (from == 'kg' && to == 'mg') return quantity * 1000000.0;
  if (from == 'kg' && to == 'hg') return quantity * 10.0;
  if (from == 'kg' && to == 'g') return quantity * 1000.0;

  // Volume
  if (from == 'ml' && to == 'l') return quantity / 1000.0;
  if (from == 'cl' && to == 'l') return quantity / 100.0;
  if (from == 'dl' && to == 'l') return quantity / 10.0;
  if (from == 'l' && to == 'ml') return quantity * 1000.0;
  if (from == 'l' && to == 'cl') return quantity * 100.0;
  if (from == 'l' && to == 'dl') return quantity * 10.0;

  // Intra-volume conversions
  if (from == 'ml' && to == 'cl') return quantity / 10.0;
  if (from == 'ml' && to == 'dl') return quantity / 100.0;
  if (from == 'cl' && to == 'ml') return quantity * 10.0;
  if (from == 'cl' && to == 'dl') return quantity / 10.0;
  if (from == 'dl' && to == 'ml') return quantity * 100.0;
  if (from == 'dl' && to == 'cl') return quantity * 10.0;

  return null;
}

/// Konverterar VERSALER-produktnamn till Title Case med smarta regler:
/// - Token med `/` (förkortningar) lämnas i versaler: KY/KAL/LE/TO
/// - Token som börjar med siffra (mängd/storlek) görs till gemener: 284g, 12x85g
/// - Övriga token: första bokstav versal, resten gemen: Aprikosmarmelad
String _normalizeProductName(String raw) {
  return raw.trim().split(' ').map((token) {
    if (token.isEmpty) return token;
    if (token.contains('/')) return token;
    if (RegExp(r'^\d').hasMatch(token)) return token.toLowerCase();
    return token[0].toUpperCase() + token.substring(1).toLowerCase();
  }).join(' ');
}

// ── Redigeringstillstånd per rad ─────────────────────────────────────────────

typedef _ItemEdit = ItemEdit;

// ── Redigeringsdialog ─────────────────────────────────────────────────────────

class _EditDialog extends StatefulWidget {
  final ParsedReceiptItem item;
  final _ItemEdit current;
  final List<ProductOption> products;
  final List<AdminCategoryNode> categoryTree;
  final Future<ProductOption?> Function(String name, int categoryId)? onCreate;
  final _ProductEntryMode? initialEntryMode;

  const _EditDialog({
    required this.item,
    required this.current,
    required this.products,
    required this.categoryTree,
    this.onCreate,
    this.initialEntryMode,
  });

  @override
  State<_EditDialog> createState() => _EditDialogState();
}

class _EditDialogState extends State<_EditDialog> {
  late final TextEditingController _quantityCtrl;
  late final TextEditingController _unitCtrl;
  late final TextEditingController _packageCountCtrl;
  late final TextEditingController _newProductNameCtrl;
  int? _productId;
  String? _productName;
  int? _productCategoryId;
  String? _productCategoryPath;
  CategorySelectionSource? _productCategorySource;
  int? _newCategoryId;
  String? _newCategoryPath;
  CategorySelectionSource? _newCategorySource;
  _Destination _destination = _Destination.inventory;
  _ProductEntryMode _entryMode = _ProductEntryMode.existing;
  bool _isCreatingProduct = false;
  // Lokal lista — utökas om nya produkter skapas under dialogen
  late List<ProductOption> _localProducts;

  @override
  void initState() {
    super.initState();
    _productId = widget.current.productId;
    _productName = widget.current.productName == null
        ? null
        : _normalizeProductName(widget.current.productName!);
    _destination = widget.current.destination;
    _entryMode = widget.initialEntryMode ??
      (_productId == null ? _ProductEntryMode.create : _ProductEntryMode.existing);
    _localProducts = List.of(widget.products);
    _productCategoryId = widget.current.categoryId ?? _categoryIdForProduct(_productId);
    _productCategoryPath = widget.current.categoryPath ?? _categoryPathForCategoryId(_productCategoryId);
    _productCategorySource = widget.current.categorySource;
    _newCategoryId = widget.current.categoryId ?? widget.item.categorySuggestionId;
    _newCategoryPath = widget.current.categoryPath ?? widget.item.categorySuggestionPath;
    _newCategorySource = widget.current.categorySource;
    final inferred = _inferPackageFields(
      rawName: widget.item.rawName,
      quantity: widget.current.quantity ?? widget.item.quantity,
      unit: widget.current.unit ?? widget.item.unit,
    );
    final initialPackQuantity = widget.current.packQuantity ?? inferred.packQuantity;
    final initialPackUnit = widget.current.packUnit ?? inferred.packUnit;
    final initialPackageCount = widget.current.packageCount ?? inferred.packageCount;

    _quantityCtrl = TextEditingController(
      text: initialPackQuantity?.toString() ?? '',
    );
    _unitCtrl = TextEditingController(
      text: initialPackUnit ?? '',
    );
    _packageCountCtrl = TextEditingController(
      text: initialPackageCount.toString(),
    );
    _newProductNameCtrl = TextEditingController(
      text: _normalizeProductName(widget.current.productName ?? widget.item.rawName),
    );
  }

  int? _categoryIdForProduct(int? productId) {
    if (productId == null) return null;
    return _localProducts
        .cast<ProductOption?>()
        .firstWhere((p) => p?.id == productId, orElse: () => null)
        ?.categoryId;
  }

  String? _categoryPathForCategoryId(int? categoryId) {
    if (categoryId == null) return null;

    List<String>? walk(List<AdminCategoryNode> nodes, List<String> parents) {
      for (final node in nodes) {
        final path = [...parents, node.name];
        if (node.id == categoryId) return path;
        final found = walk(node.children, path);
        if (found != null) return found;
      }
      return null;
    }

    return walk(widget.categoryTree, const [])?.join(' > ');
  }

  @override
  void dispose() {
    _quantityCtrl.dispose();
    _unitCtrl.dispose();
    _packageCountCtrl.dispose();
    _newProductNameCtrl.dispose();
    super.dispose();
  }

  Future<void> _openCreateCategoryPicker({int? preselectedCategoryId}) async {
    final selected = await CategoryThenProductPicker.showCategorySheet(
      context,
      categoryTree: widget.categoryTree,
      preselectedCategoryId:
          preselectedCategoryId ?? _newCategoryId ?? widget.item.categorySuggestionId,
    );
    if (selected == null || !mounted) return;
    setState(() {
      _newCategoryId = selected.id;
      _newCategoryPath = selected.path;
      _newCategorySource = CategorySelectionSource.manual;
    });
  }

  Future<void> _openExistingCategoryPicker({int? preselectedCategoryId}) async {
    Future<ProductOption?> Function(String, int)? onCreateWrapped;
    if (widget.onCreate != null) {
      onCreateWrapped = (name, categoryId) async {
        final newProduct = await widget.onCreate!(name, categoryId);
        if (newProduct != null && mounted) {
          setState(() => _localProducts = [..._localProducts, newProduct]);
        }
        return newProduct;
      };
    }

    final id = await CategoryThenProductPicker.show(
      context,
      categoryTree: widget.categoryTree,
      products: _localProducts,
      currentProductId: _productId,
      preselectedCategoryId: preselectedCategoryId,
      initialQuery: widget.item.rawName,
      onCreate: onCreateWrapped,
    );
    if (id != null && mounted) {
      setState(() {
        _productId = id;
        final selectedName = _localProducts
            .cast<ProductOption?>()
            .firstWhere((p) => p?.id == id, orElse: () => null)
            ?.name;
        _productName = selectedName == null ? null : _normalizeProductName(selectedName);
        _productCategoryId = _categoryIdForProduct(id);
        _productCategoryPath = _categoryPathForCategoryId(_productCategoryId);
        _productCategorySource = CategorySelectionSource.manual;
      });
    }
  }

  void _applyAiSuggestionForExistingSelection() {
    final suggestedId = widget.item.suggestedProductId;
    if (suggestedId != null) {
      setState(() {
        _productId = suggestedId;
        _productName = widget.item.suggestedProductName == null
            ? null
            : _normalizeProductName(widget.item.suggestedProductName!);
        _productCategoryId = _categoryIdForProduct(suggestedId) ?? widget.item.categorySuggestionId;
        _productCategoryPath =
            _categoryPathForCategoryId(_productCategoryId) ?? widget.item.categorySuggestionPath;
        _productCategorySource = CategorySelectionSource.ai;
      });
      return;
    }

    _openExistingCategoryPicker(
      preselectedCategoryId: widget.item.categorySuggestionId,
    );
  }

  bool get _canConfirm {
    if (_isCreatingProduct) return false;
    if (_entryMode == _ProductEntryMode.create) return true;
    return _productId != null;
  }

  Future<void> _confirm() async {
    if (_entryMode == _ProductEntryMode.create) {
      final trimmedName = _newProductNameCtrl.text.trim();
      if (trimmedName.isEmpty) {
        showGlobalErrorDialog(context, 'Ange ett produktnamn först.');
        return;
      }

      if (_newCategoryId == null) {
        showGlobalErrorDialog(context, 'Välj kategori innan du skapar produkten.');
        return;
      }

      if (widget.onCreate == null) {
        showGlobalErrorDialog(context, 'Produktskapande är inte tillgängligt i den här vyn.');
        return;
      }

      setState(() => _isCreatingProduct = true);
      try {
        final newProduct = await widget.onCreate!(
          trimmedName,
          _newCategoryId!,
        );
        if (newProduct == null || !mounted) {
          if (mounted) {
            showGlobalErrorDialog(context, 'Kunde inte skapa produkten. Försök igen.');
          }
          return;
        }
        if (!_localProducts.any((p) => p.id == newProduct.id)) {
          _localProducts = [..._localProducts, newProduct];
        }
        _productId = newProduct.id;
        _productName = newProduct.name;
        _productCategoryId = _newCategoryId;
        _productCategoryPath = _newCategoryPath;
        _productCategorySource = _newCategorySource ?? CategorySelectionSource.manual;
      } on ApiException catch (e) {
        if (mounted) {
          showGlobalErrorDialog(
            context,
            e.message.trim().isEmpty
                ? 'Kunde inte skapa produkten. Försök igen.'
                : e.message,
          );
        }
        return;
      } catch (_) {
        if (mounted) {
          showGlobalErrorDialog(context, 'Kunde inte skapa produkten. Försök igen.');
        }
        return;
      } finally {
        if (mounted) setState(() => _isCreatingProduct = false);
      }
      if (!mounted || _productId == null) return;
    }

    final packQuantity = double.tryParse(_quantityCtrl.text.replaceAll(',', '.'));
    final packageCount =
        double.tryParse(_packageCountCtrl.text.replaceAll(',', '.')) ?? 1.0;
    final packUnit = _unitCtrl.text.trim().isEmpty
        ? (widget.current.packUnit ?? widget.current.unit ?? widget.item.unit)
        : _unitCtrl.text.trim();
    final totalQuantity = packQuantity != null ? packQuantity * packageCount : widget.item.quantity;

    Navigator.pop(
      context,
      _ItemEdit(
        productId: _productId,
        productName: _productName,
        categoryId: _productCategoryId,
        categoryPath: _productCategoryPath,
        categorySource: _productCategorySource,
        quantity: totalQuantity,
        unit: packUnit,
        packQuantity: packQuantity,
        packUnit: packUnit,
        packageCount: packageCount,
        destination: _destination,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final item = widget.item;
    final aiCategory = item.categorySuggestionName;
    final aiPath = item.categorySuggestionPath;
    final aiLabel = (aiPath != null && aiPath.isNotEmpty)
        ? aiPath
        : ((aiCategory != null && aiCategory.isNotEmpty) ? aiCategory : null);
    final suggestedProductLabel = item.suggestedProductName?.isNotEmpty == true
        ? _normalizeProductName(item.suggestedProductName!)
        : (item.matchedProductName?.isNotEmpty == true
            ? _normalizeProductName(item.matchedProductName!)
            : null);
    final currentPackQuantity =
      double.tryParse(_quantityCtrl.text.replaceAll(',', '.'));
    final currentPackageCount =
      double.tryParse(_packageCountCtrl.text.replaceAll(',', '.')) ?? 1.0;
    final currentUnit = _unitCtrl.text.trim().isEmpty
      ? (widget.current.packUnit ?? widget.current.unit ?? widget.item.unit)
      : _unitCtrl.text.trim();
    final totalPreview =
      currentPackQuantity == null ? null : currentPackQuantity * currentPackageCount;

    return AlertDialog(
      title: Text(
        _normalizeProductName(item.rawName),
        maxLines: 2,
        overflow: TextOverflow.ellipsis,
      ),
      content: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Destination
            SegmentedButton<_Destination>(
              segments: const [
                ButtonSegment(
                  value: _Destination.inventory,
                  icon: Icon(Icons.kitchen_outlined, size: 16),
                  label: Text('Inventarie'),
                ),
                ButtonSegment(
                  value: _Destination.pantry,
                  icon: Icon(Icons.inventory_2_outlined, size: 16),
                  label: Text('Baslager'),
                ),
              ],
              selected: {_destination},
              onSelectionChanged: (s) => setState(() => _destination = s.first),
              style: const ButtonStyle(visualDensity: VisualDensity.compact),
            ),
            const SizedBox(height: 12),
            // Produktval: befintlig produkt eller skapa ny från importnamnet
            SegmentedButton<_ProductEntryMode>(
              segments: const [
                ButtonSegment(
                  value: _ProductEntryMode.existing,
                  icon: Icon(Icons.search, size: 16),
                  label: Text('Befintlig'),
                ),
                ButtonSegment(
                  value: _ProductEntryMode.create,
                  icon: Icon(Icons.add_box_outlined, size: 16),
                  label: Text('Ny produkt'),
                ),
              ],
              selected: {_entryMode},
              onSelectionChanged: (s) => setState(() => _entryMode = s.first),
              style: const ButtonStyle(visualDensity: VisualDensity.compact),
            ),
            const SizedBox(height: 12),
            if (_entryMode == _ProductEntryMode.existing)
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  if (suggestedProductLabel != null) ...[
                    Tooltip(
                      message: 'Trolig matchning baserat på produktnamn i databasen',
                      child: ActionChip(
                        avatar: Icon(
                          Icons.search,
                          size: 14,
                          color: Colors.blue.shade700,
                        ),
                        label: Text(
                          'Namnförslag: $suggestedProductLabel',
                          style: theme.textTheme.labelSmall,
                        ),
                        backgroundColor: Colors.blue.shade50,
                        side: BorderSide(color: Colors.blue.shade300),
                        visualDensity: VisualDensity.compact,
                        onPressed: _applyAiSuggestionForExistingSelection,
                      ),
                    ),
                    const SizedBox(height: 8),
                  ],
                  Row(
                    children: [
                      Expanded(
                        child: ProductPickerField(
                          products: _localProducts,
                          value: _productId,
                          label: 'Produkt',
                          initialQuery: item.rawName,
                          onChanged: (id) {
                            setState(() {
                              _productId = id;
                              final selectedName = id == null
                                ? null
                                : _localProducts
                                  .cast<ProductOption?>()
                                  .firstWhere((p) => p?.id == id, orElse: () => null)
                                  ?.name;
                              _productName = selectedName == null
                                ? null
                                : _normalizeProductName(selectedName);
                              _productCategoryId = _categoryIdForProduct(id);
                              _productCategoryPath = _categoryPathForCategoryId(_productCategoryId);
                              _productCategorySource =
                                  id == null ? null : CategorySelectionSource.manual;
                            });
                          },
                        ),
                      ),
                      const SizedBox(width: 8),
                      Tooltip(
                        message: 'Välj via kategori',
                        child: OutlinedButton(
                          style: OutlinedButton.styleFrom(
                            minimumSize: const Size(44, 56),
                            padding: EdgeInsets.zero,
                          ),
                          onPressed: () => _openExistingCategoryPicker(),
                          child: const Icon(Icons.account_tree_outlined, size: 20),
                        ),
                      ),
                    ],
                  ),
                  if (_productCategoryPath != null) ...[
                    const SizedBox(height: 8),
                    ActionChip(
                      avatar: Icon(
                        Icons.account_tree_outlined,
                        size: 14,
                        color: theme.colorScheme.primary,
                      ),
                      label: Text(
                        'Kategori: $_productCategoryPath',
                        style: theme.textTheme.labelSmall,
                        overflow: TextOverflow.ellipsis,
                      ),
                      side: BorderSide(color: theme.colorScheme.outlineVariant),
                      visualDensity: VisualDensity.compact,
                      onPressed: () => _openExistingCategoryPicker(
                        preselectedCategoryId: _productCategoryId,
                      ),
                    ),
                  ],
                  if (aiLabel != null) ...[
                    const SizedBox(height: 8),
                    ActionChip(
                      avatar: Icon(
                        Icons.auto_awesome,
                        size: 14,
                        color: Colors.green.shade700,
                      ),
                      label: Text(
                        'AI-kategori: $aiLabel',
                        style: theme.textTheme.labelSmall,
                      ),
                      backgroundColor: Colors.green.shade50,
                      side: BorderSide(color: Colors.green.shade300),
                      visualDensity: VisualDensity.compact,
                      onPressed: _applyAiSuggestionForExistingSelection,
                    ),
                  ],
                ],
              )
            else ...[
              TextField(
                controller: _newProductNameCtrl,
                textCapitalization: TextCapitalization.sentences,
                decoration: const InputDecoration(
                  labelText: 'Produktnamn',
                  border: OutlineInputBorder(),
                ),
                onChanged: (_) => setState(() {}),
              ),
              const SizedBox(height: 8),
              SizedBox(
                width: double.infinity,
                child: OutlinedButton.icon(
                  onPressed: _openCreateCategoryPicker,
                  icon: const Icon(Icons.account_tree_outlined),
                  label: Text(
                    _newCategoryPath == null
                        ? 'Välj kategori'
                        : 'Kategori: $_newCategoryPath',
                    overflow: TextOverflow.ellipsis,
                  ),
                ),
              ),
              if (_newCategoryPath != null) ...[
                const SizedBox(height: 8),
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: theme.colorScheme.surfaceContainerHighest,
                    borderRadius: BorderRadius.circular(12),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Vald kategori',
                        style: theme.textTheme.labelSmall?.copyWith(
                          color: theme.colorScheme.onSurfaceVariant,
                        ),
                      ),
                      const SizedBox(height: 4),
                      Text(
                        _newCategoryPath!,
                        style: theme.textTheme.bodyMedium?.copyWith(
                          fontWeight: FontWeight.w600,
                        ),
                      ),
                    ],
                  ),
                ),
                if (aiLabel != null) ...[
                  const SizedBox(height: 8),
                  Wrap(
                    children: [
                      ActionChip(
                        avatar: Icon(
                          Icons.auto_awesome,
                          size: 14,
                          color: Colors.green.shade700,
                        ),
                        label: Text(
                          'AI-forslag: $aiLabel',
                          style: theme.textTheme.labelSmall,
                        ),
                        backgroundColor: Colors.green.shade50,
                        side: BorderSide(color: Colors.green.shade300),
                        visualDensity: VisualDensity.compact,
                        onPressed: item.categorySuggestionId == null
                            ? null
                            : () => _openCreateCategoryPicker(
                                  preselectedCategoryId: item.categorySuggestionId,
                                ),
                      ),
                    ],
                  ),
                ],
              ],
            ],
            const SizedBox(height: 12),
            if (_destination == _Destination.inventory) ...[
              Row(children: [
                Expanded(
                  child: TextField(
                    controller: _quantityCtrl,
                    keyboardType: const TextInputType.numberWithOptions(decimal: true),
                    decoration: const InputDecoration(
                      labelText: 'Mängd per förpackning',
                      border: OutlineInputBorder(),
                    ),
                    onChanged: (_) => setState(() {}),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: TextField(
                    controller: _unitCtrl,
                    decoration: const InputDecoration(
                      labelText: 'Enhet',
                      border: OutlineInputBorder(),
                    ),
                    onChanged: (_) => setState(() {}),
                  ),
                ),
              ]),
              const SizedBox(height: 8),
              TextField(
                controller: _packageCountCtrl,
                keyboardType: const TextInputType.numberWithOptions(decimal: true),
                decoration: const InputDecoration(
                  labelText: 'Antal förpackningar',
                  border: OutlineInputBorder(),
                ),
                onChanged: (_) => setState(() {}),
              ),
              if (totalPreview != null && currentUnit != null && currentUnit.isNotEmpty) ...[
                const SizedBox(height: 8),
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.all(10),
                  decoration: BoxDecoration(
                    color: Colors.green.shade50,
                    borderRadius: BorderRadius.circular(10),
                    border: Border.all(color: Colors.green.shade200),
                  ),
                  child: Text(
                    'Totalt: ${_formatSwedishNumber(totalPreview)} $currentUnit '
                    '(mängd x antal förpackningar).',
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: Colors.green.shade800,
                    ),
                  ),
                ),
              ],
            ] else ...[
              Text(
                'Baslager sparar bara produkt — ingen mängd eller enhet.',
                style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.onSurfaceVariant),
              ),
            ],
          ],
        ),
      ),
      actions: [
        TextButton(onPressed: () => Navigator.pop(context), child: const Text('Avbryt')),
        FilledButton(
          onPressed: _canConfirm ? _confirm : null,
          child: _isCreatingProduct
              ? const SizedBox(
                  width: 18,
                  height: 18,
                  child: CircularProgressIndicator(strokeWidth: 2),
                )
              : Text(_entryMode == _ProductEntryMode.create ? 'Skapa och välj' : 'OK'),
        ),
      ],
    );
  }
}

// ── Huvudwidget ───────────────────────────────────────────────────────────────

class ReceiptImportTab extends ConsumerStatefulWidget {
  const ReceiptImportTab({super.key});

  @override
  ConsumerState<ReceiptImportTab> createState() => _ReceiptImportTabState();
}

class _ReceiptImportTabState extends ConsumerState<ReceiptImportTab> {
  bool _isLoading = false;
  bool _isSaving = false;
  PlatformFile? _pickedFile;

  // Session-state lyfts till provider — överlever tabbyte
  ReceiptImportSession? get _session => ref.read(receiptImportSessionProvider);
  List<ParsedReceiptItem>? get _items => _session?.items;
  Map<int, _ItemEdit> get _edits => _session?.edits ?? {};
  Map<int, bool> get _selected => _session?.selected ?? {};

  // Produktlistan för pickern
  List<ProductOption> _products = [];

  // Kategoriträdet för tvåstegs-picker
  List<AdminCategoryNode> _categoryTree = [];

  // Befintligt inventarie: productId → InventoryItem (för sammanslagning)
  Map<int, InventoryItem> _inventoryByProduct = {};

  // Befintligt baslager: productId → PantryItem (för deduplicering)
  Set<int> _pantryProductIds = {};

  @override
  void initState() {
    super.initState();
    _loadProducts();
  }

  int? _categoryIdForProduct(int? productId) {
    if (productId == null) return null;
    return _products
        .cast<ProductOption?>()
        .firstWhere((p) => p?.id == productId, orElse: () => null)
        ?.categoryId;
  }

  String? _categoryPathForCategoryId(int? categoryId) {
    if (categoryId == null) return null;

    List<String>? walk(List<AdminCategoryNode> nodes, List<String> parents) {
      for (final node in nodes) {
        final path = [...parents, node.name];
        if (node.id == categoryId) return path;
        final found = walk(node.children, path);
        if (found != null) return found;
      }
      return null;
    }

    return walk(_categoryTree, const [])?.join(' > ');
  }

  Future<void> _loadProducts() async {
    try {
      final token = await ref.read(authStateProvider.future);
      final api = ref.read(apiClientProvider);
      final adminRepo = ref.read(adminRepositoryProvider);
      final results = await Future.wait([
        api.getJson(ProductApiPaths.list, token: token),
        api.getJson(ProductApiPaths.mine, token: token),
        adminRepo.listCategoryTree(),
      ]);
      final globalData = results[0];
      final mineData = results[1];
      final globalList = globalData is List
          ? globalData
          : ((globalData as Map<String, dynamic>?)?['items'] as List? ?? []);
      final mineList = mineData is List
          ? mineData
          : ((mineData as Map<String, dynamic>?)?['items'] as List? ?? []);
      if (mounted) {
        final mergedProducts = [
          ...globalList
              .cast<Map<String, dynamic>>()
              .map((e) => (id: e['id'] as int, name: (e['canonicalName'] ?? e['name']) as String, categoryId: (e['categoryId'] as num?)?.toInt())),
          ...mineList
              .cast<Map<String, dynamic>>()
              .map((e) => (id: e['id'] as int, name: (e['canonicalName'] ?? e['name']) as String, categoryId: (e['categoryId'] as num?)?.toInt())),
        ];
        final dedupedById = <int, ProductOption>{
          for (final product in mergedProducts) product.id: product,
        };

        setState(() {
          _products = dedupedById.values.toList();
          _categoryTree = results[2] as List<AdminCategoryNode>;
        });
      }
    } catch (e, st) {
      debugPrint('ReceiptImportTab._loadProducts failed: $e');
      debugPrintStack(stackTrace: st);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Kunde inte ladda produktlistan. Försök igen.')),
        );
      }
    }
  }

  Future<void> _loadInventory() async {
    try {
      final token = await ref.read(authStateProvider.future);
      final invRepo = ref.read(inventoryRepositoryProvider);
      final pantryRepo = ref.read(pantryRepositoryProvider);
      final results = await Future.wait([
        invRepo.fetchInventory(token: token),
        pantryRepo.fetchPantry(token: token),
      ]);
      if (mounted) {
        setState(() {
          _inventoryByProduct = {
            for (final item in results[0] as List<InventoryItem>) item.productId: item,
          };
          _pantryProductIds = {
            for (final item in results[1] as List<PantryItem>) item.productId,
          };
        });
      }
    } catch (_) {
      // Tyst fel — sammanslagningsfunktionen är valfri
    }
  }

  Future<void> _pickFile() async {
    final result = await FilePicker.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['pdf', 'png', 'jpg', 'jpeg', 'webp', 'bmp'],
      withData: true,
    );
    if (result == null || result.files.isEmpty) return;
    final file = result.files.first;
    setState(() => _pickedFile = file);
    // Spara bildbytes i session så att förhandsvisningen överlever tabbyte
    ref.read(receiptImportSessionProvider.notifier).setFile(
      file.bytes!,
      file.extension?.toLowerCase() ?? '',
    );
  }

  Future<void> _submit() async {
    if (_pickedFile == null) return;
    setState(() { _isLoading = true; });
    // Obs: setFile() i _pickFile har redan placerat bytes i session; clear() behövs ej här

    try {
      final token = await ref.read(authStateProvider.future);
      final repo = ref.read(importRepositoryProvider);
      final items = await repo.importReceiptFile(
        bytes: _pickedFile!.bytes!,
        filename: _pickedFile!.name,
        token: token,
      );
      if (!mounted) return;
      final notifier = ref.read(receiptImportSessionProvider.notifier);
      notifier.setItems(items);
      // Förmarkera rader som har en träff
      for (var i = 0; i < items.length; i++) {
        final it = items[i];
        final pid = it.matchedProductId ?? it.suggestedProductId;
        notifier.setSelected(i, pid != null);
        if (pid != null) {
          final inferred = _inferPackageFields(
            rawName: it.rawName,
            quantity: it.quantity,
            unit: it.unit,
          );
          final name = it.matchedProductName ?? it.suggestedProductName;
          final resolvedCategoryId = it.categorySuggestionId ?? _categoryIdForProduct(pid);
          final resolvedCategoryPath = it.categorySuggestionPath ??
              _categoryPathForCategoryId(resolvedCategoryId);
          notifier.setEdit(i, _ItemEdit(
            productId: pid,
            productName: name,
            categoryId: resolvedCategoryId,
            categoryPath: resolvedCategoryPath,
            categorySource: it.categorySuggestionId != null
                ? CategorySelectionSource.ai
                : null,
            quantity: inferred.totalQuantity,
            unit: inferred.totalUnit,
            packQuantity: inferred.packQuantity,
            packUnit: inferred.packUnit,
            packageCount: inferred.packageCount,
          ));
        }
      }
      // Ladda inventariet för att visa befintliga poster och möjliggöra sammanslagning
      await _loadInventory();
    } catch (e) {
      if (mounted) showGlobalErrorDialog(context, 'Ett fel uppstod vid import: $e');
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  Future<void> _openEditDialog(
    int index, {
    _ProductEntryMode? initialEntryMode,
  }) async {
    final item = _items![index];
    final inferred = _inferPackageFields(
      rawName: item.rawName,
      quantity: item.quantity,
      unit: item.unit,
    );
    final current = _edits[index] ??
        _ItemEdit(
          productId: item.matchedProductId ?? item.suggestedProductId,
          productName: item.matchedProductName ?? item.suggestedProductName,
        categoryId: item.categorySuggestionId ??
          _categoryIdForProduct(item.matchedProductId ?? item.suggestedProductId),
        categoryPath: item.categorySuggestionPath ??
          _categoryPathForCategoryId(
          item.categorySuggestionId ??
            _categoryIdForProduct(item.matchedProductId ?? item.suggestedProductId),
          ),
          categorySource: item.categorySuggestionId != null
              ? CategorySelectionSource.ai
              : null,
          quantity: inferred.totalQuantity,
          unit: inferred.totalUnit,
          packQuantity: inferred.packQuantity,
          packUnit: inferred.packUnit,
          packageCount: inferred.packageCount,
        );

    final result = await showDialog<_ItemEdit>(
      context: context,
      builder: (_) => _EditDialog(
        item: item,
        current: current,
        products: _products,
        categoryTree: _categoryTree,
        initialEntryMode: initialEntryMode,
        onCreate: (name, categoryId) async {
          final token = await ref.read(authStateProvider.future);
          final api = ref.read(apiClientProvider);
          final raw = await api.postJson(
            ProductApiPaths.createPrivate,
            body: {
              'name': name.trim(),
              'categoryId': categoryId,
            },
            token: token,
          );

          if (raw is! Map<String, dynamic>) {
            throw Exception('Ogiltigt API-svar vid produktskapande.');
          }

          final idRaw = raw['id'];
          if (idRaw is! num) {
            throw Exception('API-svar saknar giltigt produkt-id.');
          }

          final displayNameRaw = raw['canonicalName'] ?? raw['name'];
          final displayName = displayNameRaw?.toString().trim();
          if (displayName == null || displayName.isEmpty) {
            throw Exception('API-svar saknar produktnamn.');
          }

          final returnedCategoryId = raw['categoryId'] is num
              ? (raw['categoryId'] as num).toInt()
              : categoryId;

          final newProduct = (
            id: idRaw.toInt(),
            name: displayName,
            categoryId: returnedCategoryId,
          );

          if (mounted) setState(() => _products = [..._products, newProduct]);
          return newProduct;
        },
      ),
    );
    if (result != null && mounted) {
      ref.read(receiptImportSessionProvider.notifier).setEdit(index, result);
      ref.read(receiptImportSessionProvider.notifier).setSelected(index, true);
      setState(() {});
    }
  }

  Future<void> _addSelected() async {
    final items = _items;
    if (items == null) return;

    final toAdd = <int>[];
    for (var i = 0; i < items.length; i++) {
      if (_selected[i] == true && _edits[i]?.productId != null) toAdd.add(i);
    }
    if (toAdd.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Välj produkter för alla markerade rader först.')),
      );
      return;
    }

    setState(() => _isSaving = true);
    int created = 0;
    int merged = 0;
    int pantryAdded = 0;
    int pantrySkipped = 0;
    try {
      final token = await ref.read(authStateProvider.future);
      final invRepo = ref.read(inventoryRepositoryProvider);
      final pantryRepo = ref.read(pantryRepositoryProvider);

      for (final i in toAdd) {
        final edit = _edits[i]!;
        final item = items[i];
        final pid = edit.productId!;

        if (edit.destination == _Destination.pantry) {
          if (_pantryProductIds.contains(pid)) {
            pantrySkipped++;
          } else {
            await pantryRepo.createPantryItem(pid, token: token);
            pantryAdded++;
          }
        } else {
          final inferred = _inferPackageFields(
            rawName: item.rawName,
            quantity: edit.quantity ?? item.quantity,
            unit: edit.unit ?? item.unit,
          );
          final packageCount = edit.packageCount ?? inferred.packageCount;
          final packQuantity = edit.packQuantity ?? inferred.packQuantity;
          final packUnit = edit.packUnit ?? inferred.packUnit ?? edit.unit ?? item.unit ?? 'st';
          final qty = packQuantity != null
              ? (packQuantity * packageCount)
              : (edit.quantity ?? inferred.totalQuantity ?? item.quantity ?? 1.0);
          final unit = packUnit;
          final existing = _inventoryByProduct[pid];
          final qtyInExistingUnit = existing == null
              ? null
              : _convertQuantity(qty, unit, existing.unit);
          if (existing != null && qtyInExistingUnit != null) {
            await invRepo.updateInventoryItem(
              existing.id,
              {'quantity': existing.quantity + qtyInExistingUnit},
              token: token,
            );
            merged++;
          } else {
            await invRepo.createInventoryItem({
              'productId': pid,
              'quantity': qty,
              'unit': unit,
              if (item.brand != null) 'brand': item.brand,
            }, token: token);
            created++;
          }
        }
      }

      if (!mounted) return;
      final parts = <String>[
        if (created > 0) '$created ny${created == 1 ? '' : 'a'} i inventarie',
        if (merged > 0) '$merged ${merged == 1 ? 'sammanslagen' : 'sammanslagna'} i inventarie',
        if (pantryAdded > 0) '$pantryAdded tillagd${pantryAdded == 1 ? '' : 'a'} i baslager',
        if (pantrySkipped > 0) '$pantrySkipped fanns redan i baslager',
      ];
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(parts.join(', ') + '.')),
      );
      // Avmarkera sparade rader och uppdatera inventariet
      final notifier = ref.read(receiptImportSessionProvider.notifier);
      for (final i in toAdd) notifier.setSelected(i, false);
      setState(() {});
      await _loadInventory();
    } catch (e) {
      if (mounted) showGlobalErrorDialog(context, 'Fel vid sparande: $e');
    } finally {
      if (mounted) setState(() => _isSaving = false);
    }
  }

  bool get _canSubmit => !_isLoading && _pickedFile?.bytes != null;
  int get _selectedCount => _selected.values.where((v) => v).length;

  // ── Kvittobild / PDF-förhandsvisning ───────────────────────────────────────

  Widget _buildReceiptPreview(ThemeData theme, ReceiptImportSession session) {
    final bytes = session.fileBytes!;
    final ext = session.fileExtension ?? '';
    final isImage = ['png', 'jpg', 'jpeg', 'webp', 'bmp'].contains(ext);

    return Card(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          ListTile(
            dense: true,
            leading: Icon(
              isImage ? Icons.image_outlined : Icons.picture_as_pdf_outlined,
              color: theme.colorScheme.primary,
            ),
            title: const Text('Kvittoförhandsvisning'),
            trailing: isImage
                ? null
                : OutlinedButton.icon(
                    icon: const Icon(Icons.open_in_new, size: 16),
                    label: const Text('Visa kvitto'),
                    style: OutlinedButton.styleFrom(visualDensity: VisualDensity.compact),
                    onPressed: () async {
                      final opened = await openPdfBytes(bytes);
                      if (!context.mounted || opened) return;
                      ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(
                          content: Text('PDF kan bara öppnas direkt i webbversionen just nu.'),
                        ),
                      );
                    },
                  ),
          ),
          if (isImage)
            Padding(
              padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(8),
                child: ConstrainedBox(
                  constraints: const BoxConstraints(maxHeight: 600),
                  child: Image.memory(bytes, fit: BoxFit.contain),
                ),
              ),
            )
          else
            const SizedBox(height: 8),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final session = ref.watch(receiptImportSessionProvider);
    final theme = Theme.of(context);
    final items = session?.items;

    return SingleChildScrollView(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Ladda upp ett kvitto (PDF eller bild) — raderna tolkas och kan läggas till i ditt inventarie.',
            style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.onSurfaceVariant),
          ),
          const SizedBox(height: 20),
          OutlinedButton.icon(
            onPressed: _isLoading ? null : _pickFile,
            icon: const Icon(Icons.attach_file),
            label: Text(_pickedFile == null ? 'Välj kvittofil' : _pickedFile!.name),
          ),
          if (_pickedFile != null) ...[
            const SizedBox(height: 8),
            Text(
              '${(_pickedFile!.size / 1024).round()} KB',
              style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.outline),
            ),
          ],
          // ── Förhandsvisning av kvitto ────────────────────────────────────────
          if (session?.fileBytes != null) ...[
            const SizedBox(height: 12),
            _buildReceiptPreview(theme, session!),
          ],
          const SizedBox(height: 24),
          if (_isLoading) ...[
            const LinearProgressIndicator(),
            const SizedBox(height: 8),
            Text(
              'Tolkar kvittot — detta kan ta upp till en minut...',
              style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.onSurfaceVariant),
            ),
            const SizedBox(height: 16),
          ],
          FilledButton.icon(
            onPressed: _canSubmit ? _submit : null,
            icon: const Icon(Icons.receipt_long_outlined),
            label: const Text('Importera kvitto'),
          ),
          // ── Resultatlista ──────────────────────────────────────────────
          if (items != null) ...[
            const SizedBox(height: 24),
            const Divider(),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text('${items.length} rader — tryck för att redigera', style: theme.textTheme.titleSmall),
                TextButton(
                  onPressed: () => setState(() {
                    final notifier = ref.read(receiptImportSessionProvider.notifier);
                    for (var i = 0; i < items.length; i++) {
                      notifier.setSelected(i, _selectedCount < items.length);
                    }
                  }),
                  child: Text(_selectedCount < items.length ? 'Välj alla' : 'Avmarkera alla'),
                ),
              ],
            ),
            const SizedBox(height: 4),
            ...List.generate(items.length, (i) {
              final item = items[i];
              final edit = _edits[i];
              final isChecked = _selected[i] ?? false;
              final hasProduct = edit?.productId != null;
              final isMatched = item.matchedProductId != null;
              final isSuggested = item.suggestedProductId != null && item.matchedProductId == null;
                final existingInv = edit?.productId != null && edit?.destination != _Destination.pantry
                  ? _inventoryByProduct[edit!.productId]
                  : null;
                final inferredForPreview = _inferPackageFields(
                rawName: item.rawName,
                quantity: edit?.quantity ?? item.quantity,
                unit: edit?.unit ?? item.unit,
                );
                final previewPackageCount = edit?.packageCount ?? inferredForPreview.packageCount;
                final previewPackQuantity = edit?.packQuantity ?? inferredForPreview.packQuantity;
                final previewIncomingQty = previewPackQuantity != null
                  ? (previewPackQuantity * previewPackageCount)
                  : (edit?.quantity ?? inferredForPreview.totalQuantity ?? item.quantity ?? 0);
                final previewIncomingUnit = edit?.packUnit ??
                  inferredForPreview.packUnit ??
                  edit?.unit ??
                  item.unit ??
                  'st';
                final convertedPreviewQty = existingInv == null
                  ? null
                  : _convertQuantity(
                    previewIncomingQty,
                    previewIncomingUnit,
                    existingInv.unit,
                  );
                final canMergePreview = existingInv != null && convertedPreviewQty != null;
              final alreadyInPantry = edit?.productId != null && edit?.destination == _Destination.pantry
                  ? _pantryProductIds.contains(edit!.productId)
                  : false;

              return Card(
                margin: const EdgeInsets.symmetric(vertical: 3),
                child: ListTile(
                  leading: Checkbox(
                    value: isChecked,
                    onChanged: (v) {
                      ref.read(receiptImportSessionProvider.notifier).setSelected(i, v ?? false);
                      setState(() {});
                    },
                  ),
                  title: Text(
                    _normalizeProductName(item.rawName),
                    style: theme.textTheme.bodyMedium,
                  ),
                  subtitle: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        [
                          if ((edit?.quantity ?? item.quantity) != null)
                            '${edit?.quantity ?? item.quantity}',
                          if ((edit?.unit ?? item.unit) != null)
                            edit?.unit ?? item.unit!,
                          if (item.price != null) '· ${item.price} kr',
                        ].join(' '),
                        style: theme.textTheme.bodySmall,
                      ),
                      const SizedBox(height: 2),
                      if (hasProduct)
                        Wrap(
                          spacing: 6,
                          runSpacing: 4,
                          crossAxisAlignment: WrapCrossAlignment.center,
                          children: [
                            Text(
                              'Produktnamn: ${_normalizeProductName(edit!.productName ?? '')}',
                              style: theme.textTheme.bodySmall?.copyWith(
                                color: isMatched ? Colors.green.shade700 : theme.colorScheme.primary,
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                            if (edit.categorySource != null)
                              Container(
                                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
                                decoration: BoxDecoration(
                                  color: edit.categorySource == CategorySelectionSource.ai
                                      ? Colors.green.shade50
                                      : theme.colorScheme.surfaceContainerHighest,
                                  borderRadius: BorderRadius.circular(999),
                                  border: Border.all(
                                    color: edit.categorySource == CategorySelectionSource.ai
                                        ? Colors.green.shade300
                                        : theme.colorScheme.outlineVariant,
                                  ),
                                ),
                                child: Text(
                                  edit.categorySource == CategorySelectionSource.ai ? 'AI' : 'Manuell',
                                  style: theme.textTheme.labelSmall?.copyWith(
                                    color: edit.categorySource == CategorySelectionSource.ai
                                        ? Colors.green.shade800
                                        : theme.colorScheme.onSurfaceVariant,
                                  ),
                                ),
                              ),
                          ],
                        )
                      else if (isSuggested)
                        Text('Namnförslag: ${_normalizeProductName(item.suggestedProductName ?? '')}',
                            style: theme.textTheme.bodySmall?.copyWith(color: Colors.orange.shade700))
                      else
                        Text('Ingen matchning ännu — tryck för att välja eller skapa produkt',
                            style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.tertiary)),
                      if (hasProduct && edit?.categoryPath != null) ...[
                        const SizedBox(height: 2),
                        Text(
                          'Kategori: ${edit!.categoryPath!}',
                          style: theme.textTheme.bodySmall?.copyWith(
                            color: theme.colorScheme.onSurfaceVariant,
                          ),
                        ),
                      ],
                      if (!hasProduct && !isSuggested) ...[
                        const SizedBox(height: 8),
                        Wrap(
                          spacing: 8,
                          runSpacing: 8,
                          children: [
                            OutlinedButton.icon(
                              onPressed: () => _openEditDialog(
                                i,
                                initialEntryMode: _ProductEntryMode.existing,
                              ),
                              icon: const Icon(Icons.search, size: 16),
                              label: const Text('Välj befintlig'),
                              style: OutlinedButton.styleFrom(
                                visualDensity: VisualDensity.compact,
                                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                              ),
                            ),
                            OutlinedButton.icon(
                              onPressed: () => _openEditDialog(
                                i,
                                initialEntryMode: _ProductEntryMode.create,
                              ),
                              icon: const Icon(Icons.add_box_outlined, size: 16),
                              label: const Text('Ny produkt'),
                              style: OutlinedButton.styleFrom(
                                visualDensity: VisualDensity.compact,
                                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                              ),
                            ),
                          ],
                        ),
                      ],
                      if (existingInv != null && canMergePreview) ...[
                        const SizedBox(height: 2),
                        Row(children: [
                          Icon(Icons.kitchen_outlined, size: 12, color: Colors.blue.shade700),
                          const SizedBox(width: 3),
                          Text(
                            'I lager: ${existingInv.quantity} ${existingInv.unit} → blir ${(existingInv.quantity + (convertedPreviewQty ?? 0)).toStringAsFixed(existingInv.quantity % 1 == 0 ? 0 : 2)} ${existingInv.unit}',
                            style: theme.textTheme.bodySmall?.copyWith(color: Colors.blue.shade700),
                          ),
                        ]),
                      ],
                      if (existingInv != null && !canMergePreview) ...[
                        const SizedBox(height: 2),
                        Row(children: [
                          Icon(Icons.info_outline, size: 12, color: Colors.orange.shade700),
                          const SizedBox(width: 3),
                          Text(
                            'Finns i lager med annan enhet (${existingInv.unit}) - sparas som ny rad',
                            style: theme.textTheme.bodySmall?.copyWith(color: Colors.orange.shade700),
                          ),
                        ]),
                      ],
                      if (alreadyInPantry) ...[
                        const SizedBox(height: 2),
                        Row(children: [
                          Icon(Icons.inventory_2_outlined, size: 12, color: Colors.orange.shade700),
                          const SizedBox(width: 3),
                          Text('Finns redan i baslager',
                              style: theme.textTheme.bodySmall?.copyWith(color: Colors.orange.shade700)),
                        ]),
                      ],
                    ],
                  ),
                  trailing: Icon(
                    hasProduct ? Icons.check_circle : (isSuggested ? Icons.help_outline : Icons.error_outline),
                    color: hasProduct
                        ? Colors.green
                        : (isSuggested ? Colors.orange : theme.colorScheme.tertiary),
                    size: 20,
                  ),
                  onTap: () => _openEditDialog(i),
                ),
              );
            }),
            const SizedBox(height: 16),
            SizedBox(
              width: double.infinity,
              child: FilledButton.icon(
                onPressed: (_selectedCount > 0 && !_isSaving) ? _addSelected : null,
                icon: _isSaving
                    ? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white))
                    : const Icon(Icons.add_shopping_cart),
                label: Text(_selectedCount > 0 ? 'Lägg till $_selectedCount markerade' : 'Markera rader att lägga till'),
              ),
            ),
          ],
        ],
      ),
    );
  }
}

