import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_navigation/src/dialog/dialog_route.dart';

typedef DialogTransitions = Widget Function(BuildContext context, Animation<double> animation,
    Animation<double> secondaryAnimation, Widget child);

enum DialogAnimation { fadeIn, scale, slideIn, rightToLeft, material }

class DialogUtils {
  static Widget _buildScaleTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return Transform.scale(
        scale: animation.value, child: Opacity(opacity: animation.value, child: child));
  }

  static Widget _buildSlideInTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(0.0, 0.4),
        end: const Offset(0.0, 0.0),
      ).animate(animation),
      child: FadeTransition(opacity: animation, child: child),
    );

    // return FadeTransition(opacity: animation, child: child);
  }

  static Widget _buildRightToLeftTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    if (animation.status == AnimationStatus.reverse) {
      return SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(-1.0, 0.0),
          end: const Offset(0.0, 0.0),
        ).animate(animation),
        child: FadeTransition(opacity: animation, child: child),
      );
    } else {
      return SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(1.0, 0.0),
          end: const Offset(0.0, 0.0),
        ).animate(animation),
        child: FadeTransition(opacity: animation, child: child),
      );
    }

    // return FadeTransition(opacity: animation, child: child);
  }

  static Widget _buildMaterialDialogTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return FadeTransition(
      opacity: CurvedAnimation(
        parent: animation,
        curve: Curves.easeOut,
      ),
      child: child,
    );
  }

  static DialogTransitions _buildTransitions(DialogAnimation animation) {
    switch (animation) {
      case DialogAnimation.scale:
        return _buildScaleTransitions;
      case DialogAnimation.slideIn:
        return _buildSlideInTransitions;
      case DialogAnimation.rightToLeft:
        return _buildRightToLeftTransitions;
      default:
        return _buildMaterialDialogTransitions;
    }
  }

  static Future showDialog({
    required Widget widget,
    bool barrierDismissible = true,
    Color? barrierColor = const Color(0xAF000000),
    bool useRootNavigator = true,
    bool useSafeArea = true,
    bool ignoreBack = false,
    bool replace = false,
    // AudioEffect? showAudio = CardAudioBundle.pageIn,
    // AudioEffect? backAudio = CardAudioBundle.pageOut,
    Bindings? bindings,
    Duration transitionDuration = const Duration(milliseconds: 150),
    DialogAnimation animation = DialogAnimation.slideIn,
    RouteSettings? routeSettings,
  }) {
    if (barrierColor == null || barrierColor.value == 0) {
      barrierColor = const Color(0x01000000);
    }
    // if (showAudio != null) {
    //   CardAudio.play(showAudio);
    // }
    return generalDialogEx(
        pageBuilder: (buildContext, animation, secondaryAnimation) {
          final pageChild = widget;
          bindings?.dependencies();
          Widget dialog = Builder(builder: (context) {
            return Dialog(
              backgroundColor: Colors.transparent,
              elevation: 0,
              insetPadding: EdgeInsets.zero,
              child: pageChild,
            );
          });
          if (useSafeArea) {
            dialog = SafeArea(child: dialog);
          }
          dialog = WillPopScope(
              child: dialog,
              onWillPop: () async {
                if (ignoreBack) {
                  return false;
                }
                // if (backAudio != null) {
                //   CardAudio.play(backAudio);
                // }
                return true;
              });
          return dialog;
        },
        replace: replace,
        barrierColor: barrierColor,
        barrierDismissible: barrierDismissible,
        barrierLabel: MaterialLocalizations.of(Get.context!).modalBarrierDismissLabel,
        routeSettings: routeSettings,
        transitionDuration: transitionDuration,
        transitionBuilder: _buildTransitions(animation));
  }

  static Future<T?> generalDialogEx<T>({
    required RoutePageBuilder pageBuilder,
    bool barrierDismissible = false,
    String? barrierLabel,
    bool replace = false,
    Color barrierColor = const Color(0x80000000),
    Duration transitionDuration = const Duration(milliseconds: 200),
    RouteTransitionsBuilder? transitionBuilder,
    GlobalKey<NavigatorState>? navigatorKey,
    RouteSettings? routeSettings,
  }) {
    if (replace) {
      assert(!barrierDismissible || barrierLabel != null);
      final nav = navigatorKey?.currentState ??
          Navigator.of(Get.overlayContext!,
              rootNavigator: true); //overlay context will always return the root navigator
      return nav.pushReplacement(
          GetDialogRoute<T>(
            pageBuilder: pageBuilder,
            barrierDismissible: barrierDismissible,
            barrierLabel: barrierLabel,
            barrierColor: barrierColor,
            transitionDuration: transitionDuration,
            transitionBuilder: transitionBuilder,
            settings: routeSettings,
          ),
          result: null);
    } else {
      return Get.generalDialog(
        pageBuilder: pageBuilder,
        barrierDismissible: barrierDismissible,
        barrierLabel: barrierLabel,
        barrierColor: barrierColor,
        transitionDuration: transitionDuration,
        transitionBuilder: transitionBuilder,
        routeSettings: routeSettings,
      );
    }
  }
}
