# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Routes for Google authentication.
"""

from fastapi import APIRouter, HTTPException, Request, Response, status, Depends, Body, Query
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
import logging
import json
from typing import Dict, Any, Optional
from requests_oauthlib import OAuth2Session
import httpx

from modules.shared.configuration import APP_CONFIG
from modules.interfaces.interfaceDbApp import getInterface, getRootInterface
from modules.datamodels.datamodelUam import AuthAuthority, User, ConnectionStatus, UserConnection
from modules.auth import getCurrentUser, limiter, SECRET_KEY, ALGORITHM
from modules.auth import createAccessToken, setAccessTokenCookie, createRefreshToken, setRefreshTokenCookie
from modules.auth.tokenManager import TokenManager
from modules.shared.timeUtils import createExpirationTimestamp, getUtcTimestamp, parseTimestamp

# Configure logger
logger = logging.getLogger(__name__)

async def verify_google_token(access_token: str) -> Dict[str, Any]:
    """
    Verify Google access token validity and get token info.
    Returns token information including scopes and expiration.
    """
    try:
        headers = {
            'Authorization': f"Bearer {access_token}",
            'Content-Type': 'application/json'
        }
        
        async with httpx.AsyncClient() as client:
            # Use Google's tokeninfo endpoint to verify token
            response = await client.get(
                "https://www.googleapis.com/oauth2/v1/tokeninfo",
                headers=headers,
                params={"access_token": access_token}
            )
            
            if response.status_code == 200:
                token_info = response.json()
                logger.debug(f"Token verification successful: {token_info.get('email', 'unknown')}")
                return {
                    "valid": True,
                    "token_info": token_info,
                    "scopes": token_info.get("scope", "").split(" ") if token_info.get("scope") else [],
                    "expires_in": int(token_info.get("expires_in", 0)),
                    "user_id": token_info.get("user_id"),
                    "email": token_info.get("email")
                }
            else:
                logger.warning(f"Token verification failed: {response.status_code} - {response.text}")
                return {
                    "valid": False,
                    "error": f"HTTP {response.status_code}",
                    "details": response.text
                }
                
    except Exception as e:
        logger.error(f"Error verifying Google token: {str(e)}")
        return {
            "valid": False,
            "error": str(e)
        }

# Create router
router = APIRouter(
    prefix="/api/google",
    tags=["Security Google"],
    responses={
        404: {"description": "Not found"}, 
        400: {"description": "Bad request"},
        401: {"description": "Unauthorized"},
        403: {"description": "Forbidden"},
        500: {"description": "Internal server error"}
    }
)

# Google OAuth configuration
CLIENT_ID = APP_CONFIG.get("Service_GOOGLE_CLIENT_ID")
CLIENT_SECRET = APP_CONFIG.get("Service_GOOGLE_CLIENT_SECRET")
REDIRECT_URI = APP_CONFIG.get("Service_GOOGLE_REDIRECT_URI")
SCOPES = [
    "https://www.googleapis.com/auth/gmail.readonly",
    "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/userinfo.email",
    "openid"
]

@router.get("/config")
def get_config():
    """Debug endpoint to check Google OAuth configuration"""
    return {
        "client_id": CLIENT_ID,
        "client_secret": "***" if CLIENT_SECRET else None,
        "redirect_uri": REDIRECT_URI,
        "scopes": SCOPES,
        "config_loaded": bool(CLIENT_ID and CLIENT_SECRET and REDIRECT_URI),
        "config_source": {
            "client_id_from": "config.ini" if CLIENT_ID and "354925410565" in CLIENT_ID else "env file",
            "redirect_uri_from": "config.ini" if REDIRECT_URI and "gateway-int.poweron-center.net" in REDIRECT_URI else "env file"
        }
    }

@router.get("/login")
@limiter.limit("5/minute")
def login(
    request: Request,
    state: str = Query("login", description="State parameter to distinguish between login and connection flows"),
    connectionId: Optional[str] = Query(None, description="Connection ID for connection flow")
) -> RedirectResponse:
    """Initiate Google login"""
    try:
        # Debug: Log configuration values
        logger.info(f"Google OAuth Configuration - CLIENT_ID: {CLIENT_ID}, REDIRECT_URI: {REDIRECT_URI}")
        
        # Validate required configuration
        if not CLIENT_ID:
            logger.error("Google OAuth CLIENT_ID is not configured")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Google OAuth CLIENT_ID is not configured"
            )
        
        if not CLIENT_SECRET:
            logger.error("Google OAuth CLIENT_SECRET is not configured")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Google OAuth CLIENT_SECRET is not configured"
            )
        
        if not REDIRECT_URI:
            logger.error("Google OAuth REDIRECT_URI is not configured")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Google OAuth REDIRECT_URI is not configured"
            )
        
        # Generate auth URL with state - use state as is if it's already JSON, otherwise create new state
        try:
            # Try to parse state as JSON to check if it's already encoded
            json.loads(state)
            state_param = state  # Use state as is if it's valid JSON
        except json.JSONDecodeError:
            # If not JSON, create new state object
            state_param = json.dumps({
                "type": state,
                "connectionId": connectionId
            })
        
        logger.info(f"Using state parameter: {state_param}")
        
        # Use OAuth2Session directly - it works reliably
        oauth = OAuth2Session(
            client_id=CLIENT_ID,
            redirect_uri=REDIRECT_URI,
            scope=SCOPES
        )
        
        extra_params = {
            "access_type": "offline",
            "include_granted_scopes": "true",
            "state": state_param
        }
        # If targeting specific connection, add login_hint and hd to preselect account
        try:
            if connectionId:
                rootInterface = getRootInterface()
                connection = rootInterface.getUserConnectionById(connectionId)
                if connection:
                    login_hint = connection.externalEmail or connection.externalUsername
                    if login_hint:
                        extra_params["login_hint"] = login_hint
                        if "@" in login_hint:
                            extra_params["hd"] = login_hint.split("@", 1)[1]
                    # Avoid account picker when targeting a known account
                    extra_params["prompt"] = "consent"
                else:
                    extra_params["prompt"] = "consent select_account"
            else:
                extra_params["prompt"] = "consent select_account"
        except Exception:
            extra_params["prompt"] = "consent select_account"

        auth_url, state = oauth.authorization_url(
            "https://accounts.google.com/o/oauth2/auth",
            **extra_params
        )
        
        logger.info(f"Generated Google OAuth URL using OAuth2Session: {auth_url}")
        
        return RedirectResponse(auth_url)
        
    except Exception as e:
        logger.error(f"Error initiating Google login: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to initiate Google login: {str(e)}"
        )

@router.get("/auth/callback")
async def auth_callback(code: str, state: str, request: Request, response: Response) -> HTMLResponse:
    """Handle Google OAuth callback"""
    try:
        # Import Token at function level to avoid scoping issues
        from modules.datamodels.datamodelSecurity import Token
        
        # Parse state
        state_data = json.loads(state)
        state_type = state_data.get("type", "login")
        connection_id = state_data.get("connectionId")
        user_id = state_data.get("userId")  # Get user ID from state
        
        logger.info(f"Processing Google auth callback: state_type={state_type}, connection_id={connection_id}, user_id={user_id}")
        
        # Use OAuth2Session directly for token exchange
        oauth = OAuth2Session(
            client_id=CLIENT_ID,
            redirect_uri=REDIRECT_URI
        )
        
        # Get token using OAuth2Session
        token_data = oauth.fetch_token(
            "https://oauth2.googleapis.com/token",
            client_secret=CLIENT_SECRET,
            code=code,
            include_client_id=True
        )
        
        # Verify which scopes were actually granted (as per Google OAuth 2.0 spec)
        granted_scopes = token_data.get("scope", "")
        logger.info(f"Granted scopes: {granted_scopes}")
        
        # Check if all requested scopes were granted
        missing_scopes = []
        for requested_scope in SCOPES:
            if requested_scope not in granted_scopes:
                missing_scopes.append(requested_scope)
        
        if missing_scopes:
            logger.warning(f"Some requested scopes were not granted: {missing_scopes}")
            # Continue with available scopes, but log the limitation
        
        token_response = {
            "access_token": token_data.get("access_token"),
            "refresh_token": token_data.get("refresh_token", ""),
            "token_type": token_data.get("token_type", "bearer"),
            "expires_in": token_data.get("expires_in", 0)
        }

        # If Google did not return a refresh_token, try to reuse an existing one for this user/connection
        if not token_response.get("refresh_token"):
            try:
                rootInterface = getRootInterface()
                # Prefer connection flow reuse; fallback to user access token
                if connection_id:
                    existing_tokens = rootInterface.getTokensByConnectionIdAndAuthority(
                        connection_id, AuthAuthority.GOOGLE
                    )
                    if existing_tokens:
                        # Use most recent by createdAt
                        existing_tokens.sort(key=lambda x: parseTimestamp(x.createdAt, default=0), reverse=True)
                        token_response["refresh_token"] = existing_tokens[0].tokenRefresh or ""
                if not token_response.get("refresh_token") and user_id:
                    existing_access_tokens = rootInterface.getTokensByUserIdNoConnection(
                        user_id, AuthAuthority.GOOGLE
                    )
                    if existing_access_tokens:
                        existing_access_tokens.sort(key=lambda x: parseTimestamp(x.createdAt, default=0), reverse=True)
                        token_response["refresh_token"] = existing_access_tokens[0].tokenRefresh or ""
            except Exception:
                # Non-fatal; continue without refresh token
                pass
        

        
        if not token_response.get("access_token"):
            logger.error("Token acquisition failed: No access token received")
            return HTMLResponse(
                content="<html><body><h1>Authentication Failed</h1><p>Could not acquire token.</p></body></html>",
                status_code=400
            )
        
        # Verify the token before proceeding (as per Google OAuth 2.0 spec)
        token_verification = await verify_google_token(token_response['access_token'])
        if not token_verification.get("valid"):
            logger.error(f"Token verification failed: {token_verification.get('error')}")
            return HTMLResponse(
                content=f"<html><body><h1>Authentication Failed</h1><p>Token verification failed: {token_verification.get('error')}</p></body></html>",
                status_code=400
            )
        
        # Get user info using the verified access token
        headers = {
            'Authorization': f"Bearer {token_response['access_token']}",
            'Content-Type': 'application/json'
        }
        async with httpx.AsyncClient() as client:
            user_info_response = await client.get(
                "https://www.googleapis.com/oauth2/v2/userinfo",
                headers=headers
            )
            if user_info_response.status_code != 200:
                logger.error(f"Failed to get user info: {user_info_response.text}")
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail="Failed to get user info from Google"
                )
            user_info = user_info_response.json()
            logger.info(f"Got user info from Google: {user_info.get('email')}")
            
        # Log verified scopes for debugging
        verified_scopes = token_verification.get("scopes", [])
        logger.info(f"Verified token scopes: {verified_scopes}")
        
        if state_type == "login":
            # Handle login flow
            rootInterface = getRootInterface()
            user = rootInterface.getUserByUsername(user_info.get("email"))
            
            if not user:
                # Create new user if doesn't exist
                user = rootInterface.createUser(
                    username=user_info.get("email"),
                    email=user_info.get("email"),
                    fullName=user_info.get("name"),
                    authenticationAuthority=AuthAuthority.GOOGLE,
                    externalId=user_info.get("id"),
                    externalUsername=user_info.get("email"),
                    externalEmail=user_info.get("email")
                )
            
            # Create JWT token data (like Microsoft does)
            # MULTI-TENANT: Token does NOT contain mandateId anymore
            jwt_token_data = {
                "sub": user.username,
                "userId": str(user.id),
                "authenticationAuthority": AuthAuthority.GOOGLE.value
                # NO mandateId in token - stateless multi-tenant design
            }

            # Create JWT access token
            jwt_token, jwt_expires_at = createAccessToken(jwt_token_data)
            
            # Create refresh token
            refresh_token, _refresh_expires = createRefreshToken(jwt_token_data)
            
            # Decode token to get jti for database record
            from jose import jwt
            payload = jwt.decode(jwt_token, SECRET_KEY, algorithms=[ALGORITHM])
            jti = payload.get("jti")

            # Create JWT token with matching id
            # MULTI-TENANT: Token model no longer has mandateId field
            token = Token(
                id=jti,
                userId=user.id,  # Use local user's ID
                authority=AuthAuthority.GOOGLE,
                tokenAccess=jwt_token,  # Use JWT token instead of Google access token
                tokenRefresh=token_response.get("refresh_token", ""),
                tokenType="bearer",
                expiresAt=jwt_expires_at.timestamp(),
                createdAt=getUtcTimestamp()
                # NO mandateId - Token is not mandate-bound
            )
            
            # Save access token (no connectionId)
            appInterface = getInterface(user)
            appInterface.saveAccessToken(token)
            
            # Convert token to dict and ensure proper timestamp handling
            token_dict = token.model_dump()
            
            # Create HTML response
            html_response = HTMLResponse(
                content=f"""
                <html>
                    <head><title>Authentication Successful</title></head>
                    <body>
                        <script>
                            if (window.opener) {{
                                window.opener.postMessage({{
                                    type: 'google_auth_success',
                                    access_token: {json.dumps(token_response["access_token"])},
                                    token_data: {json.dumps(token_dict)}
                                }}, '*');
                            }}
                            setTimeout(() => window.close(), 1000);
                        </script>
                    </body>
                </html>
                """
            )
            
            # Set access token as httpOnly cookie (like local login)
            # HTMLResponse inherits from Response, so we can set cookies directly on it
            setAccessTokenCookie(html_response, jwt_token, expiresDelta=None)
            
            # Set refresh token as httpOnly cookie
            setRefreshTokenCookie(html_response, refresh_token)
            
            return html_response
        else:
            # Handle connection flow
            if not connection_id or not user_id:
                logger.error("Connection ID or User ID is missing in connection flow")
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="Connection ID and User ID are required for connection flow"
                )
            
            # Get user directly by ID
            rootInterface = getRootInterface()
            user = rootInterface.getUser(user_id)
            
            if not user:
                logger.error(f"User {user_id} not found in database")
                return HTMLResponse(
                    content=f"""
                    <html>
                        <head><title>Connection Failed</title></head>
                        <body>
                            <script>
                                if (window.opener) {{
                                    window.opener.postMessage({{
                                        type: 'google_connection_error',
                                        error: 'User not found in database'
                                    }}, '*');
                                    // Wait for message to be sent before closing
                                    setTimeout(() => window.close(), 1000);
                                }} else {{
                                    window.close();
                                }}
                            </script>
                        </body>
                    </html>
                    """,
                    status_code=404
                )
            
            # Get the connection from the connections table
            interface = getInterface(user)
            connections = interface.getUserConnections(user_id)
            connection = None
            for conn in connections:
                if conn.id == connection_id:
                    connection = conn
                    logger.info(f"Found existing connection for user {user.username}")
                    break
            
            try:
                if not connection:
                    logger.error(f"Connection {connection_id} not found in user's connections")
                    return HTMLResponse(
                        content=f"""
                        <html>
                            <head><title>Connection Failed</title></head>
                            <body>
                                <script>
                                    if (window.opener) {{
                                        window.opener.postMessage({{
                                            type: 'google_connection_error',
                                            error: 'Connection not found in user\'s connections'
                                        }}, '*');
                                        // Wait for message to be sent before closing
                                        setTimeout(() => window.close(), 1000);
                                    }} else {{
                                        window.close();
                                    }}
                                </script>
                            </body>
                        </html>
                        """,
                        status_code=404
                    )
                
                logger.info(f"Updating connection {connection_id} for user {user.username}")
                # Update connection with external service details
                connection.status = ConnectionStatus.ACTIVE
                connection.lastChecked = getUtcTimestamp()
                connection.expiresAt = getUtcTimestamp() + token_response.get("expires_in", 0)
                connection.externalId = user_info.get("id")
                connection.externalUsername = user_info.get("email")
                connection.externalEmail = user_info.get("email")
                # Store actually granted scopes for this connection
                granted_scopes_list = granted_scopes.split(" ") if granted_scopes else SCOPES
                connection.grantedScopes = granted_scopes_list
                logger.info(f"Storing granted scopes for connection {connection_id}: {granted_scopes_list}")
                
                # Update connection record directly
                rootInterface.db.recordModify(UserConnection, connection_id, connection.model_dump())
                
                
                # Save token
                token = Token(
                    userId=user.id,  # Use local user's ID
                    authority=AuthAuthority.GOOGLE,
                    connectionId=connection_id,  # Link token to this specific connection
                    tokenAccess=token_response["access_token"],
                    tokenRefresh=token_response.get("refresh_token", ""),
                    tokenType=token_response.get("token_type", "bearer"),
                    expiresAt=createExpirationTimestamp(token_response.get("expires_in", 0)),
                    createdAt=getUtcTimestamp()
                )
                interface.saveConnectionToken(token)
                
                # Return success page with connection data
                return HTMLResponse(
                    content=f"""
                    <html>
                        <head><title>Connection Successful</title></head>
                        <body>
                            <script>
                                if (window.opener) {{
                                    window.opener.postMessage({{
                                        type: 'google_connection_success',
                                        connection: {{
                                            id: '{connection.id}',
                                            status: 'connected',
                                            type: 'google',
                                            lastChecked: {getUtcTimestamp()},
                                            expiresAt: {createExpirationTimestamp(token_response.get("expires_in", 0))}
                                        }}
                                    }}, '*');
                                    // Wait for message to be sent before closing
                                    setTimeout(() => window.close(), 1000);
                                }} else {{
                                    window.close();
                                }}
                            </script>
                        </body>
                    </html>
                    """
                )
            except Exception as e:
                logger.error(f"Error updating connection: {str(e)}", exc_info=True)
                return HTMLResponse(
                    content=f"""
                    <html>
                        <head><title>Connection Failed</title></head>
                        <body>
                            <script>
                                if (window.opener) {{
                                    window.opener.postMessage({{
                                        type: 'google_connection_error',
                                        error: 'Failed to update connection: {str(e)}'
                                    }}, '*');
                                    // Wait for message to be sent before closing
                                    setTimeout(() => window.close(), 1000);
                                }} else {{
                                    window.close();
                                }}
                            </script>
                        </body>
                    </html>
                    """,
                    status_code=500
                )
            
    except Exception as e:
        logger.error(f"Error in auth callback: {str(e)}", exc_info=True)
        return HTMLResponse(
            content=f"""
            <html>
                <head><title>Authentication Failed</title></head>
                <body>
                    <script>
                        if (window.opener) {{
                            window.opener.postMessage({{
                                type: 'google_connection_error',
                                error: 'Authentication failed: {str(e)}'
                            }}, '*');
                            // Wait for message to be sent before closing
                            setTimeout(() => window.close(), 1000);
                        }} else {{
                            window.close();
                        }}
                    </script>
                </body>
            </html>
            """,
            status_code=500
        )

@router.get("/me", response_model=User)
@limiter.limit("30/minute")
def get_current_user(
    request: Request,
    currentUser: User = Depends(getCurrentUser)
) -> User:
    """Get current user information"""
    try:
        return currentUser
    except Exception as e:
        logger.error(f"Error getting current user: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=str(e)
        )

@router.post("/logout")
@limiter.limit("10/minute")
def logout(
    request: Request,
    currentUser: User = Depends(getCurrentUser)
) -> Dict[str, Any]:
    """Logout current user"""
    try:
        appInterface = getInterface(currentUser)
        appInterface.logout()
        
        # Log successful logout
        # MULTI-TENANT: Logout is a system-level function, no mandate context
        try:
            from modules.shared.auditLogger import audit_logger
            audit_logger.logUserAccess(
                userId=str(currentUser.id),
                mandateId="system",
                action="logout",
                successInfo="google_auth_logout",
                ipAddress=request.client.host if request.client else None,
                userAgent=request.headers.get("user-agent"),
                success=True
            )
        except Exception:
            # Don't fail if audit logging fails
            pass
            
        return {"message": "Logged out successfully"}
    except Exception as e:
        logger.error(f"Error during logout: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to logout: {str(e)}"
        )

@router.post("/verify")
@limiter.limit("30/minute")
async def verify_token(
    request: Request,
    currentUser: User = Depends(getCurrentUser)
) -> Dict[str, Any]:
    """Verify current user's Google token validity and get token info"""
    try:
        appInterface = getInterface(currentUser)
        
        # Find Google connection for this user
        connections = appInterface.getUserConnections(currentUser.id)
        google_connection = None
        
        for conn in connections:
            if conn.authority == AuthAuthority.GOOGLE:
                google_connection = conn
                break
        
        if not google_connection:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="No Google connection found for current user"
            )
        
        # Get a fresh token via TokenManager convenience method
        current_token = TokenManager().getFreshToken(google_connection.id)

        if not current_token:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="No Google token found for this connection"
            )
        
        # Verify the (fresh) token
        token_verification = await verify_google_token(current_token.tokenAccess)
        
        return {
            "valid": token_verification.get("valid", False),
            "scopes": token_verification.get("scopes", []),
            "expires_in": token_verification.get("expires_in", 0),
            "email": token_verification.get("email"),
            "user_id": token_verification.get("user_id"),
            "error": token_verification.get("error") if not token_verification.get("valid") else None
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error verifying Google token: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to verify token: {str(e)}"
        )

