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

import '../../../core/api/api_error_mapper.dart';
import '../../../core/forms/form_options.dart';
import '../../../core/l10n/l10n.dart';
import '../../../core/ui/category_then_product_picker.dart';
import '../../../core/ui/searchable_category_field.dart';
import '../../../core/ui/product_picker_field.dart';
import 'admin_form_shared.dart';
import '../data/admin_repository.dart';
import '../domain/admin_category_node.dart';
import '../domain/admin_pantry_item.dart';
import '../domain/admin_product.dart';
import '../domain/user_admin.dart';

class AdminPantryPanel extends ConsumerStatefulWidget {
  final bool embedded;

  const AdminPantryPanel({super.key, this.embedded = false});

  @override
  ConsumerState<AdminPantryPanel> createState() => _AdminPantryPanelState();
}

class _AdminPantryPanelState extends ConsumerState<AdminPantryPanel> {
  bool _isLoading = true;
  String? _error;
  String _search = '';
  int? _selectedUserId;
  List<AdminPantryItem> _items = [];
  List<AdminProduct> _products = [];
  List<AdminCategoryNode> _categories = [];
  List<UserAdmin> _users = [];

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

  Future<void> _load() async {
    setState(() {
      _isLoading = true;
      _error = null;
    });

    try {
      final results = await Future.wait<dynamic>([
        ref.read(adminRepositoryProvider).listAdminPantry(userId: _selectedUserId),
        ref.read(adminRepositoryProvider).listSelectableProductsForAdmin(),
        ref.read(adminRepositoryProvider).listCategoryTree(),
        ref.read(adminRepositoryProvider).listUsers(),
      ]);
      if (!mounted) return;
      setState(() {
        _items = results[0] as List<AdminPantryItem>;
        _products = results[1] as List<AdminProduct>;
        _categories = results[2] as List<AdminCategoryNode>;
        _users = results[3] as List<UserAdmin>;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() => _error = mapErrorToUserMessage(e, context));
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  List<AdminPantryItem> get _filtered {
    final q = _search.trim().toLowerCase();
    if (q.isEmpty) return _items;
    return _items.where((item) {
      return item.displayName.toLowerCase().contains(q) ||
          item.username.toLowerCase().contains(q) ||
          item.userEmail.toLowerCase().contains(q) ||
          (item.location ?? '').toLowerCase().contains(q) ||
          (item.categoryPath ?? '').toLowerCase().contains(q);
    }).toList();
  }

  List<String> get _locationOptions {
    return buildLocationOptionsFromValues(_items.map((item) => item.location));
  }

  Future<void> _addItem() async {
    final values = await _showPantryFormDialog(initialOwnerUserId: _selectedUserId);
    if (values == null) return;

    try {
      await ref.read(adminRepositoryProvider).createAdminPantry(
            userId: values.ownerUserId,
            productId: values.productId,
            location: values.location,
          );
      if (!mounted) return;
      await _load();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Baslager-post skapad.')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
      );
    }
  }

  Future<void> _editItem(AdminPantryItem item) async {
    final values = await _showPantryFormDialog(initial: item);
    if (values == null) return;

    try {
      await ref.read(adminRepositoryProvider).updateAdminPantry(
            item.id,
            productId: values.productId,
            location: values.location,
          );
      if (!mounted) return;
      await _load();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Baslager-post uppdaterad.')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
      );
    }
  }

  Future<_PantryFormValues?> _showPantryFormDialog({
    AdminPantryItem? initial,
    int? initialOwnerUserId,
  }) {
    return showDialog<_PantryFormValues>(
      context: context,
      builder: (context) => _PantryFormDialog(
        users: _users,
        products: _products,
        categories: _categories,
        locationOptions: _locationOptions,
        initial: initial,
        initialOwnerUserId: initialOwnerUserId,
      ),
    );
  }

  Future<void> _moveToInventory(AdminPantryItem 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 {
      await ref.read(adminRepositoryProvider).moveAdminPantryToInventory(
            item.id,
            {
              'productId': item.productId,
              'quantity': payload['quantity'] as double,
              'unit': payload['unit'] as String,
              if (payload['location'] != null) 'location': payload['location'] as String,
            },
          );
      if (!mounted) return;
      await _load();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Flyttade "${item.displayName}" till inventarie.')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    if (_isLoading) return const Center(child: CircularProgressIndicator());
    if (_error != null) {
      return buildCopyableErrorPanel(
        context: context,
        message: _error!,
        onRetry: _load,
        title: 'Kunde inte läsa admin pantry',
      );
    }

    final filtered = _filtered;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Card(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text('Baslager', style: theme.textTheme.titleMedium),
                const SizedBox(height: 8),
                Text(
                  'Här ser du användarnas pantryposter. Du kan lägga till, ändra, flytta till inventarie och sätta/ändra kategori via produktval.',
                  style: theme.textTheme.bodyMedium,
                ),
                const SizedBox(height: 8),
                const Wrap(
                  spacing: 8,
                  runSpacing: 8,
                  children: [
                    Chip(label: Text('User-scope')),
                    Chip(label: Text('Kategorier')), 
                    Chip(label: Text('Ändra/Lägg till')),
                    Chip(label: Text('Flytta till inventarie')),
                    Chip(label: Text('Ta bort')),
                  ],
                ),
              ],
            ),
          ),
        ),
        const SizedBox(height: 12),
        Card(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Expanded(
                  child: DropdownButtonFormField<int>(
                    initialValue: _selectedUserId,
                    decoration: const InputDecoration(labelText: 'Filtrera användare'),
                    items: [
                      const DropdownMenuItem<int>(
                        value: null,
                        child: Text('Alla användare'),
                      ),
                      ..._users.map(
                        (user) => DropdownMenuItem<int>(
                          value: user.id,
                          child: Text('${user.displayName} (${user.username})'),
                        ),
                      ),
                    ],
                    onChanged: (value) {
                      setState(() => _selectedUserId = value);
                      _load();
                    },
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: TextField(
                    decoration: const InputDecoration(
                      prefixIcon: Icon(Icons.search),
                      hintText: 'Sök produkt, kategori, användare eller plats',
                    ),
                    onChanged: (value) => setState(() => _search = value),
                  ),
                ),
                const SizedBox(width: 8),
                OutlinedButton.icon(
                  onPressed: _load,
                  icon: const Icon(Icons.refresh),
                  label: const Text('Uppdatera'),
                ),
                const SizedBox(width: 8),
                FilledButton.icon(
                  onPressed: _addItem,
                  icon: const Icon(Icons.add),
                  label: const Text('Lägg till'),
                ),
              ],
            ),
          ),
        ),
        const SizedBox(height: 12),
        Text('Visar ${filtered.length} av ${_items.length} baslager-poster'),
        const SizedBox(height: 8),
        Expanded(
          child: filtered.isEmpty
              ? Card(
                  child: Padding(
                    padding: const EdgeInsets.all(16),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Baslager', style: theme.textTheme.titleMedium),
                        const SizedBox(height: 8),
                        Text(
                          'Här ser du användarnas pantryposter. Flytta dem tillbaka till inventarie eller ta bort poster som inte längre ska ligga kvar.',
                          style: theme.textTheme.bodyMedium,
                        ),
                        const SizedBox(height: 8),
                        Text(
                          'Inga pantry-poster hittades.',
                          style: theme.textTheme.bodyMedium,
                        ),
                      ],
                    ),
                  ),
                )
              : ListView.separated(
                  itemCount: filtered.length,
                  separatorBuilder: (_, __) => const Divider(height: 1),
                  itemBuilder: (context, index) {
                    final item = filtered[index];
                    return ListTile(
                      title: Row(
                        children: [
                          Expanded(child: Text(item.displayName)),
                          buildCategoryPathChip(item.categoryPath),
                        ],
                      ),
                      subtitle: Text(
                        '${item.username} (${item.userEmail})'
                        '${item.location == null || item.location!.trim().isEmpty ? '' : ' · ${item.location}'}',
                      ),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          IconButton(
                            tooltip: 'Ändra',
                            icon: const Icon(Icons.edit_outlined),
                            onPressed: () => _editItem(item),
                          ),
                          IconButton(
                            tooltip: 'Flytta till inventarie',
                            icon: const Icon(Icons.inventory_2_outlined),
                            onPressed: () => _moveToInventory(item),
                          ),
                          IconButton(
                            tooltip: 'Ta bort',
                            icon: const Icon(Icons.delete_outline, color: Colors.red),
                            onPressed: () async {
                              try {
                                await ref.read(adminRepositoryProvider).removeAdminPantryItem(item.id);
                                if (!mounted) return;
                                await _load();
                              } catch (e) {
                                if (!mounted) return;
                                ScaffoldMessenger.of(context).showSnackBar(
                                  buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
                                );
                              }
                            },
                          ),
                        ],
                      ),
                    );
                  },
                ),
        ),
      ],
    );
  }
}

