/// Page d'Authentification UnionFlow
///
/// Interface utilisateur pour la connexion sécurisée
/// avec gestion complète des états et des erreurs.
library keycloak_webview_auth_page;

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../../data/datasources/keycloak_webview_auth_service.dart';
import '../../data/models/user.dart';
import '../../../../shared/design_system/tokens/color_tokens.dart';
import '../../../../shared/design_system/tokens/spacing_tokens.dart';
import '../../../../shared/design_system/tokens/typography_tokens.dart';

/// États de l'authentification WebView
enum KeycloakWebViewAuthState {
  /// Initialisation en cours
  initializing,
  /// Chargement de la page d'authentification
  loading,
  /// Page d'authentification affichée
  ready,
  /// Authentification en cours
  authenticating,
  /// Authentification réussie
  success,
  /// Erreur d'authentification
  error,
  /// Timeout
  timeout,
}

/// Page d'authentification Keycloak avec WebView
class KeycloakWebViewAuthPage extends StatefulWidget {
  /// Callback appelé en cas de succès d'authentification
  final Function(User user) onAuthSuccess;
  
  /// Callback appelé en cas d'erreur
  final Function(String error) onAuthError;
  
  /// Callback appelé en cas d'annulation
  final VoidCallback? onAuthCancel;
  
  /// Timeout pour l'authentification (en secondes)
  final int timeoutSeconds;
  
  const KeycloakWebViewAuthPage({
    super.key,
    required this.onAuthSuccess,
    required this.onAuthError,
    this.onAuthCancel,
    this.timeoutSeconds = 300, // 5 minutes par défaut
  });

  @override
  State<KeycloakWebViewAuthPage> createState() => _KeycloakWebViewAuthPageState();
}

