# #region SupersetDatabasesMixin [C:3] [TYPE Module] [SEMANTICS superset, search, superset-databases-mixin]
# @defgroup Core Module group.
# @LAYER Infrastructure
# @BRIEF Database domain mixin for SupersetClient — list, get, summary, by_uuid.
# @RELATION DEPENDS_ON -> [SupersetClientBase]
# @SIDE_EFFECT Асинхронные HTTP-вызовы к Superset API для работы с базами данных.
from typing import Any, cast

from ..logger import belief_scope, logger as app_logger

app_logger = cast(Any, app_logger)
# #region SupersetDatabasesMixin [C:3] [TYPE Class]
# @defgroup Core Module group.
# @BRIEF Mixin providing all database-related Superset API operations.
# @RELATION DEPENDS_ON -> [SupersetClientBase]
# @SIDE_EFFECT Асинхронные HTTP-вызовы к Superset API.
class SupersetDatabasesMixin:
    # #region SupersetClientGetDatabases [TYPE Function] [C:3]
# @ingroup Core
    # @PURPOSE: Получает полный список баз данных.
    # @SIDE_EFFECT Асинхронные HTTP-вызовы к Superset API для пагинации.
    # @RELATION CALLS -> [SupersetClientFetchAllPages]
    async def get_databases(self, query: dict | None = None) -> tuple[int, list[dict]]:
        with belief_scope("get_databases"):
            app_logger.info("[get_databases][Enter] Fetching databases.")
            validated_query = self._validate_query_params(query or {})
            if "columns" not in validated_query:
                validated_query["columns"] = []
            paginated_data = await self._fetch_all_pages(
                endpoint="/database/",
                pagination_options={
                    "base_query": validated_query,
                    "results_field": "result",
                },
            )
            total_count = len(paginated_data)
            app_logger.reflect(f"Found {total_count} databases.", extra={"src": "get_databases"})
            return total_count, paginated_data
    # #endregion SupersetClientGetDatabases
    # #region SupersetClientGetDatabase [TYPE Function] [C:3]
# @ingroup Core
    # @PURPOSE: Получает информацию о конкретной базе данных по её ID.
    # @SIDE_EFFECT Асинхронный HTTP-вызов к Superset API.
    # @RELATION CALLS -> [AsyncAPIClient]
    async def get_database(self, database_id: int) -> dict:
        with belief_scope("get_database"):
            app_logger.info("[get_database][Enter] Fetching database %s.", database_id)
            response = await self.client.request(
                method="GET", endpoint=f"/database/{database_id}"
            )
            response = cast(dict, response)
            app_logger.reflect(f"Got database {database_id}.", extra={"src": "get_database"})
            return response
    # #endregion SupersetClientGetDatabase
    # #region SupersetClientGetDatabasesSummary [TYPE Function] [C:3]
# @ingroup Core
    # @PURPOSE: Fetch a summary of databases including uuid, name, and engine.
    # @SIDE_EFFECT Асинхронные HTTP-вызовы к Superset API.
    # @RELATION CALLS -> [SupersetClientGetDatabases]
    async def get_databases_summary(self) -> list[dict]:
        with belief_scope("SupersetClient.get_databases_summary"):
            query = {"columns": ["id", "uuid", "database_name", "backend"]}
            _, databases = await self.get_databases(query=query)
            for db in databases:
                db["engine"] = db.pop("backend", None)
            return databases
    # #endregion SupersetClientGetDatabasesSummary
    # #region SupersetClientGetDatabaseByUuid [TYPE Function] [C:3]
# @ingroup Core
    # @PURPOSE: Find a database by its UUID.
    # @SIDE_EFFECT Асинхронные HTTP-вызовы к Superset API.
    # @RELATION CALLS -> [SupersetClientGetDatabases]
    async def get_database_by_uuid(self, db_uuid: str) -> dict | None:
        with belief_scope("SupersetClient.get_database_by_uuid", f"uuid={db_uuid}"):
            query = {"filters": [{"col": "uuid", "op": "eq", "value": db_uuid}]}
            _, databases = await self.get_databases(query=query)
            return databases[0] if databases else None
    # #endregion SupersetClientGetDatabaseByUuid
    # #region SupersetClientCreateDatabase [TYPE Function] [C:3]
# @ingroup Core
    # @PURPOSE: Register a new database in Superset via REST API.
    # @POST Returns the created database dict with id.
    # @SIDE_EFFECT Makes POST request to /api/v1/database/.
    # @RELATION CALLS -> [AsyncAPIClient.request]
    async def create_database(
        self,
        database_name: str,
        sqlalchemy_uri: str,
        expose_in_sqllab: bool = True,
        allow_dml: bool = False,
    ) -> dict:
        with belief_scope("SupersetClient.create_database"):
            app_logger.reason(
                "Creating database in Superset",
                extra={"database_name": database_name, "expose_in_sqllab": expose_in_sqllab},
            )
            response = await self.client.request(
                method="POST",
                endpoint="/database/",
                data={
                    "database_name": database_name,
                    "sqlalchemy_uri": sqlalchemy_uri,
                    "expose_in_sqllab": expose_in_sqllab,
                    "allow_dml": allow_dml,
                },
            )
            response = cast(dict, response)
            app_logger.reflect(
                "Database created",
                extra={"database_id": response.get("id"), "database_name": database_name},
            )
            return response
    # #endregion SupersetClientCreateDatabase
    # #region SupersetClientDeleteDatabase [TYPE Function] [C:3]
# @ingroup Core
    # @PURPOSE: Delete a database from Superset by ID.
    # @POST Database removed from Superset.
    # @SIDE_EFFECT Makes DELETE request to /api/v1/database/<id>.
    # @RELATION CALLS -> [AsyncAPIClient.request]
    async def delete_database(self, database_id: int) -> dict:
        with belief_scope("SupersetClient.delete_database"):
            app_logger.reason("Deleting database", extra={"database_id": database_id})
            response = await self.client.request(
                method="DELETE",
                endpoint=f"/database/{database_id}",
            )
            response = cast(dict, response)
            app_logger.reflect("Database deleted", extra={"database_id": database_id})
            return response
    # #endregion SupersetClientDeleteDatabase
# #endregion SupersetDatabasesMixin
# #endregion SupersetDatabasesMixin
