# Per-User NotebookLM Google Account Linking - Implementation Complete

## Summary
Implemented a new OAuth-based flow for per-user NotebookLM account linking that uses the existing Google OAuth tokens instead of opening a browser window.

## What Was Changed

### 1. New File: `app/ai/nlm_oauth_helper.py`
- `get_nlm_cookies_with_oauth()` - Uses Playwright in headless mode with OAuth token to get NotebookLM cookies
- `refresh_nlm_session_with_refresh_token()` - Refreshes session using refresh token

### 2. Modified: `app/routes/study.py`
Added three new routes:
- **`/study/api/notebook/connect-with-oauth`** (POST) - Connect using existing OAuth tokens
- **`/study/api/notebook/disconnect`** (POST) - Disconnect NotebookLM session
- Enhanced error handling for users without Google OAuth

### 3. Modified: `app/templates/study/notebook.html`
- Updated `connectGoogle()` function to call the new OAuth endpoint
- Added helpful error message when Google OAuth is required

## How It Works

### User Flow:
1. User logs in with Google OAuth (if not already)
2. User visits `/notebook/<report_id>` in per-user mode
3. User clicks "ربط حساب Google" (Connect Google Account) button
4. System uses existing OAuth tokens to authenticate to NotebookLM in headless mode
5. NotebookLM cookies are saved to user's storage
6. User can create notebooks and generate assets

### Technical Flow:
```
1. User clicks "Connect Google"
2. API call to /study/api/notebook/connect-with-oauth
3. Check if user has google_access_token
4. If yes: Use get_nlm_cookies_with_oauth()
   - Launch Playwright headless
   - Set Authorization header with OAuth token
   - Navigate to Google to establish session
   - Navigate to NotebookLM
   - Save cookies to storage_state.json
5. If no OAuth: Return error asking user to login with Google first
```

## Files Created/Modified

### Created:
- `app/ai/nlm_oauth_helper.py` - OAuth helper functions
- `NOTEBOOKLM_OAUTH_PLAN.md` - Implementation plan

### Modified:
- `app/routes/study.py` - Added OAuth-based routes
- `app/templates/study/notebook.html` - Updated connect function

## Requirements

### For Users:
1. **Must be logged in with Google OAuth** - Users need to have signed up/logged in with Google
2. **Valid Google OAuth tokens** - `google_access_token` must be present in user profile

### For System:
1. **Playwright installed** - Already present
2. **Google OAuth configured** - Already configured (`GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`)
3. **Per-user mode enabled** - Set in admin panel

## Advantages of This Approach

1. **No display server required** - Uses headless mode
2. **Uses existing OAuth flow** - No new authentication needed
3. **Faster connection** - No manual login required
4. **More secure** - Tokens are managed by Google OAuth
5. **Works in production** - No Xvfb or browser windows needed

## Testing

To test the implementation:
1. Go to https://jadwaai.com/admin/notebooklm
2. Select "حساب منفصل لكل مستخدم" (Per User)
3. Logout and login with Google OAuth
4. Visit any report's notebook page
5. Click "ربط حساب Google"
6. Should connect automatically without opening browser window

## Error Messages

- **"يجب تسجيل الدخول بحساب Google أولاً"** - User needs to login with Google first
- **"فشل ربط الحساب"** - Connection failed (check logs)
- **"تم ربط حساب Google بـ NotebookLM بنجاح"** - Success

## Troubleshooting

### If connection fails:
1. Check user has `google_access_token` in database
2. Check Playwright is installed correctly
3. Check Google OAuth credentials are valid
4. Check logs: `tail -f logs/app.log`

### To refresh expired tokens:
The system automatically tries to refresh using `google_refresh_token` if access fails.

## Next Steps (Optional Enhancements)

1. **Add retry logic** - Automatically retry if rate limited
2. **Add session validity check** - Periodically verify cookies are still valid
3. **Add auto-refresh** - Automatically refresh sessions before expiration
4. **Add disconnect button in UI** - Allow users to disconnect their NotebookLM account
