import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rasadyar_core/presentation/common/app_color.dart';

class OverlayDropdownWidget<T> extends StatefulWidget {
  final List<T> items;
  final T? selectedItem;
  final T? initialValue;
  final int? height;
  final Color? background;
  final bool? hasDropIcon;
  final Widget Function(T item) itemBuilder;
  final Widget Function(T? selected) labelBuilder;
  final void Function(T selected)? onChanged;
  final EdgeInsets? contentPadding;
  final bool isDisabled;

  const OverlayDropdownWidget({
    super.key,
    required this.items,
    required this.itemBuilder,
    required this.labelBuilder,
    this.initialValue,
    this.onChanged,
    this.selectedItem,
    this.contentPadding,
    this.height,
    this.background,
    this.hasDropIcon = true,
    this.isDisabled = false,
  });

  @override
  State<OverlayDropdownWidget<T>> createState() => _OverlayDropdownState<T>();
}

class _OverlayDropdownState<T> extends State<OverlayDropdownWidget<T>> {
  final GlobalKey _key = GlobalKey();
  OverlayEntry? _overlayEntry;
  final RxBool _isOpen = false.obs;
  T? selectedItem;

  @override
  void initState() {
    super.initState();
    selectedItem = widget.selectedItem ?? widget.initialValue;
  }

