///
/// Created by @Haoyi on 2021/9/8
///

part of "../guru_popup.dart";

enum GuruToastGravity { top, bottom, center }

extension ToastAware on GuruPopup {
  void showCommonToast(String msg,
      {ToastGravity gravity = ToastGravity.CENTER,
      Duration duration = const Duration(seconds: 2)}) {
    FToast toast = FToast();
    toast.init(Get.overlayContext!);
    // toast.removeQueuedCustomToasts();
    toast.showToast(
        child: SizedBox(
          width: 240,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              FlexibleContainer(
                padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 22),
                color: Colors.black.withOpacity(0.84),
                radius: BorderRadius.circular(20),
                child: Text(
                  msg,
                  textAlign: TextAlign.center,
                  style: const TextStyle(
                      fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
                ),
              ),
            ],
          ),
        ),
        gravity: gravity,
        toastDuration: duration);
  }

  void showWidget(Widget child, BuildContext context,
      {Duration duration = const Duration(seconds: 3),
      GuruToastGravity gravity = GuruToastGravity.bottom,
      Color backgroundColor = Colors.transparent,
      double backgroundRadius = 20}) {
    ToastView.dismiss();
    ToastView.createWidget(
      child,
      duration,
      gravity,
      backgroundColor: backgroundColor,
      backgroundRadius: backgroundRadius,
    );
  }
}

class ToastView {
  static final ToastView _singleton = ToastView._internal();

  factory ToastView() {
    return _singleton;
  }

  ToastView._internal();

  static OverlayState? overlayState;
  static OverlayEntry? _overlayEntry;
  static bool _isVisible = false;

  static void createView(
    String msg,
    BuildContext context,
    Duration duration,
    GuruToastGravity gravity, {
    Color? backgroundColor,
    textStyle = const TextStyle(
      color: Color(0xffffffff),
      fontSize: 11,
      fontWeight: FontWeight.w500,
    ),
    double backgroundRadius = 4,
    Rect? anchorRect,
  }) async {
    overlayState = Overlay.of(context);
    _overlayEntry = OverlayEntry(
      builder: (BuildContext context) => ToastWidget(
        widget: SizedBox(
          width: MediaQuery.of(context).size.width,
          child: Container(
              alignment: Alignment.center,
              width: MediaQuery.of(context).size.width - 80,
              child: Container(
                decoration: BoxDecoration(
                  color: backgroundColor ?? Colors.black.withOpacity(0.3),
                  borderRadius: BorderRadius.circular(backgroundRadius),
                ),
                padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
                child: Text(
                  msg,
                  softWrap: true,
                  style: textStyle,
                  textAlign: TextAlign.center,
                  strutStyle: const StrutStyle(height: 1.5),
                ),
              )),
        ),
        gravity: gravity,
        anchorRect: anchorRect,
      ),
    );
    _isVisible = true;
    overlayState?.insert(_overlayEntry!);
    await Future.delayed(duration);
    dismiss();
  }

  static createWidget(
    Widget widget,
    Duration duration,
    GuruToastGravity gravity, {
    Color? backgroundColor,
    double backgroundRadius = 4,
    Rect? anchorRect,
  }) async {
    overlayState = Overlay.of(Get.overlayContext!);
    _overlayEntry = OverlayEntry(
      builder: (BuildContext context) => ToastWidget(
        widget: SizedBox(
          width: MediaQuery.of(context).size.width,
          child: Container(
              alignment: Alignment.center,
              width: MediaQuery.of(context).size.width - 80,
              child: Container(
                  decoration: BoxDecoration(
                    color: backgroundColor ?? Colors.transparent,
                    borderRadius: BorderRadius.circular(backgroundRadius),
                  ),
                  padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
                  child: widget)),
        ),
        gravity: gravity,
        anchorRect: anchorRect,
      ),
    );
    _isVisible = true;
    overlayState?.insert(_overlayEntry!);
    await Future.delayed(duration);
    dismiss();
  }

  static dismiss() async {
    if (!_isVisible) {
      return;
    }
    _isVisible = false;
    _overlayEntry?.remove();
  }
}

class ToastWidget extends StatelessWidget {
  const ToastWidget({super.key, required this.widget, required this.gravity, this.anchorRect});

  final Widget widget;
  final GuruToastGravity gravity;
  final Rect? anchorRect;

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);
    double top = mediaQuery.padding.top + 50;
    if (anchorRect != null) {
      top = mediaQuery.padding.top + anchorRect!.height;
    }

    return Positioned(
        top: gravity == GuruToastGravity.top ? top : null,
        bottom: gravity == GuruToastGravity.bottom ? mediaQuery.size.height : null,
        left: 40,
        right: 40,
        child: Material(
          child: widget,
        ));
  }
}
