import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';

import '../../../core/api/api_error_mapper.dart';
import '../../../core/forms/form_options.dart';
import '../../../core/l10n/l10n.dart';
import '../../../core/ui/async_state_views.dart';
import '../../../core/ui/product_picker_field.dart';
import '../../auth/data/auth_providers.dart';
import '../../inventory/data/inventory_providers.dart';
import '../data/pantry_providers.dart';
import '../domain/pantry_item.dart';
import '../domain/pantry_product.dart';

final _logger = Logger('PantryScreen');

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

  @override
  ConsumerState<PantryScreen> createState() => _PantryScreenState();
}

class _PantryScreenState extends ConsumerState<PantryScreen> {
  int? _selectedProductId;
  bool _isSubmitting = false;

  @override
  void initState() {
    super.initState();
    _logger.info('Initializing PantryScreen');
  }

  Future<void> _addToInventory(PantryItem item) async {
    final quantityController = TextEditingController(text: '1');
    String selectedUnit = 'st';
    String? selectedLocation;
    String? formError;

    final payload = await showDialog<Map<String, dynamic>>(
      context: context,
      builder: (ctx) {
        return StatefulBuilder(
          builder: (ctx, setDialogState) {
            return AlertDialog(
      title: Text(context.l10n.pantryAddToInventoryTitle(item.displayName)),
              content: SizedBox(
                width: 380,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(
                      controller: quantityController,
                      keyboardType: const TextInputType.numberWithOptions(decimal: true),
                      decoration: InputDecoration(
                        labelText: context.l10n.inventoryQuantityDisplayLabel,
                        border: const OutlineInputBorder(),
                      ),
                    ),
                    const SizedBox(height: 12),
                    DropdownButtonFormField<String>(
                      initialValue: selectedUnit,
                      isExpanded: true,
                      decoration: InputDecoration(
                        labelText: context.l10n.unitLabel,
                        border: const OutlineInputBorder(),
                      ),
                      items: unitOptions
                          .map((option) => DropdownMenuItem<String>(
                                value: option.value,
                                child: Text(option.label),
                              ))
                          .toList(),
                      onChanged: (value) {
                        if (value == null) return;
                        setDialogState(() => selectedUnit = value);
                      },
                    ),
                    const SizedBox(height: 12),
                    DropdownButtonFormField<String>(
                      initialValue: selectedLocation,
                      isExpanded: true,
                      decoration: InputDecoration(
                        labelText: context.l10n.locationOptionalLabel,
                        border: const OutlineInputBorder(),
                      ),
                      items: [
                        DropdownMenuItem<String>(
                          value: null,
                          child: Text(context.l10n.pantryNoLocation),
                        ),
                        ...inventoryLocationOptions.map(
                          (location) => DropdownMenuItem<String>(
                            value: location,
                            child: Text(location),
                          ),
                        ),
                      ],
                      onChanged: (value) {
                        setDialogState(() => selectedLocation = value);
                      },
                    ),
                    if (formError != null) ...[
                      const SizedBox(height: 8),
                      Text(
                        formError!,
                        style: TextStyle(color: Theme.of(ctx).colorScheme.error),
                      ),
                    ],
                  ],
                ),
              ),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(ctx),
                  child: Text(context.l10n.cancelAction),
                ),
                FilledButton(
                  onPressed: () {
                    final quantity = double.tryParse(
                      quantityController.text.trim().replaceAll(',', '.'),
                    );
                    if (quantity == null || quantity <= 0) {
                      setDialogState(() {
                        formError = context.l10n.pantryInvalidQuantity;
                      });
                      return;
                    }
                    Navigator.pop(ctx, {
                      'quantity': quantity,
                      'unit': selectedUnit,
                      'location': selectedLocation,
                    });
                  },
                  child: Text(context.l10n.addAction),
                ),
              ],
            );
          },
        );
      },
    );

    quantityController.dispose();
    if (payload == null) return;

    try {
      final token = await ref.read(authStateProvider.future);
      await ref.read(inventoryRepositoryProvider).createInventoryItem(
        {
          'productId': item.productId,
          'quantity': payload['quantity'] as double,
          'unit': payload['unit'] as String,
          if (payload['location'] != null) 'location': payload['location'] as String,
        },
        token: token,
      );
      ref.invalidate(inventoryProvider);
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(context.l10n.pantryItemAdded(item.displayName))),
      );
    } catch (error) {
      _logger.severe('Failed to add item to inventory: $error');
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(mapErrorToUserMessage(error, context))),
      );
    }
  }

  Future<void> _addItem() async {
    final selectedId = _selectedProductId;
    if (selectedId == null || _isSubmitting) return;

    setState(() => _isSubmitting = true);
    try {
      final token = await ref.read(authStateProvider.future);
      await ref.read(pantryRepositoryProvider).createPantryItem(selectedId, token: token);
      ref.invalidate(pantryProvider);
      if (mounted) setState(() => _selectedProductId = null);
    } catch (error) {
      _logger.severe('Failed to add pantry item: $error');
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(mapErrorToUserMessage(error, context))),
      );
    } finally {
      if (mounted) setState(() => _isSubmitting = false);
    }
  }

  Future<void> _removeItem(PantryItem item) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(context.l10n.pantryRemoveTitle),
        content: Text(context.l10n.pantryRemoveContent(item.displayName)),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx, false),
            child: Text(context.l10n.cancelAction),
          ),
          FilledButton(
            onPressed: () => Navigator.pop(ctx, true),
            child: Text(context.l10n.deleteAction),
          ),
        ],
      ),
    );

    if (confirmed != true) return;

    try {
      final token = await ref.read(authStateProvider.future);
      await ref.read(pantryRepositoryProvider).deletePantryItem(item.id, token: token);
      ref.invalidate(pantryProvider);
    } catch (error) {
      _logger.severe('Failed to remove pantry item: $error');
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(mapErrorToUserMessage(error, context))),
      );
    }
  }

  String _resolveCategory(PantryItem item, Map<int, PantryProduct> productById) {
    final fromTree = productById[item.productId]?.categoryPath;
    if (fromTree != null && fromTree.trim().isNotEmpty) {
      return fromTree;
    }
    if (item.category != null && item.category!.trim().isNotEmpty) {
      return item.category!;
    }
    return context.l10n.pantryOtherCategory;
  }

  @override
  Widget build(BuildContext context) {
    final pantryAsync = ref.watch(pantryProvider);
    final productsAsync = ref.watch(pantryProductsProvider);

    if (pantryAsync.isLoading || productsAsync.isLoading) {
      return LoadingStateView(label: context.l10n.pantryLoading);
    }

    if (pantryAsync.hasError || productsAsync.hasError) {
      final error = pantryAsync.error ?? productsAsync.error;
      _logger.severe('Error loading pantry or products: $error');
      return ErrorStateView(
        message: mapErrorToUserMessage(error ?? 'Okänt fel', context),
        onRetry: () {
          ref.invalidate(pantryProvider);
          ref.invalidate(pantryProductsProvider);
        },
      );
    }

    final pantryItems =
        pantryAsync.maybeWhen(data: (d) => d, orElse: () => null) ?? const [];
    final products =
        productsAsync.maybeWhen(data: (d) => d, orElse: () => null) ?? const [];
    final productById = {for (final product in products) product.id: product};
    final pantryProductIds = pantryItems.map((e) => e.productId).toSet();
    final availableProducts = products
        .where((product) => !pantryProductIds.contains(product.id))
        .toList()
      ..sort(
        (a, b) => a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase()),
      );
    final availableOptions = availableProducts
        .map((p) => (id: p.id, name: p.displayName, categoryId: null as int?))
        .toList();

    final grouped = <String, List<PantryItem>>{};
    for (final item in pantryItems) {
      final category = _resolveCategory(item, productById);
      grouped.putIfAbsent(category, () => []).add(item);
    }
    final categories = grouped.keys.toList()
      ..sort((a, b) {
        if (a == 'Övrigt') return 1;
        if (b == 'Övrigt') return -1;
        return a.toLowerCase().compareTo(b.toLowerCase());
      });

    return ListView(
      padding: const EdgeInsets.all(16),
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              context.l10n.pantryDescription,
              style: Theme.of(context).textTheme.bodyMedium,
            ),
            IconButton(
              tooltip: context.l10n.pantryGoToRecipesTooltip,
              icon: const Icon(Icons.restaurant_menu),
              onPressed: () => context.go('/recipes'),
            ),
          ],
        ),
        const SizedBox(height: 12),
        Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Expanded(
              child: ProductPickerField(
                products: availableOptions,
                value: _selectedProductId,
                enabled: !_isSubmitting && availableProducts.isNotEmpty,
                label: 'Produkt',
                onChanged: (value) => setState(() => _selectedProductId = value),
              ),
            ),
            const SizedBox(width: 8),
            FilledButton(
              onPressed:
                  (_selectedProductId == null || _isSubmitting || availableProducts.isEmpty)
                      ? null
                      : _addItem,
              child: _isSubmitting
                  ? const SizedBox(
                      height: 18,
                      width: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Text('Lägg till'),
            ),
          ],
        ),
        if (availableProducts.isEmpty) ...[
          const SizedBox(height: 12),
          Text(
            'Inga produkter tillgängliga att lägga till.',
            style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey),
          ),
        ],
        const SizedBox(height: 20),
        Text(
          '${pantryItems.length} ${pantryItems.length == 1 ? 'produkt' : 'produkter'} i baslagret',
          style: Theme.of(context).textTheme.titleMedium,
        ),
        const SizedBox(height: 12),
        if (pantryItems.isEmpty)
          const EmptyStateView(
            title: 'Baslagret är tomt',
            description: 'Lägg till produkter ovan.',
          )
        else
          ...categories.map((category) {
            final items = grouped[category]!
              ..sort(
                (a, b) =>
                    a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase()),
              );
            return Padding(
              padding: const EdgeInsets.only(bottom: 16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    category,
                    style: Theme.of(context).textTheme.titleSmall,
                  ),
                  const SizedBox(height: 8),
                  Column(
                    children: items
                        .map(
                          (item) => Card(
                            margin: const EdgeInsets.only(bottom: 8),
                            child: ListTile(
                              title: Text(item.displayName),
                              trailing: Row(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  const Tooltip(
                                    message: 'Konsumera (inte tillgängligt i baslager)',
                                    child: IconButton(
                                      onPressed: null,
                                      icon: Icon(Icons.remove_circle_outline),
                                    ),
                                  ),
                                  const Tooltip(
                                    message: 'Redigera (inte tillgängligt i baslager)',
                                    child: IconButton(
                                      onPressed: null,
                                      icon: Icon(Icons.edit_outlined),
                                    ),
                                  ),
                                  IconButton(
                                    tooltip: 'Lägg i inventarie',
                                    icon: const Icon(Icons.inventory_2_outlined),
                                    onPressed: () => _addToInventory(item),
                                  ),
                                  IconButton(
                                    tooltip: 'Ta bort',
                                    icon: const Icon(
                                      Icons.delete_outline,
                                      color: Colors.red,
                                    ),
                                    onPressed: () => _removeItem(item),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        )
                        .toList(),
                  ),
                ],
              ),
            );
          }).toList(),
      ],
    );
  }
}
