import 'package:flutter/material.dart'; import '../../utils/colors.dart'; import '../../utils/haptic_utils.dart'; import '../../utils/settings_manager.dart'; import '../../l10n/app_localizations.dart'; class TutorialOverlay extends StatefulWidget { final VoidCallback onComplete; const TutorialOverlay({super.key, required this.onComplete}); @override State createState() => _TutorialOverlayState(); } class _TutorialOverlayState extends State with TickerProviderStateMixin { late AnimationController _pulseController; late AnimationController _fadeController; late Animation _pulseAnimation; late Animation _fadeAnimation; int _currentStep = 0; final int _totalSteps = 3; @override void initState() { super.initState(); _pulseController = AnimationController( duration: const Duration(milliseconds: 1500), vsync: this, )..repeat(reverse: true); _fadeController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); _pulseAnimation = Tween(begin: 0.8, end: 1.2).animate( CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut), ); _fadeAnimation = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut), ); _fadeController.forward(); } @override void dispose() { _pulseController.dispose(); _fadeController.dispose(); super.dispose(); } List _getSteps(BuildContext context) { final l10n = AppLocalizations.of(context)!; return [ TutorialStep( title: l10n.tutorialWelcomeTitle, description: l10n.tutorialWelcomeDescription, icon: Icons.touch_app, position: TutorialPosition.center, ), TutorialStep( title: l10n.tutorialRelaxationTitle, description: l10n.tutorialRelaxationDescription, icon: Icons.stars, position: TutorialPosition.center, ), TutorialStep( title: l10n.tutorialZenTitle, description: l10n.tutorialZenDescription, icon: Icons.self_improvement, position: TutorialPosition.center, ), ]; } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final steps = _getSteps(context); final step = steps[_currentStep]; return FadeTransition( opacity: _fadeAnimation, child: Container( color: ZenColors.black.withValues(alpha: 0.85), child: SafeArea( child: Stack( children: [ // Tutorial content Positioned.fill( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Animated icon AnimatedBuilder( animation: _pulseAnimation, builder: (context, child) { return Transform.scale( scale: _pulseAnimation.value, child: Container( padding: const EdgeInsets.all(30), decoration: BoxDecoration( shape: BoxShape.circle, color: ZenColors.buttonBackground.withValues( alpha: 0.2, ), border: Border.all( color: ZenColors.buttonBackground, width: 2, ), ), child: Icon( step.icon, size: 60, color: ZenColors.buttonBackground, ), ), ); }, ), const SizedBox(height: 40), // Title Padding( padding: const EdgeInsets.symmetric(horizontal: 40), child: Text( step.title, style: const TextStyle( color: ZenColors.primaryText, fontSize: 28, fontWeight: FontWeight.bold, letterSpacing: 0.5, ), textAlign: TextAlign.center, ), ), const SizedBox(height: 20), // Description Padding( padding: const EdgeInsets.symmetric(horizontal: 40), child: Text( step.description, style: TextStyle( color: ZenColors.secondaryText, fontSize: 16, height: 1.5, ), textAlign: TextAlign.center, ), ), const SizedBox(height: 60), // Progress indicator Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(_totalSteps, (index) { return Container( margin: const EdgeInsets.symmetric(horizontal: 4), width: 12, height: 12, decoration: BoxDecoration( shape: BoxShape.circle, color: index <= _currentStep ? ZenColors.buttonBackground : ZenColors.mutedText.withValues( alpha: 0.3, ), ), ); }), ), const SizedBox(height: 40), // Action buttons Padding( padding: const EdgeInsets.symmetric(horizontal: 40), child: Row( children: [ if (_currentStep > 0) Expanded( child: OutlinedButton( onPressed: _previousStep, style: OutlinedButton.styleFrom( foregroundColor: ZenColors.primaryText, side: const BorderSide( color: ZenColors.mutedText, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.symmetric( vertical: 16, ), ), child: Text( l10n.previous, style: const TextStyle(fontSize: 16), ), ), ), if (_currentStep > 0) const SizedBox(width: 16), Expanded( flex: 2, child: ElevatedButton( onPressed: _nextStep, style: ElevatedButton.styleFrom( backgroundColor: ZenColors.buttonBackground, foregroundColor: ZenColors.buttonText, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.symmetric( vertical: 16, ), elevation: 4, ), child: Text( _currentStep == _totalSteps - 1 ? l10n.startRelaxing : l10n.continueButton, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ), ], ), ), ], ), ), // Skip button Positioned( top: 20, right: 20, child: TextButton( onPressed: _skipTutorial, style: TextButton.styleFrom( foregroundColor: ZenColors.mutedText, ), child: Text(l10n.skip, style: const TextStyle(fontSize: 16)), ), ), ], ), ), ), ); } void _nextStep() async { if (SettingsManager.isHapticsEnabled) { await HapticUtils.vibrate(duration: 50); } if (_currentStep < _totalSteps - 1) { setState(() { _currentStep++; }); } else { await _completeTutorial(); } } void _previousStep() async { if (SettingsManager.isHapticsEnabled) { await HapticUtils.vibrate(duration: 50); } if (_currentStep > 0) { setState(() { _currentStep--; }); } } void _skipTutorial() async { if (SettingsManager.isHapticsEnabled) { await HapticUtils.vibrate(duration: 50); } await _completeTutorial(); } Future _completeTutorial() async { await SettingsManager.setTutorialShown(true); await _fadeController.reverse(); widget.onComplete(); } } class TutorialStep { final String title; final String description; final IconData icon; final TutorialPosition position; TutorialStep({ required this.title, required this.description, required this.icon, required this.position, }); } enum TutorialPosition { center, top, bottom }