@router.post("/refresh")
@limiter.limit("10/minute")
async def refresh_token(
    request: Request,
    currentUser: User = Depends(getCurrentUser)
) -> Dict[str, Any]:
    """Refresh Google OAuth token for current user. Accepts optional { connectionId } to target a specific connection."""
    try:
        appInterface = getInterface(currentUser)
        
        # Optional: use provided connectionId to target a specific connection
        payload = {}
        try:
            payload = await request.json()
        except Exception:
            payload = {}
        requested_connection_id = payload.get("connectionId") if isinstance(payload, dict) else None

        # Find Google connection for this user
        logger.debug(f"Looking for Google connection for user {currentUser.id}")
        connections = appInterface.getUserConnections(currentUser.id)
        google_connection = None
        if requested_connection_id:
            for conn in connections:
                if conn.id == requested_connection_id and conn.authority == AuthAuthority.GOOGLE:
                    google_connection = conn
                    break
            if not google_connection:
                raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Requested Google connection not found for current user")
        else:
            for conn in connections:
                if conn.authority == AuthAuthority.GOOGLE:
                    google_connection = conn
                    break
        
        if not google_connection:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="No Google connection found for current user"
            )
        
        logger.debug(f"Found Google connection: {google_connection.id}, status={google_connection.status}")
        
        # Get the token for this specific connection (fresh if expiring soon)
        current_token = TokenManager().getFreshToken(google_connection.id)
        
        if not current_token:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="No Google token found for this connection"
            )
        

        # If we could not obtain a fresh token, report error
        if not current_token:
            raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to refresh token")
        
        # Update the connection status and timing
        expiresAtValue = parseTimestamp(current_token.expiresAt)
        google_connection.expiresAt = expiresAtValue if expiresAtValue else google_connection.expiresAt
        google_connection.lastChecked = getUtcTimestamp()
        google_connection.status = ConnectionStatus.ACTIVE
        appInterface.db.recordModify(UserConnection, google_connection.id, google_connection.model_dump())
        
        # Calculate time until expiration
        currentTime = getUtcTimestamp()
        expiresAt = parseTimestamp(current_token.expiresAt)
        expiresIn = int(expiresAt - currentTime) if expiresAt else 0
        
        return {
            "message": "Token refreshed successfully",
            "expires_at": expiresAt,
            "expires_in_seconds": expiresIn
        }
            
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error refreshing Google token: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to refresh token: {str(e)}"
        ) 