class _PantryFormValues {
  final int? ownerUserId;
  final int productId;
  final String? location;

  const _PantryFormValues({
    this.ownerUserId,
    required this.productId,
    this.location,
  });
}

class _PantryFormDialog extends StatefulWidget {
  final List<UserAdmin> users;
  final List<AdminProduct> products;
  final List<AdminCategoryNode> categories;
  final List<String> locationOptions;
  final AdminPantryItem? initial;
  final int? initialOwnerUserId;

  const _PantryFormDialog({
    required this.users,
    required this.products,
    required this.categories,
    required this.locationOptions,
    this.initial,
    this.initialOwnerUserId,
  });

  @override
  State<_PantryFormDialog> createState() => _PantryFormDialogState();
}

class _PantryFormDialogState extends State<_PantryFormDialog> {
  static const String _manualLocationValue = '__manual_location__';

  late final TextEditingController _locationController;
  late final TextEditingController _categorySearchController;
  late List<CategorySelectOption> _categoryOptions;
  
  int? _ownerUserId;
  int? _productId;
  int? _categoryId;
  String? _categoryPath;
  String? _productErrorText;
  bool _useManualLocation = false;
  ProductScopeFilter _productScopeFilter = ProductScopeFilter.globalOnly;

  @override
  void initState() {
    super.initState();
    final initial = widget.initial;
    _ownerUserId = initial?.userId ?? widget.initialOwnerUserId;
    _productId = initial?.productId;
    final initialProduct = _productById(_productId);
    _categoryId = initialProduct?.categoryId;
    _categoryPath = initialProduct?.categoryPath;
    _locationController = TextEditingController(text: initial?.location ?? '');
    _categorySearchController = TextEditingController(text: _categoryPath ?? '');
    _categoryOptions = _flattenCategoryOptions(widget.categories);
    final initialLocation = _locationController.text.trim();
    _useManualLocation = initialLocation.isNotEmpty &&
      !widget.locationOptions.contains(initialLocation);
  }

