"""Dataset exploration helpers."""

from __future__ import annotations

from typing import Any

from ..clients import get_bigquery_client
from ..exceptions import MCPBigQueryError
from ..logging_config import get_logger
from ..utils import format_error_response
from ..validators import ListDatasetsRequest, validate_request
from .describe import serialize_timestamp

logger = get_logger(__name__)


async def list_datasets(
    project_id: str | None = None,
    max_results: int | None = None,
) -> dict[str, Any]:
    """List datasets along with core metadata."""
    try:
        request = validate_request(
            ListDatasetsRequest,
            {"project_id": project_id, "max_results": max_results},
        )
    except MCPBigQueryError as exc:
        return {"error": format_error_response(exc)}

    try:
        return await _list_datasets_impl(request)
    except MCPBigQueryError as exc:
        return {"error": format_error_response(exc)}
    except Exception as exc:  # pragma: no cover - defensive guard
        logger.exception("Unexpected error while listing datasets")
        wrapped = MCPBigQueryError(str(exc), code="LIST_DATASETS_ERROR")
        return {"error": format_error_response(wrapped)}


async def _list_datasets_impl(request: ListDatasetsRequest) -> dict[str, Any]:
    client = get_bigquery_client(project_id=request.project_id)
    project = request.project_id or client.project

    datasets = []
    list_kwargs: dict[str, Any] = {"project": project}
    if request.max_results is not None:
        list_kwargs["max_results"] = request.max_results

    iterator = client.list_datasets(**list_kwargs)

    for dataset in iterator:
        ref = client.get_dataset(dataset.reference)
        datasets.append(
            {
                "dataset_id": dataset.dataset_id,
                "project": dataset.project,
                "location": ref.location,
                "created": serialize_timestamp(ref.created),
                "modified": serialize_timestamp(ref.modified),
                "description": ref.description,
                "labels": ref.labels or {},
                "default_table_expiration_ms": ref.default_table_expiration_ms,
                "default_partition_expiration_ms": ref.default_partition_expiration_ms,
            }
        )

    return {
        "project": project,
        "dataset_count": len(datasets),
        "datasets": datasets,
    }
