// import 'package:fis_lib_dropdown_button/dropdown_button2.dart'
//     as fis_lib_dropdown;

/// 【TODO】 需要迁移到ui库，
import 'package:fis_common/event/event_type.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';

class FMutiSelectModel {
  FMutiSelectModel({required this.name, required this.code});
  final String name;
  final String code;
}

/// 多选框
class FMutiSelect<T, TValue> extends StatefulWidget implements FWidget {
  const FMutiSelect({
    Key? key,
    required this.source,
    this.value,
    required this.optionValueExtractor,
    required this.optionLabelExtractor,
    this.onSelectChanged,
    this.hintText,
    this.clearable = false,
    this.isExpanded = false,
    this.width,
    this.height,
    this.fontSize,
    this.decoration,
    this.specialWidget,
    this.specialWidgetHeight,
    this.onLoad,
    this.isSearchInner = false,
    this.textColor,
    this.fontFamily,
    this.buttonDecoration,
    this.focusNode,
    this.onReload,
  }) : super(key: key);

  ///按钮装饰器
  final BoxDecoration? buttonDecoration;

  ///文本颜色
  final Color? textColor;

  ///文本字体
  final String? fontFamily;

  /// 数据源
  final List<T> source;

  /// 已选值
  final List<TValue>? value;

  /// 选项值提取器
  ///
  /// [data] 选项数据源
  final TValue Function(T data) optionValueExtractor;

  /// 选项文本提取器
  ///
  /// [data] 选项数据源
  final String Function(T data) optionLabelExtractor;

  /// 选中变更事件
  ///
  /// [value] 当前已选值
  ///
  /// [index] 当前已选索引
  final void Function(List<TValue>? value, int? index)? onSelectChanged;

  /// 选择提示文本
  final String? hintText;

  /// 是否可清除
  final bool clearable;

  /// 是否自适应 (开启后[width]和[height]不起作用)
  final bool isExpanded;

  /// 自定义宽度
  final double? width;

  /// 自定义高度
  final double? height;

  /// 自定义字体大小
  final double? fontSize;

  /// 自定义item
  final Widget Function(T data)? specialWidget;

  /// 自定义的item的高度
  final double? specialWidgetHeight;

  /// 装饰器
  final BoxDecoration? decoration;

  /// 刷新加载
  final Function(String? keyWords)? onLoad;

  /// 是否展示搜索功能
  final bool? isSearchInner;

  final FocusNode? focusNode;

  final FEventHandler<bool>? onReload;

  @override
  State<StatefulWidget> createState() => _FMutiSelectState<T, TValue>();
}

class _FMutiSelectState<T, TValue> extends State<FMutiSelect<T, TValue>> {
  /// 数据源
  List<T> _source = [];
  final TextEditingController textEditingController = TextEditingController();
  List<TValue> selectedValues = [];
  @override
  void initState() {
    _source = widget.source;
    selectedValues = widget.value ?? [];
    setState(() {});

    super.initState();
  }

  @override
  void didUpdateWidget(covariant FMutiSelect<T, TValue> oldWidget) {
    if (_source != widget.source) {
      setState(() {
        _source = widget.source;
      });
      selectedValues.clear();
      selectedValues = widget.value ?? [];
    }

    // selectedValues.addAll(widget.value ?? []);
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    var buttonDecoration = widget.buttonDecoration ??
        BoxDecoration(
          border: Border.all(color: Color(0xffdcdfe6), width: 0.8),
          // border: Border.all(color: Colors.grey[200]!, width: 0.5),
          borderRadius: BorderRadius.circular(4),
        );
    if (widget.decoration != null) {
      final cfg = widget.decoration!;
      buttonDecoration = widget.buttonDecoration ??
          buttonDecoration.copyWith(
            color: cfg.color,
            image: cfg.image,
            border: cfg.border,
            borderRadius: cfg.borderRadius,
            backgroundBlendMode: cfg.backgroundBlendMode,
            boxShadow: cfg.boxShadow,
            shape: cfg.shape,
            gradient: cfg.gradient,
          );
    }

    return DropDownSelect<T, TValue>(
      source: _source,
      optionLabelExtractor: widget.optionLabelExtractor,
      optionValueExtractor: widget.optionValueExtractor,
      selectedValues: selectedValues,
      onMutiSelectValue: (value) {
        selectedValues = value;
        widget.onSelectChanged?.call(value, 1);
      },
    );
  }
}