class _KeycloakWebViewAuthPageState extends State<KeycloakWebViewAuthPage>
    with TickerProviderStateMixin {
  
  // Contrôleurs et état
  late WebViewController _webViewController;
  late AnimationController _progressAnimationController;
  late Animation<double> _progressAnimation;
  Timer? _timeoutTimer;
  
  // État de l'authentification
  KeycloakWebViewAuthState _authState = KeycloakWebViewAuthState.initializing;
  String? _errorMessage;
  double _loadingProgress = 0.0;



  // Paramètres d'authentification
  String? _authUrl;

  @override
  void initState() {
    super.initState();
    _initializeAnimations();
    _initializeAuthentication();
  }

  @override
  void dispose() {
    _progressAnimationController.dispose();
    _timeoutTimer?.cancel();
    super.dispose();
  }

  /// Initialise les animations
  void _initializeAnimations() {
    _progressAnimationController = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    
    _progressAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _progressAnimationController,
      curve: Curves.easeInOut,
    ));
  }

  /// Initialise l'authentification
  Future<void> _initializeAuthentication() async {
    try {
      debugPrint('🚀 Initialisation de l\'authentification WebView...');
      
      setState(() {
        _authState = KeycloakWebViewAuthState.initializing;
      });
      
      // Préparer l'authentification
      final Map<String, String> authParams = 
          await KeycloakWebViewAuthService.prepareAuthentication();
      
      _authUrl = authParams['url'];
      
      if (_authUrl == null) {
        throw Exception('URL d\'authentification manquante');
      }
      
      // Initialiser la WebView
      await _initializeWebView();
      
      // Démarrer le timer de timeout
      _startTimeoutTimer();
      
      debugPrint('✅ Authentification initialisée avec succès');
      
    } catch (e) {
      debugPrint('💥 Erreur initialisation authentification: $e');
      _handleError('Erreur d\'initialisation: $e');
    }
  }

  /// Initialise la WebView
  Future<void> _initializeWebView() async {
    _webViewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(ColorTokens.surface)
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: _onLoadingProgress,
          onPageStarted: _onPageStarted,
          onPageFinished: _onPageFinished,
          onWebResourceError: _onWebResourceError,
          onNavigationRequest: _onNavigationRequest,
        ),
      );
    
    // Charger l'URL d'authentification
    if (_authUrl != null) {
      await _webViewController.loadRequest(Uri.parse(_authUrl!));
      
      setState(() {
        _authState = KeycloakWebViewAuthState.loading;
      });
    }
  }

  /// Démarre le timer de timeout
  void _startTimeoutTimer() {
    _timeoutTimer = Timer(Duration(seconds: widget.timeoutSeconds), () {
      if (_authState != KeycloakWebViewAuthState.success) {
        debugPrint('⏰ Timeout d\'authentification atteint');
        _handleTimeout();
      }
    });
  }

  /// Gère la progression du chargement
  void _onLoadingProgress(int progress) {
    setState(() {
      _loadingProgress = progress / 100.0;
    });
    
    if (progress == 100) {
      _progressAnimationController.forward();
    }
  }

  /// Gère le début du chargement d'une page
  void _onPageStarted(String url) {
    debugPrint('📄 Chargement de la page: $url');
    
    setState(() {
      _loadingProgress = 0.0;
    });
    
    _progressAnimationController.reset();
  }

  /// Gère la fin du chargement d'une page
  void _onPageFinished(String url) {
    debugPrint('✅ Page chargée: $url');
    
    setState(() {
      if (_authState == KeycloakWebViewAuthState.loading) {
        _authState = KeycloakWebViewAuthState.ready;
      }
    });
  }

  /// Gère les erreurs de ressources web
  void _onWebResourceError(WebResourceError error) {
    debugPrint('💥 Erreur WebView: ${error.description}');
    
    // Ignorer certaines erreurs non critiques
    if (error.errorCode == -999) { // Code d'erreur pour annulation
      return;
    }
    
    _handleError('Erreur de chargement: ${error.description}');
  }

  /// Gère les requêtes de navigation
  NavigationDecision _onNavigationRequest(NavigationRequest request) {
    final String url = request.url;
    debugPrint('🔗 Navigation vers: $url');

    // Vérifier si c'est notre URL de callback
    if (url.startsWith('dev.lions.unionflow-mobile://auth/callback')) {
      debugPrint('🎯 URL de callback détectée: $url');
      _handleAuthCallback(url);
      return NavigationDecision.prevent;
    }

    // Vérifier d'autres patterns de callback possibles
    if (url.contains('code=') && url.contains('state=')) {
      debugPrint('🎯 Callback potentiel détecté (avec code et state): $url');
      _handleAuthCallback(url);
      return NavigationDecision.prevent;
    }

    return NavigationDecision.navigate;
  }

  /// Traite le callback d'authentification
  Future<void> _handleAuthCallback(String callbackUrl) async {
    try {
      setState(() {
        _authState = KeycloakWebViewAuthState.authenticating;
      });

      debugPrint('🔄 Traitement du callback d\'authentification...');
      debugPrint('📋 URL de callback reçue: $callbackUrl');

      // Traiter le callback via le service
      final User user = await KeycloakWebViewAuthService.handleAuthCallback(callbackUrl);

      setState(() {
        _authState = KeycloakWebViewAuthState.success;
      });

      // Annuler le timer de timeout
      _timeoutTimer?.cancel();

      debugPrint('🎉 Authentification réussie pour: ${user.fullName}');
      debugPrint('👤 Rôle: ${user.primaryRole.displayName}');
      debugPrint('🔐 Permissions: ${user.additionalPermissions.length}');

      // Notifier le succès avec un délai pour l'animation
      Future.delayed(const Duration(milliseconds: 500), () {
        widget.onAuthSuccess(user);
      });

    } catch (e, stackTrace) {
      debugPrint('💥 Erreur traitement callback: $e');
      debugPrint('📋 Stack trace: $stackTrace');

      // Essayer de donner plus d'informations sur l'erreur
      String errorMessage = 'Erreur d\'authentification: $e';
      if (e.toString().contains('MISSING_AUTH_STATE')) {
        errorMessage = 'Session expirée. Veuillez réessayer.';
      } else if (e.toString().contains('INVALID_STATE')) {
        errorMessage = 'Erreur de sécurité. Veuillez réessayer.';
      } else if (e.toString().contains('MISSING_AUTH_CODE')) {
        errorMessage = 'Code d\'autorisation manquant. Veuillez réessayer.';
      }

      _handleError(errorMessage);
    }
  }

  /// Gère les erreurs
  void _handleError(String error) {
    setState(() {
      _authState = KeycloakWebViewAuthState.error;
      _errorMessage = error;
    });
    
    _timeoutTimer?.cancel();
    
    // Vibration pour indiquer l'erreur
    HapticFeedback.lightImpact();
    
    widget.onAuthError(error);
  }

  /// Gère le timeout
  void _handleTimeout() {
    setState(() {
      _authState = KeycloakWebViewAuthState.timeout;
      _errorMessage = 'Timeout d\'authentification atteint';
    });
    
    HapticFeedback.lightImpact();
    
    widget.onAuthError('Timeout d\'authentification');
  }

  /// Gère l'annulation
  void _handleCancel() {
    debugPrint('❌ Authentification annulée par l\'utilisateur');

    _timeoutTimer?.cancel();

    if (widget.onAuthCancel != null) {
      widget.onAuthCancel!();
    } else {
      Navigator.of(context).pop();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: ColorTokens.surface,
      appBar: _buildAppBar(),
      body: _buildBody(),
    );
  }

  /// Construit l'AppBar
  PreferredSizeWidget _buildAppBar() {
    return AppBar(
      backgroundColor: ColorTokens.primary,
      foregroundColor: ColorTokens.onPrimary,
      elevation: 0,
      title: Text(
        'Connexion Sécurisée',
        style: TypographyTokens.headlineSmall.copyWith(
          color: ColorTokens.onPrimary,
          fontWeight: FontWeight.w600,
        ),
      ),
      leading: IconButton(
        icon: const Icon(Icons.close),
        onPressed: _handleCancel,
        tooltip: 'Annuler',
      ),
      actions: [
        if (_authState == KeycloakWebViewAuthState.ready)
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () => _webViewController.reload(),
            tooltip: 'Actualiser',
          ),
      ],
      bottom: _buildProgressIndicator(),
    );
  }

  /// Construit l'indicateur de progression
  PreferredSizeWidget? _buildProgressIndicator() {
    if (_authState == KeycloakWebViewAuthState.loading ||
        _authState == KeycloakWebViewAuthState.authenticating) {
      return PreferredSize(
        preferredSize: const Size.fromHeight(4.0),
        child: AnimatedBuilder(
          animation: _progressAnimation,
          builder: (context, child) {
            return LinearProgressIndicator(
              value: _authState == KeycloakWebViewAuthState.authenticating
                  ? null
                  : _loadingProgress,
              backgroundColor: ColorTokens.onPrimary.withOpacity(0.3),
              valueColor: const AlwaysStoppedAnimation<Color>(ColorTokens.onPrimary),
            );
          },
        ),
      );
    }
    return null;
  }

  /// Construit le corps de la page
  Widget _buildBody() {
    switch (_authState) {
      case KeycloakWebViewAuthState.initializing:
        return _buildInitializingView();

      case KeycloakWebViewAuthState.loading:
      case KeycloakWebViewAuthState.ready:
        return _buildWebView();

      case KeycloakWebViewAuthState.authenticating:
        return _buildAuthenticatingView();

      case KeycloakWebViewAuthState.success:
        return _buildSuccessView();

      case KeycloakWebViewAuthState.error:
      case KeycloakWebViewAuthState.timeout:
        return _buildErrorView();
    }
  }

  /// Vue d'initialisation
  Widget _buildInitializingView() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const CircularProgressIndicator(),
          const SizedBox(height: SpacingTokens.xl),
          Text(
            'Initialisation...',
            style: TypographyTokens.bodyLarge.copyWith(
              color: ColorTokens.onSurface,
            ),
          ),
        ],
      ),
    );
  }

  /// Vue WebView
  Widget _buildWebView() {
    return WebViewWidget(controller: _webViewController);
  }

  /// Vue d'authentification en cours
  Widget _buildAuthenticatingView() {
    return Container(
      color: ColorTokens.surface,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const CircularProgressIndicator(),
            const SizedBox(height: SpacingTokens.xxxl),
            Text(
              'Connexion en cours...',
              style: TypographyTokens.headlineSmall.copyWith(
                color: ColorTokens.onSurface,
                fontWeight: FontWeight.w600,
              ),
            ),
            const SizedBox(height: SpacingTokens.xl),
            Text(
              'Veuillez patienter pendant que nous\nvérifions vos informations.',
              textAlign: TextAlign.center,
              style: TypographyTokens.bodyMedium.copyWith(
                color: ColorTokens.onSurface.withOpacity(0.7),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Vue de succès
  Widget _buildSuccessView() {
    return Container(
      color: ColorTokens.surface,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              width: 80,
              height: 80,
              decoration: const BoxDecoration(
                color: Colors.green,
                shape: BoxShape.circle,
              ),
              child: const Icon(
                Icons.check,
                color: Colors.white,
                size: 48,
              ),
            ),
            const SizedBox(height: SpacingTokens.xxxl),
            Text(
              'Connexion réussie !',
              style: TypographyTokens.headlineSmall.copyWith(
                color: ColorTokens.onSurface,
                fontWeight: FontWeight.w600,
              ),
            ),
            const SizedBox(height: SpacingTokens.xl),
            Text(
              'Redirection vers l\'application...',
              style: TypographyTokens.bodyMedium.copyWith(
                color: ColorTokens.onSurface.withOpacity(0.7),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Vue d'erreur
  Widget _buildErrorView() {
    return Container(
      color: ColorTokens.surface,
      padding: const EdgeInsets.all(SpacingTokens.xxxl),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              width: 80,
              height: 80,
              decoration: const BoxDecoration(
                color: ColorTokens.error,
                shape: BoxShape.circle,
              ),
              child: Icon(
                _authState == KeycloakWebViewAuthState.timeout
                    ? Icons.access_time
                    : Icons.error_outline,
                color: ColorTokens.onError,
                size: 48,
              ),
            ),
            const SizedBox(height: SpacingTokens.xxxl),
            Text(
              _authState == KeycloakWebViewAuthState.timeout
                  ? 'Délai d\'attente dépassé'
                  : 'Erreur de connexion',
              style: TypographyTokens.headlineSmall.copyWith(
                color: ColorTokens.onSurface,
                fontWeight: FontWeight.w600,
              ),
            ),
            const SizedBox(height: SpacingTokens.xl),
            Text(
              _errorMessage ?? 'Une erreur inattendue s\'est produite',
              textAlign: TextAlign.center,
              style: TypographyTokens.bodyMedium.copyWith(
                color: ColorTokens.onSurface.withOpacity(0.7),
              ),
            ),
            const SizedBox(height: SpacingTokens.huge),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton.icon(
                  onPressed: _initializeAuthentication,
                  icon: const Icon(Icons.refresh),
                  label: const Text('Réessayer'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: ColorTokens.primary,
                    foregroundColor: ColorTokens.onPrimary,
                  ),
                ),
                OutlinedButton.icon(
                  onPressed: _handleCancel,
                  icon: const Icon(Icons.close),
                  label: const Text('Annuler'),
                  style: OutlinedButton.styleFrom(
                    foregroundColor: ColorTokens.onSurface,
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