  @override
  void dispose() {
    _locationController.dispose();
    _categorySearchController.dispose();
    super.dispose();
  }

  void _applyCategorySelection(int id, String path) {
    setState(() {
      _categoryId = id;
      _categoryPath = path;
      _categorySearchController.text = path;
      if (_productId != null) {
        final current = _productById(_productId);
        if (current?.categoryId != _categoryId) {
          _productId = null;
        }
      }
    });
  }

  AdminProduct? _productById(int? id) {
    if (id == null) return null;
    for (final product in widget.products) {
      if (product.id == id) return product;
    }
    final initial = widget.initial;
    if (initial != null && initial.productId == id) {
      return AdminProduct(
        id: initial.productId,
        name: initial.productName,
        canonicalName: initial.productCanonicalName,
        ownerId: initial.userId,
        isPrivate: null,
        categoryId: initial.categoryId,
        categoryPath: initial.categoryPath,
        status: 'private',
      );
    }
    return null;
  }

  List<ProductOption> _productOptions() {
    final filtered = filterSelectableAdminProducts(
      products: widget.products,
      ownerUserId: _ownerUserId,
      categoryId: _categoryId,
      scopeFilter: _productScopeFilter,
      selectedProduct: _productById(_productId),
    );
    return toProductOptions(filtered);
  }

  String? _locationDropdownValue() {
    return resolveLocationDropdownValue(
      useManualLocation: _useManualLocation,
      currentValue: _locationController.text,
      options: widget.locationOptions,
      manualLocationValue: _manualLocationValue,
    );
  }

  List<CategorySelectOption> _flattenCategoryOptions(
    List<AdminCategoryNode> nodes, [
    List<String> parents = const [],
  ]) {
    final result = <CategorySelectOption>[];
    for (final node in nodes) {
      final pathParts = [...parents, node.name];
      final path = pathParts.join(' > ');
      result.add((value: node.id.toString(), label: path));
      result.addAll(_flattenCategoryOptions(node.children, pathParts));
    }
    return result;
  }

