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 '../../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> {
  static const _locationOptions = <String>['', 'Kyl', 'Frys', 'Skafferi'];
  String _locationFilter = '';
  String _sort = 'nameAsc';

  List<({String value, String label})> _sortOptions() => const [
    (value: 'nameAsc', label: 'Namn (A-O)'),
    (value: 'nameDesc', label: 'Namn (O-A)'),
    (value: 'l1CategoryAsc', label: 'L1-kategori (A-O)'),
    (value: 'locationAsc', label: 'Plats (A-O)'),
  ];

  @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(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(error, context)),
      );
    }
  }

  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(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(error, context)),
      );
    }
  }

  String _resolveL1Category(PantryItem item, Map<int, PantryProduct> productById) {
    final path = productById[item.productId]?.categoryPath?.trim();
    if (path != null && path.isNotEmpty) {
      return path.split('>').first.trim();
    }
    if (item.category != null && item.category!.trim().isNotEmpty) {
      return item.category!.trim();
    }
    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 filteredItems = pantryItems.where((item) {
      if (_locationFilter.isEmpty) return true;
      return (item.location ?? '').trim() == _locationFilter;
    }).toList();

    filteredItems.sort((a, b) {
      if (_sort == 'nameDesc') {
        return b.displayName.toLowerCase().compareTo(a.displayName.toLowerCase());
      }
      if (_sort == 'locationAsc') {
        final byLocation = (a.location ?? '').toLowerCase().compareTo(
          (b.location ?? '').toLowerCase(),
        );
        if (byLocation != 0) return byLocation;
        return a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase());
      }
      if (_sort == 'l1CategoryAsc') {
        final byL1 = _resolveL1Category(a, productById).toLowerCase().compareTo(
          _resolveL1Category(b, productById).toLowerCase(),
        );
        if (byL1 != 0) return byL1;
        return a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase());
      }
      return a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase());
    });

    final filterSection = Padding(
      padding: const EdgeInsets.fromLTRB(12, 12, 12, 4),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            context.l10n.inventoryFilterAndSort,
            style: const TextStyle(fontWeight: FontWeight.w600),
          ),
          const SizedBox(height: 8),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: _locationOptions
                .map(
                  (option) => ChoiceChip(
                    label: Text(option.isEmpty ? context.l10n.inventoryAllFilter : option),
                    selected: _locationFilter == option,
                    onSelected: (_) => setState(() => _locationFilter = option),
                  ),
                )
                .toList(),
          ),
          const SizedBox(height: 8),
          DropdownButtonFormField<String>(
            initialValue: _sort,
            isExpanded: true,
            decoration: InputDecoration(
              labelText: context.l10n.inventorySortLabel,
              border: const OutlineInputBorder(),
            ),
            items: _sortOptions()
                .map(
                  (option) => DropdownMenuItem<String>(
                    value: option.value,
                    child: Text(option.label),
                  ),
                )
                .toList(),
            onChanged: (value) {
              setState(() => _sort = value ?? 'nameAsc');
            },
          ),
        ],
      ),
    );

    final content = filteredItems.isEmpty
        ? ListView(
            key: const PageStorageKey<String>('pantry-empty-list'),
            padding: const EdgeInsets.fromLTRB(12, 0, 12, 96),
            children: [
              filterSection,
              const EmptyStateView(
                title: 'Baslagret är tomt',
                description: 'Lägg till produkter med plusknappen.',
              ),
            ],
          )
        : ListView.separated(
          key: const PageStorageKey<String>('pantry-main-list'),
            padding: const EdgeInsets.fromLTRB(12, 0, 12, 96),
            itemCount: filteredItems.length + 1,
            separatorBuilder: (_, __) => const Divider(height: 1),
            itemBuilder: (context, index) {
              if (index == 0) return filterSection;
              final item = filteredItems[index - 1];
              final l1Category = _resolveL1Category(item, productById);

              return ListTile(
                title: Text(item.displayName),
                subtitle: Text(
                  [
                    'L1: $l1Category',
                    if (item.location != null && item.location!.trim().isNotEmpty)
                      'Plats: ${item.location}',
                  ].join(' • '),
                ),
                trailing: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    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),
                    ),
                  ],
                ),
              );
            },
          );

    return Stack(
      children: [
        content,
        Positioned(
          right: 16,
          bottom: 16,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              FloatingActionButton.extended(
                heroTag: 'pantry_add',
                onPressed: () => context.push('/inventory/create?destination=pantry'),
                icon: const Icon(Icons.add),
                label: Text(context.l10n.addAction),
              ),
              const SizedBox(height: 8),
              FloatingActionButton.extended(
                heroTag: 'pantry_go_recipes',
                onPressed: () => context.go('/recipes'),
                icon: const Icon(Icons.restaurant_menu),
                label: Text(context.l10n.inventoryRecipesAction),
              ),
            ],
          ),
        ),
      ],
    );
  }
}

