import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:sendtrain/services/apis/google_places_service.dart';
import 'package:sendtrain/services/functional/debouncer.dart';
import 'package:sendtrain/widgets/generic/elements/form_text_input.dart';

class FormSearchInput extends StatefulWidget {
  const FormSearchInput(
      {super.key, required this.sessionController, this.optionalPayload});

  final TextEditingController sessionController;
  final dynamic optionalPayload;

  @override
  State<FormSearchInput> createState() => _FormSearchInputState();
}

class _FormSearchInputState extends State<FormSearchInput> {
  String? _currentQuery;

  final service = GooglePlacesService();

  // The most recent suggestions received from the API.
  late Iterable<Widget> _lastOptions = <Widget>[];
  late final Debouncer debouncer;

  // Calls the "remote" API to search with the given query. Returns null when
  // the call has been made obsolete.
  Future<Iterable<Suggestion>?> _search(String query) async {
    _currentQuery = query;

    // In a real application, there should be some error handling here.
    // final Iterable<String> options = await _FakeAPI.search(_currentQuery!);
    if (query.isNotEmpty) {
      final List<Suggestion>? suggestions =
          await service.fetchSuggestions(_currentQuery!, 'en');

      // If another search happened after this one, throw away these options.
      if (_currentQuery != query) {
        return null;
      }
      _currentQuery = null;

      return suggestions?.map((suggestion) => suggestion);
    } else {
      return null;
    }
  }

  @override
  void initState() {
    super.initState();
    debouncer = Debouncer(Duration(milliseconds: 50), _search);
  }

  @override
  Widget build(BuildContext context) {
    return SearchAnchor(
        builder: (BuildContext context, SearchController controller) {
      return FormTextInput(
          controller: widget.sessionController,
          title: 'Location (optional)',
          icon: Icon(Icons.search_rounded),
          maxLines: 2,
          requiresValidation: false,
          onTap: () {
            controller.openView();
          });
    }, suggestionsBuilder:
            (BuildContext context, SearchController controller) async {
      final List<Suggestion>? options =
          (await debouncer.process(controller.text))?.toList();
      if (options == null) {
        return _lastOptions;
      }
      _lastOptions = List<ListTile>.generate(options.length, (int index) {
        final Suggestion item = options[index];
        return ListTile(
          title: Text(item.description),
          onTap: () async {
            // widget.optionalPayload = service.fetchPhoto(json.decode(item.image));
            if (item.imageReferences != null) {
              // get a random photo item from the returned result
              Map<String, dynamic> photo = item.imageReferences![
                  Random().nextInt(item.imageReferences!.length)];

              await service.fetchPhoto(photo['name']).then((photoMap) {
                widget.optionalPayload.photoUri = photoMap['photoUri'];
              });
            }

            widget.optionalPayload.address = item.address;
            widget.sessionController.text = item.description;
            service.finish();
            controller.closeView(item.description);
          },
        );
      });

      return _lastOptions;
    });
  }
}