import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gif_view/gif_view.dart';
import 'package:provider/provider.dart';
import 'package:qpay/providers/splash_provider.dart';
import 'package:qpay/routes.dart';
import 'package:url_launcher/url_launcher.dart';

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
    with TickerProviderStateMixin {
  late AnimationController _fadeController;
  late AnimationController _scaleController;
  late Animation<double> _fadeAnimation;
  late Animation<double> _scaleAnimation;

  bool _bottomSheetShown = false;

  @override
  void initState() {
    super.initState();

    // Initialize animation controllers
    _fadeController = AnimationController(
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    );

    _scaleController = AnimationController(
      duration: const Duration(milliseconds: 800),
      vsync: this,
    );

    // Create animations
    _fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _fadeController, curve: Curves.easeInOut),
    );

    _scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
      CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut),
    );

    // Start animations and version check
    _startAnimations();

    // Kick off the version check via the provider (mounted-checked
    // inside a post-frame callback so the widget is in the tree).
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) {
        context.read<SplashProvider>().addListener(_onStatusChanged);
        context.read<SplashProvider>().checkVersion();
      }
    });
  }

  void _onStatusChanged() {
    if (!mounted) return;
    final provider = context.read<SplashProvider>();

    if (provider.status == SplashCheckStatus.updateAvailable) {
      _showUpdateBottomSheet();
    }
    // For noUpdate we do nothing here — the animation will call
    // splashState.finish() when it completes naturally.
  }

  void _startAnimations() async {
    try {
      // Start fade in and scale animations
      _fadeController.forward();
      _scaleController.forward();

      // Let the splash branding play for at least 1.25 s.
      await Future.delayed(const Duration(milliseconds: 1250));

      // Start fade out animation
      await _fadeController.reverse();

      // After the animation completes, release navigation to the
      // originally intended route UNLESS an update is available
      // (in which case the bottom sheet keeps the user on splash).
      if (mounted) {
        final provider = context.read<SplashProvider>();
        if (provider.status != SplashCheckStatus.updateAvailable) {
          splashState.finish();
        }
      }
    } catch (e) {
      // If there's an error, still complete the splash screen
      if (mounted) {
        splashState.finish();
      }
    }
  }

  void _showUpdateBottomSheet() {
    // Prevent showing the sheet more than once.
    if (_bottomSheetShown) return;
    _bottomSheetShown = true;

    final provider = context.read<SplashProvider>();
    final payload = provider.updatePayload;
    final version = payload?['version']?.toString() ?? 'a newer';

    if (kIsWeb) {
      _showWebUpdateSheet(provider, version);
    } else {
      _showMobileUpdateSheet(provider, version);
    }
  }

  /// Web: clear Cloudflare cache, wait 5 s, then hard-refresh the page
  /// so the browser picks up the new deployment.
  void _showWebUpdateSheet(SplashProvider provider, String version) {
    final message =
        'A new version of the app is available. Please refresh to get the latest update.';

    showModalBottomSheet(
      context: context,
      isDismissible: false,
      enableDrag: false,
      backgroundColor: Colors.white,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      builder: (sheetContext) {
        return SafeArea(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                // Icon
                Container(
                  padding: const EdgeInsets.all(16),
                  decoration: BoxDecoration(
                    color: Colors.orange.shade50,
                    shape: BoxShape.circle,
                  ),
                  child: Icon(
                    Icons.system_update_rounded,
                    color: Colors.orange.shade700,
                    size: 40,
                  ),
                ),
                const SizedBox(height: 20),

                // Title
                Text(
                  'Update Available',
                  style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                    fontWeight: FontWeight.w700,
                  ),
                ),
                const SizedBox(height: 12),

                // Message
                Consumer<SplashProvider>(
                  builder: (context, splashProvider, _) {
                    final statusText = splashProvider.isRefreshing
                        ? 'Clearing cache and preparing the latest version. '
                              'This may take a few seconds...'
                        : message;
                    return Text(
                      statusText,
                      textAlign: TextAlign.center,
                      style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                        color: Colors.grey.shade600,
                      ),
                    );
                  },
                ),
                const SizedBox(height: 28),

                // Refresh button
                Consumer<SplashProvider>(
                  builder: (context, splashProvider, _) {
                    final refreshing = splashProvider.isRefreshing;
                    return SizedBox(
                      width: double.infinity,
                      child: ElevatedButton(
                        onPressed: refreshing
                            ? null
                            : () {
                                splashProvider.clearCacheAndRefresh();
                              },
                        style: ElevatedButton.styleFrom(
                          backgroundColor: Colors.orange.shade700,
                          foregroundColor: Colors.white,
                          disabledBackgroundColor: Colors.orange.shade400,
                          disabledForegroundColor: Colors.white70,
                          padding: const EdgeInsets.symmetric(vertical: 16),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(12),
                          ),
                        ),
                        child: refreshing
                            ? const Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  SizedBox(
                                    width: 20,
                                    height: 20,
                                    child: CircularProgressIndicator(
                                      strokeWidth: 2,
                                      valueColor: AlwaysStoppedAnimation<Color>(
                                        Colors.white,
                                      ),
                                    ),
                                  ),
                                  SizedBox(width: 12),
                                  Text(
                                    'Refreshing...',
                                    style: TextStyle(
                                      fontSize: 16,
                                      fontWeight: FontWeight.w600,
                                    ),
                                  ),
                                ],
                              )
                            : const Text(
                                'Refresh to Update',
                                style: TextStyle(
                                  fontSize: 16,
                                  fontWeight: FontWeight.w600,
                                ),
                              ),
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  /// Mobile (Android / iOS): open the app store / download URL so the
  /// user can install the latest version. No cache clearing needed.
  void _showMobileUpdateSheet(SplashProvider provider, String version) {
    final message =
        provider.updatePayload?['message']?.toString() ??
        'A new version of the app is available. Please download the latest version from the store.';
    final downloadUrl = provider.downloadUrl;

    showModalBottomSheet(
      context: context,
      isDismissible: false,
      enableDrag: false,
      backgroundColor: Colors.white,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
      ),
      builder: (sheetContext) {
        return SafeArea(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                // Icon
                Container(
                  padding: const EdgeInsets.all(16),
                  decoration: BoxDecoration(
                    color: Colors.orange.shade50,
                    shape: BoxShape.circle,
                  ),
                  child: Icon(
                    Icons.system_update_rounded,
                    color: Colors.orange.shade700,
                    size: 40,
                  ),
                ),
                const SizedBox(height: 20),

                // Title
                Text(
                  'Update Available',
                  style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                    fontWeight: FontWeight.w700,
                  ),
                ),
                const SizedBox(height: 12),

                // Message
                Text(
                  'Version $version is now available. $message',
                  textAlign: TextAlign.center,
                  style: Theme.of(
                    context,
                  ).textTheme.bodyMedium?.copyWith(color: Colors.grey.shade600),
                ),
                const SizedBox(height: 28),

                // Download button
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: () {
                      if (downloadUrl != null && downloadUrl.isNotEmpty) {
                        launchUrl(
                          Uri.parse(downloadUrl),
                          mode: LaunchMode.externalApplication,
                        );
                      }
                    },
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.orange.shade700,
                      foregroundColor: Colors.white,
                      padding: const EdgeInsets.symmetric(vertical: 16),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(12),
                      ),
                    ),
                    child: const Text(
                      'Download Update',
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  @override
  void dispose() {
    try {
      context.read<SplashProvider>().removeListener(_onStatusChanged);
    } catch (_) {}
    _fadeController.dispose();
    _scaleController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: AnimatedBuilder(
        animation: Listenable.merge([_fadeController, _scaleController]),
        builder: (context, child) {
          return FadeTransition(
            opacity: _fadeAnimation,
            child: ScaleTransition(
              scale: _scaleAnimation,
              child: Center(
                child: SizedBox(
                  width: 200,
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(20),
                    child: GifView.asset(
                      'assets/velocity-animation.gif',
                      width: MediaQuery.of(context).size.width,
                      height: MediaQuery.of(context).size.height,
                      frameRate: 30,
                      fit: BoxFit.contain,
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
