import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/api/api_error_mapper.dart';
import '../../../core/api/api_paths.dart';
import '../../../core/api/api_providers.dart';
import '../../../core/ui/product_picker_field.dart';
import '../../../core/utils/global_error_handler.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 '../domain/parsed_receipt_item.dart';

enum _Destination { inventory, pantry }

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

class _ItemEdit {
  final int? productId;
  final String? productName;
  final double? quantity;
  final String? unit;
  final _Destination destination;

  const _ItemEdit({
    this.productId,
    this.productName,
    this.quantity,
    this.unit,
    this.destination = _Destination.inventory,
  });
}

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

class _EditDialog extends StatefulWidget {
  final ParsedReceiptItem item;
  final _ItemEdit current;
  final List<ProductOption> products;

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

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

class _EditDialogState extends State<_EditDialog> {
  late final TextEditingController _quantityCtrl;
  late final TextEditingController _unitCtrl;
  int? _productId;
  String? _productName;
  _Destination _destination = _Destination.inventory;

  @override
  void initState() {
    super.initState();
    _productId = widget.current.productId;
    _productName = widget.current.productName;
    _destination = widget.current.destination;
    _quantityCtrl = TextEditingController(
      text: (widget.current.quantity ?? widget.item.quantity)?.toString() ?? '',
    );
    _unitCtrl = TextEditingController(
      text: widget.current.unit ?? widget.item.unit ?? '',
    );
  }

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

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final aiCategory = widget.item.categorySuggestionName;

    return AlertDialog(
      title: Text(widget.item.rawName, maxLines: 2, overflow: TextOverflow.ellipsis),
      content: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // AI-kategorisuggestion
            if (aiCategory != null) ...[
              Wrap(
                children: [
                  Chip(
                    avatar: const Icon(Icons.auto_awesome, size: 14),
                    label: Text('AI: $aiCategory',
                        style: theme.textTheme.labelSmall),
                    backgroundColor: Colors.green.shade50,
                    side: BorderSide(color: Colors.green.shade300),
                    visualDensity: VisualDensity.compact,
                  ),
                ],
              ),
              const SizedBox(height: 8),
            ],
            // 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),
            ProductPickerField(
              products: widget.products,
              value: _productId,
              label: 'Produkt',
              onChanged: (id) {
                setState(() {
                  _productId = id;
                  _productName = id == null
                      ? null
                      : widget.products
                          .cast<ProductOption?>()
                          .firstWhere((p) => p?.id == id, orElse: () => null)
                          ?.name;
                });
              },
            ),
            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: 'Antal', border: OutlineInputBorder()),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: TextField(
                    controller: _unitCtrl,
                    decoration: const InputDecoration(labelText: 'Enhet', border: OutlineInputBorder()),
                  ),
                ),
              ]),
            ] 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: _productId == null ? null : () {
            Navigator.pop(
              context,
              _ItemEdit(
                productId: _productId,
                productName: _productName,
                quantity: double.tryParse(_quantityCtrl.text) ?? widget.item.quantity,
                unit: _unitCtrl.text.trim().isEmpty ? widget.item.unit : _unitCtrl.text.trim(),
                destination: _destination,
              ),
            );
          },
          child: const Text('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;
  List<ParsedReceiptItem>? _items;

  // Checkbox-state och per-rad redigering
  final Map<int, bool> _selected = {};
  final Map<int, _ItemEdit> _edits = {};

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

  // 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();
  }

  Future<void> _loadProducts() async {
    setState(() => _loadingProducts = true);
    try {
      final token = await ref.read(authStateProvider.future);
      final api = ref.read(apiClientProvider);
      final data = await api.getJson(ProductApiPaths.list, token: token);
      final list = data is List ? data : ((data as Map<String, dynamic>?)?['items'] as List? ?? []);
      if (mounted) {
        setState(() {
          _products = list
              .cast<Map<String, dynamic>>()
              .map((e) => (id: e['id'] as int, name: e['name'] as String))
              .toList();
          _loadingProducts = false;
        });
      }
    } catch (_) {
      if (mounted) setState(() => _loadingProducts = false);
    }
  }

  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;
    setState(() {
      _pickedFile = result.files.first;
      _items = null;
      _selected.clear();
      _edits.clear();
    });
  }

  Future<void> _submit() async {
    if (_pickedFile == null) return;
    setState(() { _isLoading = true; _items = null; _selected.clear(); _edits.clear(); });

    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;
      setState(() {
        _items = 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;
          _selected[i] = pid != null;
          if (pid != null) {
            final name = it.matchedProductName ?? it.suggestedProductName;
            _edits[i] = _ItemEdit(
              productId: pid,
              productName: name,
              quantity: it.quantity,
              unit: it.unit,
            );
          }
        }
      });
      // 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) async {
    final item = _items![index];
    final current = _edits[index] ??
        _ItemEdit(
          productId: item.matchedProductId ?? item.suggestedProductId,
          productName: item.matchedProductName ?? item.suggestedProductName,
          quantity: item.quantity,
          unit: item.unit,
        );

    final result = await showDialog<_ItemEdit>(
      context: context,
      builder: (_) => _EditDialog(item: item, current: current, products: _products),
    );
    if (result != null && mounted) {
      setState(() {
        _edits[index] = result;
        _selected[index] = true;
      });
    }
  }

  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 qty = edit.quantity ?? item.quantity ?? 1.0;
          final unit = edit.unit ?? item.unit ?? 'st';
          final existing = _inventoryByProduct[pid];
          if (existing != null) {
            await invRepo.updateInventoryItem(
              existing.id,
              {'quantity': existing.quantity + qty},
              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
      setState(() {
        for (final i in toAdd) _selected[i] = false;
      });
      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;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final items = _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),
            ),
          ],
          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(() {
                    for (var i = 0; i < items.length; i++) _selected[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 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) => setState(() => _selected[i] = v ?? false),
                  ),
                  title: Text(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)
                        Text(edit!.productName ?? '', style: theme.textTheme.bodySmall?.copyWith(
                          color: isMatched ? Colors.green.shade700 : theme.colorScheme.primary,
                          fontWeight: FontWeight.w500,
                        ))
                      else if (isSuggested)
                        Text('Förslag: ${item.suggestedProductName ?? ''}',
                            style: theme.textTheme.bodySmall?.copyWith(color: Colors.orange.shade700))
                      else
                        Text('Ingen match — tryck för att välja produkt',
                            style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.error)),
                      if (existingInv != null) ...[
                        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 + (edit?.quantity ?? item.quantity ?? 0)).toStringAsFixed(existingInv.quantity % 1 == 0 ? 0 : 2)} ${existingInv.unit}',
                            style: theme.textTheme.bodySmall?.copyWith(color: Colors.blue.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.error),
                    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'),
              ),
            ),
          ],
        ],
      ),
    );
  }
}

