import 'package:flutter/material.dart';

typedef CategorySelectOption = ({String value, String label});

class SearchableCategoryField extends StatefulWidget {
  final List<CategorySelectOption> options;
  final String? value;
  final String label;
  final ValueChanged<String?> onChanged;

  const SearchableCategoryField({
    super.key,
    required this.options,
    required this.value,
    required this.label,
    required this.onChanged,
  });

  @override
  State<SearchableCategoryField> createState() => _SearchableCategoryFieldState();
}

class _SearchableCategoryFieldState extends State<SearchableCategoryField> {
  late final TextEditingController _controller;
  late final FocusNode _focusNode;

  String? _labelForValue(String? value) {
    if (value == null) return null;
    for (final option in widget.options) {
      if (option.value == value) return option.label;
    }
    return null;
  }

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController(text: _labelForValue(widget.value) ?? '');
    _focusNode = FocusNode();
  }

  @override
  void didUpdateWidget(covariant SearchableCategoryField oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.value != widget.value || oldWidget.options != widget.options) {
      final label = _labelForValue(widget.value) ?? '';
      if (_controller.text != label) {
        _controller.text = label;
      }
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return RawAutocomplete<CategorySelectOption>(
      textEditingController: _controller,
      focusNode: _focusNode,
      displayStringForOption: (option) => option.label,
      optionsBuilder: (textEditingValue) {
        final query = textEditingValue.text.trim().toLowerCase();
        final options = widget.options;
        if (query.isEmpty) return options.take(30);
        return options.where((option) => option.label.toLowerCase().contains(query)).take(30);
      },
      onSelected: (option) => widget.onChanged(option.value),
      fieldViewBuilder: (context, controller, focusNode, onFieldSubmitted) {
        return TextFormField(
          controller: controller,
          focusNode: focusNode,
          decoration: InputDecoration(
            labelText: widget.label,
            hintText: 'Sök kategori',
            prefixIcon: const Icon(Icons.search),
            border: const OutlineInputBorder(),
          ),
        );
      },
      optionsViewBuilder: (context, onSelected, options) {
        final optionList = options.toList(growable: false);
        return Align(
          alignment: Alignment.topLeft,
          child: Material(
            elevation: 4,
            child: SizedBox(
              width: 420,
              height: 240,
              child: ListView.separated(
                padding: EdgeInsets.zero,
                itemCount: optionList.length,
                separatorBuilder: (_, __) => const Divider(height: 1),
                itemBuilder: (context, index) {
                  final option = optionList[index];
                  return ListTile(
                    dense: true,
                    title: Text(option.label),
                    onTap: () => onSelected(option),
                  );
                },
              ),
            ),
          ),
        );
      },
    );
  }
}