  Future<void> _pickCategory() async {
    final selected = await CategoryThenProductPicker.showCategorySheet(
      context,
      categoryTree: widget.categories,
      preselectedCategoryId: _categoryId,
    );
    if (selected == null || !mounted) return;
    _applyCategorySelection(selected.id, selected.path);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(widget.initial == null ? 'Lägg till baslager-post' : 'Ändra baslager-post'),
      content: SizedBox(
        width: 460,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              if (widget.initial == null) ...[
                DropdownButtonFormField<int>(
                  initialValue: _ownerUserId,
                  items: widget.users
                      .map((u) => DropdownMenuItem<int>(
                            value: u.id,
                            child: Text(
                              '${u.displayName} (${u.username})',
                              overflow: TextOverflow.ellipsis,
                            ),
                          ))
                      .toList(),
                  onChanged: (value) => setState(() {
                    _ownerUserId = value;
                    if (value == null) {
                      _productScopeFilter = ProductScopeFilter.globalOnly;
                      final selected = _productById(_productId);
                      if (selected?.isPrivate == true) {
                        _productId = null;
                      }
                    }
                  }),
                  decoration: const InputDecoration(labelText: 'Ägare (användare)'),
                ),
                const SizedBox(height: 12),
              ] else ...[
                Text(
                  'Produkt: ${widget.initial!.displayName}',
                  style: Theme.of(context).textTheme.bodyMedium,
                ),
                const SizedBox(height: 8),
                Text(
                  'Ägare: ${widget.initial!.username} (${widget.initial!.userEmail})',
                  style: Theme.of(context).textTheme.bodyMedium,
                ),
                const SizedBox(height: 12),
              ],
              SearchableCategoryField(
                options: _categoryOptions,
                value: _categoryId?.toString(),
                label: 'Kategori (sökbar)',
                onChanged: (value) {
                  if (value == null) return;
                  final label = _categoryOptions
                      .firstWhere((option) => option.value == value)
                      .label;
                  _applyCategorySelection(int.parse(value), label);
                },
              ),
              const SizedBox(height: 12),
              Row(
                children: [
                  OutlinedButton.icon(
                    onPressed: _pickCategory,
                    icon: const Icon(Icons.category_outlined),
                    label: const Text('Välj kategori'),
                  ),
                  const SizedBox(width: 8),
                  OutlinedButton.icon(
                    onPressed: () {
                      setState(() {
                        _categoryId = null;
                        _categoryPath = null;
                      });
                    },
                    icon: const Icon(Icons.clear),
                    label: const Text('Rensa kategori'),
                  ),
                ],
              ),
              const SizedBox(height: 12),
              ProductPickerField(
                products: _productOptions(),
                value: _productId,
                label: 'Produkt',
                errorText: _productErrorText,
                onChanged: (value) {
                  setState(() {
                    _productId = value;
                    _productErrorText = null;
                  });
                },
              ),
              if (_ownerUserId != null) ...[
                const SizedBox(height: 8),
                SegmentedButton<ProductScopeFilter>(
                  segments: const [
                    ButtonSegment<ProductScopeFilter>(
                      value: ProductScopeFilter.all,
                      label: Text('Alla'),
                    ),
                    ButtonSegment<ProductScopeFilter>(
                      value: ProductScopeFilter.globalOnly,
                      label: Text('Globala'),
                    ),
                    ButtonSegment<ProductScopeFilter>(
                      value: ProductScopeFilter.privateOnly,
                      label: Text('Privata'),
                    ),
                  ],
                  selected: {_productScopeFilter},
                  onSelectionChanged: (selection) {
                    if (selection.isEmpty) return;
                    setState(() => _productScopeFilter = selection.first);
                  },
                ),
                const SizedBox(height: 12),
              ] else ...[
                const SizedBox(height: 12),
              ],
              DropdownButtonFormField<String>(
                initialValue: _locationDropdownValue(),
                decoration: const InputDecoration(labelText: 'Plats (valfritt)'),
                items: [
                  ...widget.locationOptions.map(
                    (option) => DropdownMenuItem<String>(
                      value: option,
                      child: Text(option),
                    ),
                  ),
                  const DropdownMenuItem<String>(
                    value: _manualLocationValue,
                    child: Text('Ange manuellt...'),
                  ),
                ],
                onChanged: (value) {
                  if (value == null) {
                    setState(() {
                      _useManualLocation = false;
                      _locationController.clear();
                    });
                    return;
                  }
                  if (value == _manualLocationValue) {
                    setState(() => _useManualLocation = true);
                    return;
                  }
                  setState(() {
                    _useManualLocation = false;
                    _locationController.text = value;
                  });
                },
              ),
              if (_useManualLocation) ...[
                const SizedBox(height: 12),
                TextFormField(
                  controller: _locationController,
                  decoration: const InputDecoration(labelText: 'Plats (manuell)'),
                ),
              ],
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: const Text('Avbryt'),
        ),
        FilledButton(
          onPressed: () {
            if (_productId == null) {
              setState(() => _productErrorText = 'Välj en produkt');
              return;
            }
            if (widget.initial == null && _ownerUserId == null) {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('Välj användare')),
              );
              return;
            }
            Navigator.of(context).pop(
              _PantryFormValues(
                ownerUserId: _ownerUserId,
                productId: _productId!,
                location: _locationController.text.trim().isEmpty
                    ? null
                    : _locationController.text.trim(),
              ),
            );
          },
          child: const Text('Spara'),
        ),
      ],
    );
  }
}