class _OptionRow<TValue> extends StatelessWidget {
  const _OptionRow(
    this.label, {
    Key? key,
    this.isSelected = false,
    this.fontSize,
    this.buttonDecoration,
    this.value,
    required this.onMuitSelect,
  }) : super(key: key);

  final String label;
  final bool isSelected;
  final double? fontSize;
  final BoxDecoration? buttonDecoration;
  final TValue? value;
  final ValueCallback<TValue> onMuitSelect;

  @override
  Widget build(BuildContext context) {
    final text = Text(
      label,
      style: TextStyle(
        overflow: TextOverflow.ellipsis,
        fontSize: fontSize ?? 16,
        color: isSelected ? Theme.of(context).primaryColor : null,
        height: 1,
      ),
    );
    return Material(
      color: isSelected ? Theme.of(context).secondaryHeaderColor : null,
      child: InkWell(
        onTap: () {
          onMuitSelect.call(value!);
        },
        child: Container(
          padding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
          alignment: Alignment.centerLeft,
          child: text,
        ),
      ),
    );
  }
}

class DropDownSelectItem<T, TValue> extends StatefulWidget {
  DropDownSelectItem({
    required this.source,
    required this.width,
    required this.optionValueExtractor,
    required this.optionLabelExtractor,
    required this.onMutiSelectValue,
    required this.selectedValues,
  });
  final double width;
  final List<T> source;

  /// 选项值提取器
  ///
  /// [data] 选项数据源
  final TValue Function(T data) optionValueExtractor;

  /// 选项文本提取器
  ///
  /// [data] 选项数据源
  final String Function(T data) optionLabelExtractor;

  final ValueCallback onMutiSelectValue;

  final List<TValue> selectedValues;

  @override
  State<DropDownSelectItem> createState() =>
      _DropDownSelectItemState<T, TValue>();
}

class _DropDownSelectItemState<T, TValue>
    extends State<DropDownSelectItem<T, TValue>> {
  List<TValue> selectedList = [];
  List<String> selectedNameList = [];

  @override
  void initState() {
    super.initState();
    selectedList = widget.selectedValues;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.symmetric(vertical: 5),
      height: widget.source.length * 46,
      constraints: BoxConstraints(
        maxHeight: 300,
      ),
      width: widget.width,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(4),
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.5),
            spreadRadius: 5,
            blurRadius: 7,
            offset: Offset(0, 3), // 阴影偏移量
          ),
        ],
      ),
      child: Scrollbar(
        isAlwaysShown: true,
        child: ListView(
          children: buildItems(),
        ),
      ),
    );
  }

  List<Widget> buildItems() {
    return widget.source.map((T e) {
      final TValue value = widget.optionValueExtractor(e);
      final String name = widget.optionLabelExtractor(e);
      final isSelected = selectedList.contains(value);
      return _OptionRow(
        name,
        isSelected: isSelected,
        value: widget.optionValueExtractor(e),
        onMuitSelect: (value) {
          if (!isSelected) {
            selectedList.add(value);
          } else {
            selectedList.remove(value);
          }
          widget.onMutiSelectValue.call(selectedList);
          setState(() {});
        },
      );
    }).toList();
  }
}

class DropDownSelect<T, TValue> extends StatefulWidget {
  /// 数据源
  final List<T> source;

  /// 选项值提取器
  ///
  /// [data] 选项数据源
  final TValue Function(T data) optionValueExtractor;

  /// 选项文本提取器
  ///
  /// [data] 选项数据源
  final String Function(T data) optionLabelExtractor;

  /// 数据结果事件回调
  final ValueCallback onMutiSelectValue;

  /// 选中的数据源
  final List<TValue> selectedValues;

