import { useEffect, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { 
  subscribeToAuthState, 
  refreshUserToken, 
  stopTokenRefreshTimer 
} from '../services/authService';
import { checkAuthStatus, logoutUser } from '../features/auth/authSlice';
import type { RootState, AppDispatch } from '../store/store';

/**
 * Custom hook for managing session persistence and token refresh
 * 
 * Responsibilities:
 * 1. Initialize auth state on app load and restore persisted sessions
 * 2. Manage automatic token refresh to prevent session expiry
 * 3. Detect and handle token expiration
 * 4. Set up activity monitoring (optional, can extend for activity-based timeouts)
 * 
 * Usage: Call this hook in AppLayout or a root component that wraps authenticated routes
 */
export const useSessionPersistence = () => {
  const dispatch = useDispatch<AppDispatch>();
  const navigate = useNavigate();
  const { isAuthenticated, user } = useSelector((state: RootState) => state.auth);

  /**
   * Handle token expiration by logging out user and redirecting to login
   */
  const handleTokenExpiration = useCallback(async () => {
    console.warn('Token expired, logging out user');
    await dispatch(logoutUser());
    navigate('/login', { replace: true, state: { message: 'Your session has expired. Please log in again.' } });
  }, [dispatch, navigate]);

  /**
   * Initialize session on component mount
   * Restores persisted session from Firebase and sets up auth listeners
   */
  useEffect(() => {
    let unsubscribe: (() => void) | null = null;

    const initializeSession = async () => {
      try {
        // Check if user is already logged in (from Firebase persistence)
        await dispatch(checkAuthStatus());

        // Set up real-time auth state listener
        unsubscribe = subscribeToAuthState(async (firebaseUser) => {
          if (firebaseUser) {
            // User is authenticated - token refresh is started by subscribeToAuthState
            console.log('User session restored:', firebaseUser.email);
          } else {
            // User is not authenticated
            stopTokenRefreshTimer();
          }
        });
      } catch (error) {
        console.error('Error initializing session:', error);
      }
    };

    initializeSession();

    // Cleanup on unmount
    return () => {
      if (unsubscribe) {
        unsubscribe();
      }
      stopTokenRefreshTimer();
    };
  }, [dispatch]);

  /**
   * Monitor token validity and handle expiration
   * Periodically checks if token is still valid
   */
  useEffect(() => {
    if (!isAuthenticated || !user) return;

    // Set up interval to check token validity every 5 minutes
    const tokenCheckInterval = window.setInterval(async () => {
      try {
        // Attempt to get fresh token - this will throw if token is invalid/expired
        const success = await refreshUserToken();
        
        if (!success) {
          // Token refresh failed
          handleTokenExpiration();
        }
      } catch (error) {
        console.error('Token validation failed:', error);
        handleTokenExpiration();
      }
    }, 5 * 60 * 1000); // Check every 5 minutes

    // Cleanup interval
    return () => clearInterval(tokenCheckInterval);
  }, [isAuthenticated, user, handleTokenExpiration]);

  /**
   * Update last activity timestamp on user interaction
   * This can be used to implement idle timeout if needed in the future
   */
  useEffect(() => {
    if (!isAuthenticated) return;

    const updateActivity = () => {
      localStorage.setItem('lastActivityTime', Date.now().toString());
    };

    // Track user activity
    const events = ['mousedown', 'keydown', 'scroll', 'touchstart', 'click'];
    
    events.forEach(event => {
      window.addEventListener(event, updateActivity);
    });

    // Cleanup event listeners
    return () => {
      events.forEach(event => {
        window.removeEventListener(event, updateActivity);
      });
    };
  }, [isAuthenticated]);
};
