#!/usr/bin/env python3
"""Generate a Google OAuth token for Gmail API.

This script runs a local OAuth flow that:
1. Opens your browser automatically to the Google authorization page
2. Handles the callback via a local HTTP server
3. Saves the resulting token to ./secrets/gmail_creds.json

No manual copy-paste required.
"""

from __future__ import annotations

import json
import os
import sys

SCOPES = [
    "https://www.googleapis.com/auth/gmail.modify",
    "https://www.googleapis.com/auth/gmail.labels",
]

_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_PATH = os.path.join(_ROOT, "secrets", "gmail_creds.json")
_OAUTH_CLIENT_PATH = os.path.join(_ROOT, "secrets", "google_oauth_client.json")


def _load_oauth_client() -> tuple[str, str]:
    if not os.path.exists(_OAUTH_CLIENT_PATH):
        print(f"Missing OAuth client file: {_OAUTH_CLIENT_PATH}")
        print("Create it with: {\"client_id\": \"...\", \"client_secret\": \"...\"}")
        sys.exit(1)
    with open(_OAUTH_CLIENT_PATH) as f:
        data = json.load(f)
    return data["client_id"], data["client_secret"]


def main() -> None:
    # Lazy-import so we can show helpful errors if not installed.
    try:
        from google.auth.transport.requests import Request
        from google.oauth2.credentials import Credentials
        from google_auth_oauthlib.flow import InstalledAppFlow
    except ImportError as e:
        print(f"Missing dependencies: {e}")
        print("Install with: pip3 install google-auth google-auth-oauthlib google-api-python-client")
        sys.exit(1)

    creds = None

    # Try to load existing credentials first, in case they have refresh token.
    if os.path.exists(SECRET_PATH):
        print(f"Existing credentials found at {SECRET_PATH}")
        try:
            creds = Credentials.from_authorized_user_file(SECRET_PATH, SCOPES)
        except Exception:
            creds = None

    # If creds exist and are valid, we're good.
    if creds and creds.valid:
        print("Credentials are already valid!")
        return

    # If creds exist but expired, try to refresh.
    if creds and creds.expired and creds.refresh_token:
        print("Token expired. Attempting refresh...")
        try:
            creds.refresh(Request())
            print("Token refreshed successfully!")
        except Exception as e:
            print(f"Refresh failed: {e}")
            creds = None

    if not creds or not creds.valid:
        client_id, client_secret = _load_oauth_client()
        # Start OAuth flow using local server (opens browser automatically).
        flow = InstalledAppFlow.from_client_config(
            {
                "installed": {
                    "client_id": client_id,
                    "client_secret": client_secret,
                    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
                    "token_uri": "https://oauth2.googleapis.com/token",
                    "redirect_uris": ["http://localhost"],
                }
            },
            SCOPES,
        )

        print("\nOpening browser for Google authorization...")
        creds = flow.run_local_server(
            port=0,        # pick a random available port
            open_browser=True,
            prompt="consent",
            access_type="offline",
        )

    # Save credentials.
    os.makedirs(os.path.dirname(SECRET_PATH), exist_ok=True)
    with open(SECRET_PATH, "w") as f:
        f.write(creds.to_json())

    print(f"\n✅ Gmail OAuth token saved to {SECRET_PATH}")
    print(f"   Scopes: {creds.scopes}")


if __name__ == "__main__":
    main()