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

/// Reusable spring route
class CustomPageRoute<T> extends PageRouteBuilder<T> {
  final Widget page;
  final AxisDirection direction;
  final bool fullScreenDialog;


  CustomPageRoute({required this.page, this.direction = AxisDirection.right, this.fullScreenDialog = false, super.settings})
      : super(
          transitionDuration: const Duration(milliseconds: 1500),
          reverseTransitionDuration: const Duration(milliseconds: 500),
          fullscreenDialog: fullScreenDialog,
          pageBuilder: (_, __, ___) => page,
          transitionsBuilder: (context, animation, secondaryAnimation, child) {
            final spring = SpringDescription(mass: 1, stiffness: 100, damping: 15);

            // Drive animation with spring
            final curvedAnimation = animation.drive(
              Tween<double>(begin: 0.0, end: 1.0).chain(CurveTween(curve: _SpringCurve(spring))),
            );

            // Choose offset based on direction
            Offset beginOffset;
            switch (direction) {
              case AxisDirection.left:
                beginOffset = const Offset(-1.0, 0.0);
                break;
              case AxisDirection.right:
                beginOffset = const Offset(1.0, 0.0);
                break;
              case AxisDirection.up:
                beginOffset = const Offset(0.0, -1.0);
                break;
              case AxisDirection.down:
                beginOffset = const Offset(0.0, 1.0);
                break;
            }

            final offsetAnimation = Tween<Offset>(begin: beginOffset, end: Offset.zero).animate(curvedAnimation);

            return SlideTransition(
              position: offsetAnimation,
              child: child,
            );
          },
        );
}

/// Custom spring curve
class _SpringCurve extends Curve {
  final SpringDescription spring;

  _SpringCurve(this.spring);

  @override
  double transform(double t) {
    final sim = SpringSimulation(spring, 0, 1, 0);
    return sim.x(t * 1.5); // scaled time
  }
}
