from typing import Dict, List, Union
import json


def parse_service_account_json(service_account_json: Union[str, Dict]) -> Dict:
    """Parse service account credentials from a dict or JSON string."""
    if isinstance(service_account_json, dict):
        return service_account_json
    if isinstance(service_account_json, str):
        stripped = service_account_json.strip()
        if not stripped:
            raise ValueError("Service account JSON is an empty string")
        try:
            return json.loads(stripped)
        except json.JSONDecodeError as e:
            raise ValueError(
                "Service account JSON must be valid JSON (double-quoted keys/values).\n"
                'Example: {"type":"service_account",...}.\n'
                f"JSON decode error: {e}"
            ) from e
    raise TypeError(
        f"Service account JSON must be a dict or JSON string, got {type(service_account_json)}"
    )


def create_credentials(
    service_account_json: Union[str, Dict],
    scopes: List[str],
    subject: str = None,
):
    """Create Google OAuth2 credentials from service account JSON."""
    from google.oauth2.service_account import Credentials

    sa_dict = parse_service_account_json(service_account_json)
    creds = Credentials.from_service_account_info(sa_dict, scopes=scopes)
    if subject:
        creds = creds.with_subject(subject)
    return creds