  DropDownSelect({
    required this.source,
    required this.optionValueExtractor,
    required this.optionLabelExtractor,
    required this.onMutiSelectValue,
    required this.selectedValues,
  });

  @override
  _DropDownSelectState<T, TValue> createState() =>
      _DropDownSelectState<T, TValue>();
}

class _DropDownSelectState<T, TValue> extends State<DropDownSelect<T, TValue>> {
  final GlobalKey _globalKey = GlobalKey();
  OverlayEntry? _overlayEntry;
  List<TValue> _mutiSelectList = [];
  List<String> _mutiSelectNameList = [];
  @override
  void initState() {
    super.initState();
    _mutiSelectList = widget.selectedValues;
    _resetNameList(isInit: true);
    _overlayEntry = null;
  }

  @override
  void didUpdateWidget(covariant DropDownSelect<T, TValue> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (_mutiSelectList != widget.selectedValues) {
      setState(() {
        _mutiSelectList = widget.selectedValues;
      });
    }
    _resetNameList(isInit: true);
  }

  @override
  void dispose() {
    _overlayEntry?.remove();
    super.dispose();
  }

  void _resetNameList({bool? isInit = false}) {
    List<String> _nameList = [];
    widget.source.forEach((element) {
      for (var i in _mutiSelectList) {
        if (widget.optionValueExtractor(element) == i) {
          _nameList.add(widget.optionLabelExtractor(element));
        }
      }
      _mutiSelectNameList = _nameList;
    });
    if (!isInit! && _mutiSelectList.length != 0) {
      widget.onMutiSelectValue.call(_mutiSelectList);
    }
    setState(() {});
  }

  void _showDropDownSelect() {
    final OverlayState overlayState = Overlay.of(
      context,
      debugRequiredFor: widget,
    );

    final RenderBox targetConatiner =
        overlayState.context.findRenderObject() as RenderBox;
    Offset targetConatinerOffset = targetConatiner.localToGlobal(Offset.zero);

    RenderBox renderBox = context.findRenderObject() as RenderBox;
    Rect box = renderBox.localToGlobal(Offset.zero - targetConatinerOffset) &
        renderBox.size;

    _overlayEntry = OverlayEntry(
      builder: (context) {
        return InkWell(
          onTap: () {
            _hideDropDownSelect();
          },
          child: Stack(children: [
            Positioned(
              left: box.left,
              top: box.bottom,
              child: Material(
                child: DropDownSelectItem(
                  width: box.width,
                  optionLabelExtractor: widget.optionLabelExtractor,
                  optionValueExtractor: widget.optionValueExtractor,
                  source: widget.source,
                  selectedValues: widget.selectedValues,
                  onMutiSelectValue: (value) {
                    _mutiSelectList = value;
                    _resetNameList();
                  },
                ),
              ),
            ),
          ]),
        );
      },
    );

    overlayState.insert(_overlayEntry!);
  }

  void _hideDropDownSelect() {
    _overlayEntry?.remove();
    _overlayEntry = null;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        _hideDropDownSelect();
      },
      child: Center(
        child: Container(
          key: _globalKey,
          height: 36,
          decoration: BoxDecoration(
            border: Border.all(
              color: Color(0xffe6e6e6),
              width: 1.0,
            ),
            borderRadius: BorderRadius.circular(4),
          ),
          child: Material(
            color: Colors.transparent,
            child: InkWell(
              onTap: () {
                if (_overlayEntry != null) {
                  _hideDropDownSelect();
                } else {
                  _showDropDownSelect();
                }
              },
              child: Row(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Expanded(
                    child: Container(
                      padding: EdgeInsets.only(left: 15),
                      child: Text(
                        _mutiSelectNameList.join('、'),
                        overflow: TextOverflow.ellipsis,
                        style:
                            TextStyle(fontSize: 16, color: Color(0xff333333)),
                      ),
                    ),
                  ),
                  Container(
                    padding: EdgeInsets.only(
                      right: 15,
                    ),
                    child: Icon(
                      Icons.arrow_drop_down,
                      size: 24,
                      color: widget.source.length != 0
                          ? Colors.black
                          : Color(0xffe6e6e6),
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
