import 'package:flutter/material.dart';

/// 물리 기반 스프링 애니메이션을 적용하는 위젯
class SpringAnimationWidget extends StatefulWidget {
  final Widget child;
  final Duration delay;
  final SpringDescription spring;
  final Offset? initialOffset;
  final double? initialScale;
  final double? initialRotation;

  const SpringAnimationWidget({
    super.key,
    required this.child,
    this.delay = Duration.zero,
    this.spring = const SpringDescription(
      mass: 1,
      stiffness: 100,
      damping: 10,
    ),
    this.initialOffset,
    this.initialScale,
    this.initialRotation,
  });

  @override
  State<SpringAnimationWidget> createState() => _SpringAnimationWidgetState();
}

class _SpringAnimationWidgetState extends State<SpringAnimationWidget>
    with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Offset> _offsetAnimation;
  late Animation<double> _scaleAnimation;
  late Animation<double> _rotationAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );

    // 오프셋 애니메이션
    _offsetAnimation = Tween<Offset>(
      begin: widget.initialOffset ?? const Offset(0, 50),
      end: Offset.zero,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.elasticOut,
    ));

    // 스케일 애니메이션
    _scaleAnimation = Tween<double>(
      begin: widget.initialScale ?? 0.5,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.elasticOut,
    ));

    // 회전 애니메이션
    _rotationAnimation = Tween<double>(
      begin: widget.initialRotation ?? 0.0,
      end: 0.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.elasticOut,
    ));

    // 지연 후 애니메이션 시작
    Future.delayed(widget.delay, () {
      if (mounted) {
        _controller.forward();
      }
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return Transform.translate(
          offset: _offsetAnimation.value,
          child: Transform.scale(
            scale: _scaleAnimation.value,
            child: Transform.rotate(
              angle: _rotationAnimation.value,
              child: child,
            ),
          ),
        );
      },
      child: widget.child,
    );
  }
}

/// 바운스 효과가 있는 버튼
class BouncyButton extends StatefulWidget {
  final Widget child;
  final VoidCallback? onPressed;
  final EdgeInsetsGeometry? padding;
  final BoxDecoration? decoration;

  const BouncyButton({
    super.key,
    required this.child,
    this.onPressed,
    this.padding,
    this.decoration,
  });

  @override
  State<BouncyButton> createState() => _BouncyButtonState();
}

class _BouncyButtonState extends State<BouncyButton>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _scaleAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 200),
      vsync: this,
    );

    _scaleAnimation = Tween<double>(
      begin: 1.0,
      end: 0.95,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _handleTapDown(TapDownDetails details) {
    _controller.forward();
  }

  void _handleTapUp(TapUpDetails details) {
    _controller.reverse();
    widget.onPressed?.call();
  }

  void _handleTapCancel() {
    _controller.reverse();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: _handleTapDown,
      onTapUp: _handleTapUp,
      onTapCancel: _handleTapCancel,
      child: AnimatedBuilder(
        animation: _scaleAnimation,
        builder: (context, child) {
          return Transform.scale(
            scale: _scaleAnimation.value,
            child: Container(
              padding: widget.padding,
              decoration: widget.decoration,
              child: widget.child,
            ),
          );
        },
      ),
    );
  }
}

/// 중력 효과 애니메이션
class GravityAnimation extends StatefulWidget {
  final Widget child;
  final double gravity;
  final double bounceFactor;
  final double initialVelocity;

  const GravityAnimation({
    super.key,
    required this.child,
    this.gravity = 9.8,
    this.bounceFactor = 0.8,
    this.initialVelocity = 0,
  });

  @override
  State<GravityAnimation> createState() => _GravityAnimationState();
}

class _GravityAnimationState extends State<GravityAnimation>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  double _position = 0;
  double _velocity = 0;
  final double _floor = 300;

  @override
  void initState() {
    super.initState();
    _velocity = widget.initialVelocity;
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 10),
    )..addListener(_updatePhysics);

    _controller.repeat();
  }

  void _updatePhysics() {
    setState(() {
      // 속도 업데이트 (중력 적용)
      _velocity += widget.gravity * 0.016; // 60fps 가정

      // 위치 업데이트
      _position += _velocity;

      // 바닥 충돌 감지
      if (_position >= _floor) {
        _position = _floor;
        _velocity = -_velocity * widget.bounceFactor;

        // 너무 작은 바운스는 멈춤
        if (_velocity.abs() < 1) {
          _velocity = 0;
        }
      }
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(0, _position),
      child: widget.child,
    );
  }
}

/// 물결 효과 애니메이션
class RippleAnimation extends StatefulWidget {
  final Widget child;
  final Color rippleColor;
  final Duration duration;

  const RippleAnimation({
    super.key,
    required this.child,
    this.rippleColor = Colors.blue,
    this.duration = const Duration(milliseconds: 600),
  });

  @override
  State<RippleAnimation> createState() => _RippleAnimationState();
}

class _RippleAnimationState extends State<RippleAnimation>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: widget.duration,
      vsync: this,
    );

    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeOut,
    ));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _handleTap() {
    _controller.forward(from: 0.0);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Stack(
        alignment: Alignment.center,
        children: [
          AnimatedBuilder(
            animation: _animation,
            builder: (context, child) {
              return Container(
                width: 100 + 200 * _animation.value,
                height: 100 + 200 * _animation.value,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: widget.rippleColor.withValues(
                    alpha: (1 - _animation.value) * 0.3,
                  ),
                ),
              );
            },
          ),
          widget.child,
        ],
      ),
    );
  }
}
