import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:tugas_akhir_supabase/services/session_manager.dart';
import 'package:tugas_akhir_supabase/widgets/session_expired_dialog.dart';

/// A widget that enforces session validation for authenticated routes.
/// 
/// This widget should wrap any screen that requires authentication.
/// It will automatically check if the session is valid and redirect to login
/// if the session has expired.
class SessionGuardWrapper extends StatefulWidget {
  final Widget child;
  final bool enforceAuthentication;

  const SessionGuardWrapper({
    Key? key,
    required this.child,
    this.enforceAuthentication = true,
  }) : super(key: key);

  @override
  State<SessionGuardWrapper> createState() => _SessionGuardWrapperState();
}

class _SessionGuardWrapperState extends State<SessionGuardWrapper> {
  bool _isCheckingSession = false;
  bool _sessionExpired = false;
  bool _showingDialog = false;

  @override
  void initState() {
    super.initState();
    
    // Check session on widget initialization
    if (widget.enforceAuthentication) {
      _checkSession();
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    
    // Check session when dependencies change (e.g., after navigation)
    if (widget.enforceAuthentication && !_isCheckingSession) {
      _checkSession();
    }
  }

  Future<void> _checkSession() async {
    // Skip check if not enforcing authentication
    if (!widget.enforceAuthentication) return;
    
    // Skip check if already checking
    if (_isCheckingSession) return;
    
    // Skip check if no user is logged in
    final currentUser = Supabase.instance.client.auth.currentUser;
    if (currentUser == null) return;
    
    _isCheckingSession = true;
    
    try {
      // Check if session is already marked as expired
      if (SessionManager.isExpired) {
        if (mounted && !_sessionExpired) {
          setState(() {
            _sessionExpired = true;
          });
          _showExpiredDialog();
        }
        _isCheckingSession = false;
        return;
      }
      
      // Check session validity
      final isValid = await SessionManager.isSessionValid();
      
      if (mounted && !isValid && !_sessionExpired) {
        setState(() {
          _sessionExpired = true;
        });
        _showExpiredDialog();
      }
    } catch (e) {
      debugPrint('SessionGuard: Error checking session - $e');
    } finally {
      _isCheckingSession = false;
    }
  }
  
  void _showExpiredDialog() {
    if (_showingDialog) return;
    
    _showingDialog = true;
    
    // Show dialog on next frame to avoid build phase issues
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) {
        _showingDialog = false;
        return;
      }
      
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => const SessionExpiredDialog(),
      ).then((_) {
        _showingDialog = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    // If not enforcing authentication, just show the child
    if (!widget.enforceAuthentication) {
      return widget.child;
    }
    
    // If session is expired, show a restricted UI
    if (_sessionExpired) {
      return Material(
        child: Stack(
          children: [
            // Blur the background content
            Opacity(
              opacity: 0.3,
              child: AbsorbPointer(
                child: widget.child,
              ),
            ),
            // Show a loading indicator if dialog is not showing yet
            if (!_showingDialog)
              const Center(
                child: CircularProgressIndicator(),
              ),
          ],
        ),
      );
    }
    
    // Session is valid, show the child with a gesture detector to update activity
    return GestureDetector(
      onTap: () => SessionManager.updateLastUserInteraction(),
      onPanDown: (_) => SessionManager.updateLastUserInteraction(),
      behavior: HitTestBehavior.translucent,
      child: widget.child,
    );
  }
} 