"""Cliente base para Google BigQuery."""

from dataclasses import dataclass, field
import google.auth
from google.cloud import bigquery
from google.oauth2 import service_account


@dataclass
class BQClient:
    """Cliente para Google BigQuery.

    Attributes:
        project_id: ID del proyecto GCP.
        _client: Cliente oficial de BigQuery (interno).
    """
    project_id: str
    _client: bigquery.Client = field(repr=False)

    def close(self) -> None:
        """Cierra el cliente BigQuery."""
        self._client.close()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()


def bq_auth(
    project_id: str = "",
    credentials_path: str = "",
    drop_quota_project: bool = False,
) -> BQClient:
    """Autentica contra Google BigQuery.

    Tres modos de autenticacion:
    1. ADC (Application Default Credentials): sin argumentos, usa gcloud auth
    2. Service account JSON: con credentials_path
    3. Proyecto explicito: con project_id (usa ADC para credenciales)

    Con drop_quota_project=True (y sin credentials_path) resuelve las credenciales
    ADC via google.auth.default y elimina el quota project fijado en el ADC del
    usuario (creds.with_quota_project(None)). Esto evita el error 403
    USER_PROJECT_DENIED cuando el ADC lleva un quota_project_id ajeno al proyecto
    contra el que se consulta.

    Args:
        project_id: ID del proyecto GCP. Vacio = detectar de credenciales.
        credentials_path: Ruta a archivo JSON de service account. Vacio = ADC.
        drop_quota_project: Si True y sin credentials_path, resuelve ADC con
            google.auth.default y descarta el quota project del ADC
            (with_quota_project(None)). Default False = comportamiento original.

    Returns:
        BQClient autenticado listo para usar.

    Raises:
        google.auth.exceptions.DefaultCredentialsError: Si no hay credenciales configuradas.
        FileNotFoundError: Si credentials_path no existe.

    Example:
        >>> client = bq_auth()  # ADC
        >>> client = bq_auth("my-project")  # ADC con proyecto explicito
        >>> client = bq_auth(credentials_path="/path/to/sa.json")  # Service account
        >>> client = bq_auth("autingo-159109", drop_quota_project=True)  # sin quota project
    """
    if credentials_path:
        creds = service_account.Credentials.from_service_account_file(credentials_path)
        proj = project_id or creds.project_id
        client = bigquery.Client(credentials=creds, project=proj)
    elif drop_quota_project:
        creds, adc_project = google.auth.default(
            scopes=["https://www.googleapis.com/auth/bigquery"]
        )
        if hasattr(creds, "with_quota_project"):
            creds = creds.with_quota_project(None)
        client = bigquery.Client(project=project_id or adc_project, credentials=creds)
    elif project_id:
        client = bigquery.Client(project=project_id)
    else:
        client = bigquery.Client()

    return BQClient(project_id=client.project, _client=client)
