import { useCallback } from 'react';
import { usePersSDK } from '../providers/PersSDKProvider';
import { AccountOwnerType } from '@explorins/pers-sdk/core';
/**
 * React hook for authentication operations in the PERS SDK
 *
 * Provides methods for user login, logout, token management, and authentication state.
 * Automatically manages authentication state and user data synchronization.
 *
 * @returns Authentication hook with methods and state
 *
 * @example
 * ```typescript
 * function LoginComponent() {
 *   const { login, logout, isAuthenticated, user } = useAuth();
 *
 *   const handleLogin = async (token: string) => {
 *     try {
 *       await login(token, 'user');
 *       console.log('Login successful');
 *     } catch (error) {
 *       console.error('Login failed:', error);
 *     }
 *   };
 *
 *   return (
 *     <div>
 *       {isAuthenticated ? (
 *         <div>
 *           <p>Welcome, {user?.name}</p>
 *           <button onClick={logout}>Logout</button>
 *         </div>
 *       ) : (
 *         <button onClick={() => handleLogin('jwt-token')}>Login</button>
 *       )}
 *     </div>
 *   );
 * }
 * ```
 */
export const useAuth = () => {
    const { sdk, authProvider, isInitialized, isAuthenticated, user, refreshUserData } = usePersSDK();
    /**
     * Authenticates a user with a JWT token
     *
     * @param jwtToken - The JWT token to authenticate with
     * @param userType - The type of user (AccountOwnerType), defaults to USER
     * @returns Promise resolving to session auth context with user data
     * @throws Error if SDK is not initialized or authentication fails
     *
     * @example
     * ```typescript
     * const { login } = useAuth();
     * const result = await login(jwtToken, AccountOwnerType.USER);
     * console.log('Logged in user:', result.user);
     * ```
     */
    const login = useCallback(async (jwtToken, userType = AccountOwnerType.USER) => {
        if (!sdk || !authProvider) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            // Set token in auth provider
            await authProvider.setAccessToken(jwtToken);
            // Perform login - emits login_success event which Provider handles
            const result = await sdk.auth.loginWithToken(jwtToken, userType);
            return result;
        }
        catch (error) {
            console.error('Login failed:', error);
            throw error;
        }
    }, [sdk, authProvider]);
    /**
     * Logs in a user using raw user data (direct authentication bypass)
     *
     * @param rawUserData - Raw user data for direct authentication
     * @throws Error if SDK is not initialized or authentication fails
     *
     * @example
     * ```typescript
     * const { loginWithRawData } = useAuth();
     * await loginWithRawData({ userId: '123', email: 'user@example.com' });
     * ```
     */
    const loginWithRawData = useCallback(async (rawUserData) => {
        if (!sdk || !authProvider) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            // Use the raw data login - emits login_success event which Provider handles
            const result = await sdk.auth.loginWithRawData(rawUserData);
            // Set token from result
            if (result.accessToken) {
                await authProvider.setAccessToken(result.accessToken);
            }
        }
        catch (error) {
            console.error('Raw data login failed:', error);
            throw error;
        }
    }, [sdk, authProvider]);
    /**
     * Logs out the current user and clears authentication state
     *
     * @throws Error if logout process fails
     *
     * @example
     * ```typescript
     * const { logout } = useAuth();
     * await logout();
     * console.log('User logged out');
     * ```
     */
    const logout = useCallback(async () => {
        if (!sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            // clearAuth emits logout_success event which Provider handles
            await sdk.auth.clearAuth();
        }
        catch (error) {
            console.error('Logout failed:', error);
            throw error;
        }
    }, [sdk]);
    /**
     * Retrieves the current authenticated user data
     *
     * @returns Promise resolving to current user data
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getCurrentUser } = useAuth();
     * const user = await getCurrentUser();
     * console.log('Current user:', user.email);
     * ```
     */
    const getCurrentUser = useCallback(async () => {
        if (!sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        return sdk.auth.getCurrentUser();
    }, [sdk]);
    /**
     * Checks if the current session is authenticated
     *
     * @returns Promise resolving to authentication status
     *
     * @example
     * ```typescript
     * const { checkIsAuthenticated } = useAuth();
     * const isAuth = await checkIsAuthenticated();
     * console.log('Is authenticated:', isAuth);
     * ```
     */
    const checkIsAuthenticated = useCallback(async () => {
        if (!sdk) {
            return false;
        }
        return sdk.auth.isAuthenticated();
    }, [sdk]);
    /**
     * Refreshes authentication tokens
     *
     * @param refreshToken - Optional refresh token to use
     * @returns Promise resolving to new session auth response
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { refreshTokens } = useAuth();
     * const tokens = await refreshTokens();
     * console.log('Tokens refreshed:', tokens);
     * ```
     */
    const refreshTokens = useCallback(async (refreshToken) => {
        if (!sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        return sdk.auth.refreshTokens(refreshToken);
    }, [sdk]);
    /**
     * Clears all authentication data and resets auth state
     *
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { clearAuth } = useAuth();
     * await clearAuth();
     * console.log('Auth data cleared');
     * ```
     */
    const clearAuth = useCallback(async () => {
        if (!sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        // clearAuth emits logout_success event which Provider handles
        await sdk.auth.clearAuth();
    }, [sdk]);
    /**
     * Checks if the current authentication is valid (non-expired)
     *
     * @returns Boolean indicating if auth is valid
     *
     * @example
     * ```typescript
     * const { hasValidAuth } = useAuth();
     * const isValid = hasValidAuth();
     * console.log('Auth is valid:', isValid);
     * ```
     */
    const hasValidAuth = useCallback(async () => {
        if (!sdk) {
            return false;
        }
        return await sdk.auth.hasValidAuth();
    }, [sdk]);
    return {
        // State
        isInitialized,
        isAuthenticated,
        user,
        // Methods
        login,
        loginWithRawData,
        logout,
        refreshUserData,
        getCurrentUser,
        checkIsAuthenticated,
        refreshTokens,
        clearAuth,
        hasValidAuth,
    };
};
