import 'dart:async';
import 'package:flutter/material.dart';
import 'package:em2rp/services/travel_service.dart';

/// Champ texte avec autocomplétion d'adresses via Google Places.
/// Remplace le TextFormField standard pour le champ adresse.
class AddressAutocompleteField extends StatefulWidget {
  final TextEditingController controller;
  final String label;
  final String? Function(String?)? validator;
  final void Function(String)? onSelected;
  final InputDecoration? decoration;

  const AddressAutocompleteField({
    super.key,
    required this.controller,
    this.label = 'Adresse',
    this.validator,
    this.onSelected,
    this.decoration,
  });

  @override
  State<AddressAutocompleteField> createState() =>
      _AddressAutocompleteFieldState();
}

class _AddressAutocompleteFieldState extends State<AddressAutocompleteField> {
  final _service = TravelService();
  final _focusNode = FocusNode();
  final _overlayKey = GlobalKey();

  List<String> _suggestions = [];
  Timer? _debounce;
  OverlayEntry? _overlayEntry;
  final _layerLink = LayerLink();

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(_onTextChanged);
    _focusNode.addListener(() {
      if (!_focusNode.hasFocus) {
        Future.delayed(const Duration(milliseconds: 200), () {
          if (mounted && !_focusNode.hasFocus) {
            _removeOverlay();
          }
        });
      }
    });
  }

  void _onTextChanged() {
    _debounce?.cancel();
    final text = widget.controller.text;
    if (text.length < 3) {
      _removeOverlay();
      return;
    }
    _debounce = Timer(const Duration(milliseconds: 400), () async {
      final results = await _service.autocompleteAddress(text);
      if (mounted) {
        setState(() => _suggestions = results);
        if (results.isNotEmpty && _focusNode.hasFocus) {
          _showSuggestions();
        } else {
          _removeOverlay();
        }
      }
    });
  }

  void _showSuggestions() {
    _removeOverlay();
    final overlay = Overlay.of(context);
    _overlayEntry = OverlayEntry(
      builder: (ctx) => Positioned(
        width: _getFieldWidth(),
        child: CompositedTransformFollower(
          link: _layerLink,
          showWhenUnlinked: false,
          offset: const Offset(0, 56),
          child: Material(
            elevation: 6,
            borderRadius: BorderRadius.circular(8),
            child: ConstrainedBox(
              constraints: const BoxConstraints(maxHeight: 220),
              child: ListView.separated(
                shrinkWrap: true,
                padding: EdgeInsets.zero,
                itemCount: _suggestions.length,
                separatorBuilder: (_, __) =>
                    const Divider(height: 1, indent: 16),
                itemBuilder: (ctx, i) {
                  return GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    onPanDown: (_) {
                      widget.controller.text = _suggestions[i];
                      widget.controller.selection = TextSelection.fromPosition(
                        TextPosition(offset: _suggestions[i].length),
                      );
                      widget.onSelected?.call(_suggestions[i]);
                      _removeOverlay();
                      _focusNode.unfocus();
                    },
                    child: ListTile(
                      dense: true,
                      leading: const Icon(Icons.location_on_outlined, size: 18),
                      title: Text(
                        _suggestions[i],
                        style: const TextStyle(fontSize: 13),
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
    overlay.insert(_overlayEntry!);
  }

  double _getFieldWidth() {
    final rb = context.findRenderObject() as RenderBox?;
    return rb?.size.width ?? 300;
  }

  void _removeOverlay() {
    _overlayEntry?.remove();
    _overlayEntry = null;
    if (mounted) setState(() {});
  }

  @override
  void dispose() {
    _debounce?.cancel();
    widget.controller.removeListener(_onTextChanged);
    _focusNode.dispose();
    _removeOverlay();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: _layerLink,
      child: TextFormField(
        key: _overlayKey,
        controller: widget.controller,
        focusNode: _focusNode,
        decoration: widget.decoration ??
            InputDecoration(
              labelText: widget.label,
              border: const OutlineInputBorder(),
              prefixIcon: const Icon(Icons.location_on_outlined),
              suffixIcon: widget.controller.text.isNotEmpty
                  ? IconButton(
                      icon: const Icon(Icons.clear, size: 18),
                      onPressed: () {
                        widget.controller.clear();
                        _removeOverlay();
                      },
                    )
                  : null,
            ),
        validator: widget.validator,
        onChanged: (_) {},
      ),
    );
  }
}
