import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

///统一管理唯一Overlay
mixin OverlayManagerMixin<T extends StatefulWidget> on State<T> {
  bool _overlayEntryInserted = false;
  OverlayState? _overlayState;
  OverlayEntry _overlayEntry = OverlayEntry(
    builder: (_) => const SizedBox.shrink(),
  );

  @override
  void initState() {
    super.initState();
    _overlayState = Overlay.of(context);
  }

  void injectOverlay(Widget widget, double width, double height) {
    if (_overlayEntryInserted) {
      debugPrint("overlay 没有销毁，不允许重复插入");
      return;
    }
    _overlayEntry = OverlayEntry(builder: (_) {
      return Material(
        type: MaterialType.transparency,
        child: DragHoverBothSidesWidget(widget, width, height),
      );
    });
    _overlayState?.insert(_overlayEntry);
    _overlayEntryInserted = true;
  }

  void removeOverlay() {
    // Call `remove` only when the entry has been inserted.
    if (_overlayEntryInserted) {
      _overlayEntry.remove();
      _overlayEntryInserted = false;
    }
  }
}

///创建一个可以拖拽悬停两边控件
class DragHoverBothSidesWidget extends StatefulWidget {
  Widget child;

  ///可拖拽控件的宽高
  double height;
  double width;
  double bottomDistance;

  DragHoverBothSidesWidget(this.child, this.width, this.height,
      {Key? key, this.bottomDistance = 68})
      : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return DragHoverBothSidesState();
  }
}

final double ratio = WidgetsBinding.instance.window.devicePixelRatio;

class DragHoverBothSidesState extends State<DragHoverBothSidesWidget> {
  double _dx = 0;
  double _dy = 0;
  final Size _windowSize = WidgetsBinding.instance.window.physicalSize / ratio;

  @override
  void initState() {
    super.initState();
    _dx = _windowSize.width - widget.width;
    _dy = _windowSize.height - widget.height - widget.bottomDistance;
  }

  void dragEnd(DragEndDetails details) {
    if (_dx + widget.width / 2 < _windowSize.width / 2) {
      _dx = 0;
    } else {
      _dx = _windowSize.width - widget.width;
    }
    if (_dy + widget.height > _windowSize.height) {
      _dy = _windowSize.height - widget.height - widget.bottomDistance;
    } else if (_dy < 0) {
      _dy = 0;
    }
    setState(() {});
  }

  void dragEvent(DragUpdateDetails details) {
    _dx = details.globalPosition.dx - widget.width / 2;
    _dy = details.globalPosition.dy - widget.height / 2;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: _windowSize.width,
      height: _windowSize.height,
      // color: Colors.green,
      child: Stack(
        alignment: Alignment.center,
        children: [
          Positioned(
              left: _dx,
              top: _dy,
              child: GestureDetector(
                  onVerticalDragEnd: dragEnd,
                  onHorizontalDragEnd: dragEnd,
                  onHorizontalDragUpdate: dragEvent,
                  onVerticalDragUpdate: dragEvent,
                  child: widget.child))
        ],
      ),
    );
  }
}
