// SPDX-FileCopyrightText: © 2025 Nøkken.io <nokken.io@proton.me>
// SPDX-License-Identifier: AGPL-3.0
//
//  autocomplete_text_field.dart
//  A reusable autocomplete text field widget
//
import 'package:flutter/material.dart';
import 'package:nokken/src/core/ui/theme/app_theme.dart';
import 'package:nokken/src/core/ui/theme/app_colors.dart';
import 'package:nokken/src/core/ui/theme/app_text_styles.dart';

/// A text field with autocomplete functionality for medical providers
class AutocompleteTextField extends StatefulWidget {
  final TextEditingController controller;
  final String labelText;
  final String hintText;
  final List<String> options;
  final ValueChanged<String>? onSelected;
  final bool isLoading;

  const AutocompleteTextField({
    super.key,
    required this.controller,
    required this.labelText,
    required this.options,
    this.hintText = '',
    this.onSelected,
    this.isLoading = false,
  });

  @override
  State<AutocompleteTextField> createState() => _AutocompleteTextFieldState();
}

class _AutocompleteTextFieldState extends State<AutocompleteTextField> {
  // Track whether the field is focused for showing loading state
  bool _isFocused = false;

  @override
  Widget build(BuildContext context) {
    return Focus(
      onFocusChange: (hasFocus) {
        setState(() {
          _isFocused = hasFocus;
        });
      },
      child: Autocomplete<String>(
        optionsBuilder: (TextEditingValue textEditingValue) {
          if (textEditingValue.text.isEmpty) {
            return const Iterable<String>.empty();
          }

          final query = textEditingValue.text.toLowerCase();
          return widget.options
              .where((option) => option.toLowerCase().contains(query));
        },
        displayStringForOption: (option) => option,
        fieldViewBuilder: (
          BuildContext context,
          TextEditingController fieldController,
          FocusNode fieldFocusNode,
          VoidCallback onFieldSubmitted,
        ) {
          // Sync the internal controller with our external one
          fieldController.text = widget.controller.text;
          fieldController.selection = widget.controller.selection;

          // Listen to changes in the field and update our controller
          fieldController.addListener(() {
            widget.controller.text = fieldController.text;
            widget.controller.selection = fieldController.selection;
          });

          return TextFormField(
            controller: fieldController,
            focusNode: fieldFocusNode,
            decoration: AppTheme.defaultTextFieldDecoration.copyWith(
              labelText: widget.labelText,
              hintText: widget.hintText,
              // Show loading indicator when options are being loaded and field is focused
              suffixIcon: (_isFocused && widget.isLoading)
                  ? SizedBox(
                      height: 20,
                      width: 20,
                      child: Padding(
                        padding: const EdgeInsets.all(12.0),
                        child: CircularProgressIndicator(
                          strokeWidth: 2,
                          color: AppColors.primary,
                        ),
                      ),
                    )
                  : null,
            ),
          );
        },
        onSelected: (String selection) {
          widget.controller.text = selection;
          if (widget.onSelected != null) {
            widget.onSelected!(selection);
          }
        },
        optionsViewBuilder: (
          BuildContext context,
          AutocompleteOnSelected<String> onSelected,
          Iterable<String> options,
        ) {
          return Align(
            alignment: Alignment.topLeft,
            child: Material(
              elevation: 4.0,
              color: AppColors.surface,
              child: ConstrainedBox(
                constraints:
                    const BoxConstraints(maxHeight: 200, maxWidth: 300),
                child: ListView.builder(
                  padding: const EdgeInsets.all(8.0),
                  shrinkWrap: true,
                  itemCount: options.length,
                  itemBuilder: (BuildContext context, int index) {
                    final option = options.elementAt(index);
                    return InkWell(
                      onTap: () {
                        onSelected(option);
                      },
                      child: Padding(
                        padding: const EdgeInsets.all(12.0),
                        child: Text(
                          option,
                          style: AppTextStyles.bodyMedium,
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
