"""
Google OAuth2 authentication handler.

Provides shared credentials for Google Drive and Gmail APIs.
Uses OAuth2 with a desktop app flow — Bill authorizes once, then
the refresh token handles everything automatically.

Setup:
1. Go to https://console.cloud.google.com
2. Create a project (or reuse one)
3. Enable: Google Drive API, Gmail API
4. Create OAuth 2.0 credentials (Desktop App type)
5. Download the JSON → save as ~/clawd/.google-credentials.json
6. Run: python setup_google_auth.py
7. Authorize in browser → token saved to ~/clawd/.google-token.json
"""

import os
import json
import logging
from pathlib import Path

logger = logging.getLogger("google-auth")

# Paths for credentials and token
_BASE_DIR = Path(__file__).resolve().parent.parent  # ~/clawd/
CREDENTIALS_PATH = os.getenv(
    "GOOGLE_CREDENTIALS_PATH",
    str(_BASE_DIR / ".google-credentials.json"),
)
TOKEN_PATH = os.getenv(
    "GOOGLE_TOKEN_PATH",
    str(_BASE_DIR / ".google-token.json"),
)

# Scopes needed for Drive (read files) and Gmail (read emails)
SCOPES = [
    "https://www.googleapis.com/auth/drive.readonly",
    "https://www.googleapis.com/auth/gmail.readonly",
]


def get_credentials():
    """
    Get valid Google OAuth2 credentials.
    Returns google.oauth2.credentials.Credentials or None.
    """
    try:
        from google.oauth2.credentials import Credentials
        from google.auth.transport.requests import Request
    except ImportError:
        logger.error(
            "google-auth not installed. Run: "
            "pip install google-auth google-auth-oauthlib google-api-python-client"
        )
        return None

    creds = None

    # Load existing token
    if os.path.exists(TOKEN_PATH):
        try:
            creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
        except Exception as e:
            logger.warning(f"Failed to load token: {e}")
            creds = None

    # Refresh if expired
    if creds and creds.expired and creds.refresh_token:
        try:
            creds.refresh(Request())
            _save_token(creds)
            logger.info("Google token refreshed successfully")
        except Exception as e:
            logger.error(f"Token refresh failed: {e}")
            creds = None

    if not creds or not creds.valid:
        logger.warning(
            "No valid Google credentials. Run 'python setup_google_auth.py' to authorize."
        )
        return None

    return creds


def _save_token(creds):
    """Save credentials to token file."""
    token_data = {
        "token": creds.token,
        "refresh_token": creds.refresh_token,
        "token_uri": creds.token_uri,
        "client_id": creds.client_id,
        "client_secret": creds.client_secret,
        "scopes": list(creds.scopes) if creds.scopes else SCOPES,
    }
    with open(TOKEN_PATH, "w") as f:
        json.dump(token_data, f, indent=2)
    logger.info(f"Token saved to {TOKEN_PATH}")


def build_drive_service():
    """Build and return a Google Drive API service object."""
    creds = get_credentials()
    if not creds:
        return None
    try:
        from googleapiclient.discovery import build
        return build("drive", "v3", credentials=creds)
    except Exception as e:
        logger.error(f"Failed to build Drive service: {e}")
        return None


def build_gmail_service():
    """Build and return a Gmail API service object."""
    creds = get_credentials()
    if not creds:
        return None
    try:
        from googleapiclient.discovery import build
        return build("gmail", "v1", credentials=creds)
    except Exception as e:
        logger.error(f"Failed to build Gmail service: {e}")
        return None


def is_configured():
    """Check if Google credentials are set up."""
    return os.path.exists(TOKEN_PATH) and os.path.exists(CREDENTIALS_PATH)
