import {
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
  setPersistence,
  browserLocalPersistence,
  sendPasswordResetEmail,
  confirmPasswordReset,
} from "firebase/auth";
import type { User, AuthError } from "firebase/auth";
import { app} from "../features/auth/firebase"
import { getAuth } from "firebase/auth";

const auth = getAuth(app);

// Token refresh interval tracking
let tokenRefreshInterval: number | null = null;

// Constants for session management
const TOKEN_REFRESH_INTERVAL = 40 * 60 * 1000; // Refresh token every 40 minutes (Firebase ID tokens expire in 1 hour)

/**
 * Initialize Firebase Auth persistence
 * Ensures user session persists across page refreshes
 */
export const initializeAuthPersistence = async () => {
  try {
    await setPersistence(auth, browserLocalPersistence);
    console.log("Auth persistence initialized with localStorage");
  } catch (error) {
    console.error("Error setting auth persistence:", error);
  }
};

/**
 * Refresh the current user's ID token to maintain session validity
 * Firebase automatically refreshes tokens, but we can force a refresh to ensure validity
 * @returns Promise<boolean> - true if refresh successful, false otherwise
 */
export const refreshUserToken = async (): Promise<boolean> => {
  try {
    const currentUser = auth.currentUser;
    if (currentUser) {
      await currentUser.getIdTokenResult(true); // Force refresh
      console.log("Token refreshed successfully");
      return true;
    }
    return false;
  } catch (error) {
    console.error("Error refreshing token:", error);
    return false;
  }
};

/**
 * Start automatic token refresh mechanism
 * Refreshes token periodically to prevent unexpected logouts
 */
export const startTokenRefreshTimer = () => {
  // Clear any existing interval
  if (tokenRefreshInterval) {
    clearInterval(tokenRefreshInterval);
  }

  // Set up auto-refresh interval
  tokenRefreshInterval = window.setInterval(async () => {
    const currentUser = auth.currentUser;
    if (currentUser) {
      await refreshUserToken();
    } else {
      // If no user, stop the refresh timer
      stopTokenRefreshTimer();
    }
  }, TOKEN_REFRESH_INTERVAL);
};

/**
 * Stop the automatic token refresh timer
 */
export const stopTokenRefreshTimer = () => {
  if (tokenRefreshInterval) {
    clearInterval(tokenRefreshInterval);
    tokenRefreshInterval = null;
  }
};

/**
 * Login user with email and password
 */
export const loginWithEmail = async (email: string, password: string) => {
  try {
    const userCredential = await signInWithEmailAndPassword(auth, email, password);
    return {
      success: true,
      user: userCredential.user,
      error: null,
    };
  } catch (error) {
    const authError = error as AuthError;
    return {
      success: false,
      user: null,
      error: getAuthErrorMessage(authError.code),
    };
  }
};

/**
 * Sign out the current user
 * Clears session data, local storage, and stops token refresh
 */
export const logout = async () => {
  try {
    // Stop token refresh interval
    stopTokenRefreshTimer();

    // Clear any session-related data from localStorage
    localStorage.removeItem('lastActivityTime');
    localStorage.removeItem('sessionStartTime');
    
    // Sign out from Firebase
    await signOut(auth);

    // Clear any other app-specific session data if needed
    sessionStorage.clear();
    
    console.log("User logged out successfully");
    return { success: true };
  } catch (error) {
    console.error("Error during logout:", error);
    return { success: false, error: (error as Error).message };
  }
};

/**
 * Send password reset email
 */
export const sendPasswordReset = async (email: string) => {
  try {
    await sendPasswordResetEmail(auth, email);
    return { success: true };
  } catch (error) {
    const authError = error as AuthError;
    return { success: false, error: getAuthErrorMessage(authError.code) };
  }
};

/**
 * Reset password with code and new password
 * Used after user clicks the link in the reset email
 */
export const resetPassword = async (code: string, newPassword: string) => {
  try {
    await confirmPasswordReset(auth, code, newPassword);
    return { success: true };
  } catch (error) {
    const authError = error as AuthError;
    return { success: false, error: getAuthErrorMessage(authError.code) };
  }
};

/**
 * Subscribe to auth state changes
 * Sets up token refresh timer when user logs in, stops it when logs out
 * Returns unsubscribe function
 */
export const subscribeToAuthState = (callback: (user: User | null) => void) => {
  return onAuthStateChanged(auth, (user) => {
    if (user) {
      // User logged in - start token refresh
      startTokenRefreshTimer();
      // Update last activity time
      localStorage.setItem('lastActivityTime', Date.now().toString());
      localStorage.setItem('sessionStartTime', Date.now().toString());
    } else {
      // User logged out - stop token refresh
      stopTokenRefreshTimer();
    }
    callback(user);
  });
};

/**
 * Get current user synchronously
 */
export const getCurrentUser = () => {
  return auth.currentUser;
};

/**
 * Convert Firebase error codes to user-friendly messages
 */
const getAuthErrorMessage = (errorCode: string): string => {
  const errorMessages: Record<string, string> = {
    "auth/invalid-email": "Invalid email address format.",
    "auth/user-disabled": "This user account has been disabled.",
    "auth/user-not-found": "No account found with this email address.",
    "auth/wrong-password": "Invalid email or password.",
    "auth/invalid-credential": "Invalid email or password.",
    "auth/too-many-requests": "Too many login attempts. Please try again later.",
    "auth/operation-not-allowed": "Login is currently disabled. Please try again later.",
    "auth/network-request-failed": "Network error. Please check your connection.",
    "auth/invalid-action-code": "This password reset link is invalid or has expired.",
    "auth/expired-action-code": "This password reset link has expired. Please request a new one.",
    "auth/weak-password": "Password is too weak. Please choose a stronger password.",
  };

  return errorMessages[errorCode] || "An error occurred. Please try again.";
};
export { app };