  @override
  void didUpdateWidget(covariant OverlayDropdownWidget<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.selectedItem != oldWidget.selectedItem) {
      setState(() {
        selectedItem = widget.selectedItem;
      });
    }
  }

  void _showOverlay() {
    final renderBox = _key.currentContext!.findRenderObject() as RenderBox;
    final size = renderBox.size;
    final offset = renderBox.localToGlobal(Offset.zero);

    _overlayEntry = OverlayEntry(
      builder: (_) => GestureDetector(
        onTap: _removeOverlay,
        behavior: HitTestBehavior.translucent,
        child: Stack(
          children: [
            Positioned(
              left: offset.dx,
              top: offset.dy + size.height + 4,
              width: size.width,
              child: Material(
                elevation: 4,
                borderRadius: BorderRadius.circular(8),
                child: Container(
                  decoration: BoxDecoration(
                    color: AppColor.bgLight,
                    border: Border.all(color: AppColor.darkGreyLight),
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Container(
                    constraints: BoxConstraints(maxHeight: 300),
                    child: ListView(
                      padding: EdgeInsets.only(bottom: 50),
                      shrinkWrap: true,
                      physics: BouncingScrollPhysics(),
                      scrollDirection: Axis.vertical,
                      children: widget.items.map((item) {
                        return InkWell(
                          onTap: () {
                            widget.onChanged?.call(item);
                            setState(() {
                              selectedItem = item;
                            });
                            _removeOverlay();
                          },
                          child: Padding(
                            padding:
                                widget.contentPadding ??
                                const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                            child: widget.itemBuilder(item),
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

    Overlay.of(context).insert(_overlayEntry!);
    _isOpen.value = true;
  }

  void _removeOverlay() {
    _overlayEntry?.remove();
    _overlayEntry = null;
    _isOpen.value = false;
  }

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

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      key: _key,
      onTap: widget.isDisabled
          ? null
          : () {
              _isOpen.value ? _removeOverlay() : _showOverlay();
            },
      child: Container(
        height: widget.height?.toDouble() ?? 40,
        width: Get.width,
        padding: const EdgeInsets.symmetric(horizontal: 12),
        decoration: BoxDecoration(
          color: widget.background ?? AppColor.bgLight,
          border: Border.all(color: AppColor.darkGreyLight),
          borderRadius: BorderRadius.circular(8),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(child: widget.labelBuilder(selectedItem)),
            Visibility(
              visible: widget.hasDropIcon!,
              child: Icon(
                _isOpen.value ? CupertinoIcons.chevron_up : CupertinoIcons.chevron_down,
                size: 14,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class OverlayDropdownWidget2<T> extends StatefulWidget {
  final List<T> items;
  final T? selectedItem;
  final T? initialValue;
  final Widget Function(T item) itemBuilder;
  final Widget Function(T? selected) labelBuilder;
  final void Function(T selected)? onChanged;
  final EdgeInsets? contentPadding;
  final String Function(T item)? itemToString;

  const OverlayDropdownWidget2({
    super.key,
    required this.items,
    required this.itemBuilder,
    required this.labelBuilder,
    this.initialValue,
    this.onChanged,
    this.selectedItem,
    this.contentPadding,
    this.itemToString,
  });

  @override
  State<OverlayDropdownWidget2<T>> createState() => _OverlayDropdownState2<T>();
}

class _OverlayDropdownState2<T> extends State<OverlayDropdownWidget2<T>> {
  final GlobalKey _key = GlobalKey();
  OverlayEntry? _overlayEntry;
  final RxBool _isOpen = false.obs;
  T? selectedItem;

  late TextEditingController _searchController;
  late RxList<T> _filteredItems;

  @override
  void initState() {
    super.initState();
    selectedItem = widget.selectedItem ?? widget.initialValue;
    _searchController = TextEditingController();
    _filteredItems = RxList<T>(widget.items);
  }

  void _showOverlay() {
    final renderBox = _key.currentContext!.findRenderObject() as RenderBox;
    final size = renderBox.size;
    final offset = renderBox.localToGlobal(Offset.zero);
    final screenHeight = MediaQuery.of(context).size.height;

    final bool openUp = offset.dy + size.height + 300 > screenHeight;

    _searchController.clear();
    _filteredItems.value = widget.items;

    _overlayEntry = OverlayEntry(
      builder: (_) => GestureDetector(
        onTap: _removeOverlay,
        behavior: HitTestBehavior.translucent,
        child: Stack(
          children: [
            Positioned(
              left: offset.dx,
              top: openUp ? offset.dy - 300 - 4 : offset.dy + size.height + 4,
              width: size.width,
              child: Material(
                elevation: 4,
                borderRadius: BorderRadius.circular(8),
                child: Obx(
                  () => Container(
                    decoration: BoxDecoration(
                      color: AppColor.bgLight,
                      border: Border.all(color: AppColor.darkGreyLight),
                      borderRadius: BorderRadius.circular(8),
                    ),
                    constraints: BoxConstraints(maxHeight: 300),
                    child: Column(
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(8),
                          child: TextField(
                            controller: _searchController,
                            decoration: const InputDecoration(
                              hintText: 'جستجو...',
                              isDense: true,
                              contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                              border: OutlineInputBorder(),
                            ),
                            onChanged: (query) {
                              _filteredItems.value = widget.items
                                  .where(
                                    (item) =>
                                        widget.itemToString
                                            ?.call(item)
                                            .toLowerCase()
                                            .contains(query.toLowerCase()) ??
                                        false,
                                  )
                                  .toList();
                            },
                          ),
                        ),
                        if (_filteredItems.isEmpty)
                          const Padding(
                            padding: EdgeInsets.all(16.0),
                            child: Text("نتیجه‌ای یافت نشد."),
                          ),
                        if (_filteredItems.isNotEmpty)
                          Flexible(
                            child: ListView.builder(
                              itemCount: _filteredItems.length,
                              itemBuilder: (context, index) {
                                var item = _filteredItems[index];
                                return InkWell(
                                  onTap: () {
                                    widget.onChanged?.call(item);
                                    setState(() {
                                      selectedItem = item;
                                    });
                                    _removeOverlay();
                                  },
                                  child: Padding(
                                    padding:
                                        widget.contentPadding ??
                                        const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                                    child: widget.itemBuilder(item),
                                  ),
                                );
                              },
                              physics: const BouncingScrollPhysics(),
                            ),
                          ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

    Overlay.of(context).insert(_overlayEntry!);
    _isOpen.value = true;
  }

  void _removeOverlay() {
    _overlayEntry?.remove();
    _overlayEntry = null;
    _isOpen.value = false;
  }

  @override
  void dispose() {
    _removeOverlay();
    _searchController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
      ignoring: widget.items.isEmpty,
      child: GestureDetector(
        key: _key,
        onTap: () {
          _isOpen.value ? _removeOverlay() : _showOverlay();
        },
        child: Container(
          height: 40,
          width: Get.width,
          padding: const EdgeInsets.symmetric(horizontal: 12),
          decoration: BoxDecoration(
            color: widget.items.isEmpty ? Colors.grey.shade200 : AppColor.bgLight,
            border: Border.all(color: AppColor.darkGreyLight),
            borderRadius: BorderRadius.circular(8),
          ),
          child: Obx(
            () => Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Expanded(child: widget.labelBuilder(selectedItem)),
                Icon(
                  _isOpen.value ? CupertinoIcons.chevron_up : CupertinoIcons.chevron_down,
                  size: 14,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
