import 'package:flutter/material.dart';
import 'product_picker_field.dart';
import '../../features/admin/domain/admin_category_node.dart';

/// Tvåstegs-picker: välj kategori i trädet → välj produkt i den kategorin.
///
/// Returnerar det valda produkt-id:t, eller null om användaren avbryter.
///
/// [onCreate] — valfri callback för att skapa ny produkt; anropas med produktnamnet
/// och returnerar `ProductOption` för den skapade produkten.
///
/// Anropas via [CategoryThenProductPicker.show].
class CategoryThenProductPicker {
  CategoryThenProductPicker._();

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

  /// Samlar alla ID:n för [node] och alla dess ättlingar rekursivt.
  static Set<int> _collectIds(AdminCategoryNode node) {
    final ids = <int>{node.id};
    for (final child in node.children) {
      ids.addAll(_collectIds(child));
    }
    return ids;
  }

  /// Hittar en nod med givet id djupet i trädet.
  static AdminCategoryNode? _findNode(List<AdminCategoryNode> nodes, int id) {
    for (final node in nodes) {
      if (node.id == id) return node;
      final found = _findNode(node.children, id);
      if (found != null) return found;
    }
    return null;
  }

  /// Öppnar ett bottenark med kategoriträdet. Klick på en lövnod (inga barn)
  /// öppnar direkt produktpickern för den kategorin.
  /// Klick på en mellannodens namn expanderar/kollapsar dess barn.
  ///
  /// [preselectedCategoryId] — om satt scrollas trädet till den noden och den
  /// markeras visuellt. Användaren kan fortfarande välja en annan kategori.
  ///
  /// [onCreate] — valfri callback; om satt visas "Skapa ny" i produktpickern.
  ///   Anropas med produktnamnet och ska returnera den nya `ProductOption`.
  static Future<int?> show(
    BuildContext context, {
    required List<AdminCategoryNode> categoryTree,
    required List<ProductOption> products,
    int? currentProductId,
    int? preselectedCategoryId,
    String? initialQuery,
    Future<ProductOption?> Function(String name, int categoryId)? onCreate,
  }) async {
    AdminCategoryNode? selectedCategory;

    if (preselectedCategoryId != null) {
      // AI-föreslagen kategori — hoppa direkt till produktpickern
      selectedCategory = _findNode(categoryTree, preselectedCategoryId);
    }

    if (selectedCategory == null) {
      // Steg 1 — visa kategoriträd
      if (!context.mounted) return null;
      selectedCategory = await showModalBottomSheet<AdminCategoryNode>(
        context: context,
        isScrollControlled: true,
        useSafeArea: true,
        builder: (ctx) => _CategoryPickerSheet(
          tree: categoryTree,
          preselectedId: preselectedCategoryId,
          onSelected: (node) => Navigator.pop(ctx, node),
        ),
      );
      if (selectedCategory == null || !context.mounted) return null;
    }

    // Samla alla kategori-IDs i den valda grenen (inkl. ättlingar)
    final categoryIds = _collectIds(selectedCategory);

    // Filtrera produkter på dessa kategorier
    final filtered = products
        .where((p) => p.categoryId != null && categoryIds.contains(p.categoryId))
        .toList();
    final useList = filtered.isNotEmpty ? filtered : products;

    // Bygg eventuell onCreate-callback med categoryId inbunden
    final onCreateBound = onCreate == null
        ? null
        : (String name) => onCreate(name, selectedCategory!.id);

    // Steg 2 — välj produkt
    if (!context.mounted) return null;
    return ProductPickerField.showSheet(
      context,
      products: useList,
      value: currentProductId,
      label: 'Produkt i "${selectedCategory.name}"',
      categoryFilter: null, // redan förfiltrerat
      initialQuery: initialQuery,
      onCreate: onCreateBound,
    );
  }

  static Future<({int id, String name, String path})?> showCategorySheet(
    BuildContext context, {
    required List<AdminCategoryNode> categoryTree,
    int? preselectedCategoryId,
  }) async {
    if (!context.mounted) return null;
    final selectedCategory = await showModalBottomSheet<AdminCategoryNode>(
      context: context,
      isScrollControlled: true,
      useSafeArea: true,
      builder: (ctx) => _CategoryPickerSheet(
        tree: categoryTree,
        preselectedId: preselectedCategoryId,
        onSelected: (node) => Navigator.pop(ctx, node),
      ),
    );
    if (selectedCategory == null) return null;
    final path = _findPath(categoryTree, selectedCategory.id, const [])
            ?.join(' > ') ??
        selectedCategory.name;
    return (
      id: selectedCategory.id,
      name: selectedCategory.name,
      path: path,
    );
  }
}

// ── Kategoriträdets bottenark ────────────────────────────────────────────────

class _CategoryPickerSheet extends StatefulWidget {
  final List<AdminCategoryNode> tree;
  final int? preselectedId;
  final void Function(AdminCategoryNode node) onSelected;

  const _CategoryPickerSheet({
    required this.tree,
    required this.onSelected,
    this.preselectedId,
  });

  @override
  State<_CategoryPickerSheet> createState() => _CategoryPickerSheetState();
}

class _CategoryPickerSheetState extends State<_CategoryPickerSheet> {
  String _query = '';
  late final TextEditingController _ctrl;

  @override
  void initState() {
    super.initState();
    _ctrl = TextEditingController();
  }

  @override
  void dispose() {
    _ctrl.dispose();
    super.dispose();
  }

  /// Returnerar alla lövnoder (inga barn) som matchar sökordet.
  List<_FlatCategory> _flatLeaves(
    List<AdminCategoryNode> nodes,
    List<String> parentNames,
  ) {
    final result = <_FlatCategory>[];
    for (final node in nodes) {
      final path = [...parentNames, node.name];
      if (node.children.isEmpty) {
        result.add(_FlatCategory(node: node, path: path));
      } else {
        result.addAll(_flatLeaves(node.children, path));
      }
    }
    return result;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final q = _query.trim().toLowerCase();

    return SizedBox(
      height: MediaQuery.of(context).size.height * 0.88,
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
            child: Row(
              children: [
                Expanded(
                  child: Text('Välj kategori', style: theme.textTheme.titleMedium),
                ),
                IconButton(
                  icon: const Icon(Icons.close),
                  onPressed: () => Navigator.pop(context),
                ),
              ],
            ),
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
            child: TextField(
              controller: _ctrl,
              autofocus: false,
              decoration: const InputDecoration(
                hintText: 'Sök kategori...',
                prefixIcon: Icon(Icons.search),
                border: OutlineInputBorder(),
              ),
              onChanged: (v) => setState(() => _query = v),
            ),
          ),
          const Divider(height: 1),
          Expanded(
            child: q.isEmpty
                ? ListView(
                    children: widget.tree
                        .map((n) => _CategoryTile(
                              node: n,
                              depth: 0,
                              preselectedId: widget.preselectedId,
                              onLeafTap: widget.onSelected,
                            ))
                        .toList(),
                  )
                : _buildSearchResults(q, theme),
          ),
        ],
      ),
    );
  }

  Widget _buildSearchResults(String q, ThemeData theme) {
    final leaves = _flatLeaves(widget.tree, [])
        .where((fc) => fc.path.any((p) => p.toLowerCase().contains(q)))
        .toList()
      ..sort((a, b) => a.path.last.toLowerCase().compareTo(b.path.last.toLowerCase()));

    if (leaves.isEmpty) {
      return const Center(child: Text('Inga kategorier matchar sökningen.'));
    }
    return ListView.separated(
      itemCount: leaves.length,
      separatorBuilder: (_, __) => const Divider(height: 1),
      itemBuilder: (ctx, i) {
        final fc = leaves[i];
        return ListTile(
          title: Text(fc.node.name),
          subtitle: Text(
            fc.path.take(fc.path.length - 1).join(' › '),
            style: theme.textTheme.bodySmall?.copyWith(
              color: theme.colorScheme.onSurfaceVariant,
            ),
          ),
          selected: fc.node.id == widget.preselectedId,
          onTap: () => widget.onSelected(fc.node),
        );
      },
    );
  }
}

class _FlatCategory {
  final AdminCategoryNode node;
  final List<String> path;
  const _FlatCategory({required this.node, required this.path});
}

// ── Rekursiv kategoritile med expand/kollaps ─────────────────────────────────

class _CategoryTile extends StatefulWidget {
  final AdminCategoryNode node;
  final int depth;
  final int? preselectedId;
  final void Function(AdminCategoryNode) onLeafTap;

  const _CategoryTile({
    required this.node,
    required this.depth,
    required this.onLeafTap,
    this.preselectedId,
  });

  @override
  State<_CategoryTile> createState() => _CategoryTileState();
}

class _CategoryTileState extends State<_CategoryTile> {
  late bool _expanded;

  @override
  void initState() {
    super.initState();
    // Expandera automatiskt om den förevalda noden finns i denna gren
    _expanded = widget.preselectedId != null &&
        _containsId(widget.node, widget.preselectedId!);
  }

  bool _containsId(AdminCategoryNode node, int id) {
    if (node.id == id) return true;
    return node.children.any((c) => _containsId(c, id));
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final node = widget.node;
    final isLeaf = node.children.isEmpty;
    final isPreselected = node.id == widget.preselectedId;
    final indent = widget.depth * 16.0;

    if (isLeaf) {
      return Padding(
        padding: EdgeInsets.only(left: indent),
        child: ListTile(
          dense: true,
          selected: isPreselected,
          selectedColor: theme.colorScheme.primary,
          selectedTileColor: theme.colorScheme.primaryContainer.withValues(alpha: 0.3),
          leading: Icon(
            Icons.label_outline,
            size: 16,
            color: isPreselected ? theme.colorScheme.primary : theme.colorScheme.onSurfaceVariant,
          ),
          title: Text(
            node.name,
            style: theme.textTheme.bodyMedium?.copyWith(
              fontWeight: isPreselected ? FontWeight.bold : null,
            ),
          ),
          onTap: () => widget.onLeafTap(node),
        ),
      );
    }

    final sortedChildren = [...node.children]
      ..sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));

    return Padding(
      padding: EdgeInsets.only(left: indent),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          ListTile(
            dense: widget.depth > 0,
            leading: Icon(
              _expanded ? Icons.expand_less : Icons.chevron_right,
              size: 18,
              color: theme.colorScheme.onSurfaceVariant,
            ),
            title: Text(
              node.name,
              style: theme.textTheme.bodyMedium?.copyWith(
                fontWeight: FontWeight.w600,
              ),
            ),
            trailing: TextButton(
              style: TextButton.styleFrom(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                minimumSize: const Size(0, 32),
                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              ),
              onPressed: () => widget.onLeafTap(node),
              child: const Text('Välj'),
            ),
            onTap: () => setState(() => _expanded = !_expanded),
          ),
          if (_expanded)
            ...sortedChildren.map((child) => _CategoryTile(
                  node: child,
                  depth: widget.depth + 1,
                  preselectedId: widget.preselectedId,
                  onLeafTap: widget.onLeafTap,
                )),
        ],
      ),
    );
  }
}
